欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenTelemetry?Java?SDK?高級用法解析

 更新時間:2023年02月15日 09:31:50   作者:A心有千千結(jié)  
這篇文章主要介紹了OpenTelemetry?Java?SDK?的高級用法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

通過引入 OpenTelemetry SDK,可以觀測業(yè)務(wù)核心邏輯,比如給核心的業(yè)務(wù)設(shè)置一個 span 以統(tǒng)計、跟蹤、分析其實際行為、設(shè)置業(yè)務(wù)屬性指標(biāo)等。此方法具有一定的侵入性。

啟動命令

java -javaagent:../opentelemetry-javaagent/opentelemetry-javaagent.jar \
-Dotel.traces.exporter=otlp \
-Dotel.exporter.otlp.endpoint=http://192.168.91.11:4317 \
-Dotel.resource.attributes=service.name=demo,version=dev \
-Dotel.metrics.exporter=otlp \
-jar springboot-opentelemetry-otlp-server.jar --client=true

根據(jù)啟動參數(shù) exporter 的不同,sdk 方式也需要引入對應(yīng)的 exporter ,否則啟動失敗。如啟動參數(shù)使用了 otlplogging 兩個 exporter,則需要在 pom 添加對應(yīng)的兩個 exporter 依賴。

如果沒有使用 sdk 相關(guān)依賴,則不需要做對應(yīng)的調(diào)整。

引入依賴

	<dependencies>
		...
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-extension-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-semconv</artifactId>
            <version>1.21.0-alpha</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
            <version>1.21.0-alpha</version>
        </dependency>
		...
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>io.opentelemetry</groupId>
				<artifactId>opentelemetry-bom</artifactId>
				<version>1.21.0</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

創(chuàng)建 sdk

/**
 * @Description 推薦使用這種方式。<br>
 * 這種方式的背后提供的是 noop,也就是默認的 provider,會根據(jù)啟動參數(shù)來決定自行構(gòu)造 所需的 provider。
 * @return io.opentelemetry.api.OpenTelemetry
 **/
@Bean
public OpenTelemetry openTelemetry() {
    return AutoConfiguredOpenTelemetrySdk.builder()
            .setResultAsGlobal(false) // 這里填寫false,否則會與全局javaagent 沖突
            .build()
            .getOpenTelemetrySdk();
}

鏈路(Trace)

創(chuàng)建 Tracer

Tracer 主要是用來獲取、創(chuàng)建 span 對象。注意: Tracer 通常不負責(zé)進行配置,這是TracerProvider 的職責(zé)。 OpenTelemetry interface 提供了默認的TracerProvider實現(xiàn)。

TracerProvider getTracerProvider();

通過openTelemetry() 來獲取 Tracer 對象

    @Bean
    public Tracer tracer() {
        return openTelemetry().getTracer(appName);
    }

創(chuàng)建 Span

除了 Tracer 外,不準(zhǔn)許任何其他 API 創(chuàng)建 Span 。

Span span = tracer.spanBuilder(spanName).startSpan();

獲取當(dāng)前 Span 對象

獲取當(dāng)前 span 對象,可以為當(dāng)前 span 設(shè)置 attribute、event 等。

Span span = Span.current();

創(chuàng)建 Attribute

attribute 為 span 的屬性,為當(dāng)前 span 的標(biāo)簽。

span.setAttribute(key, value);

創(chuàng)建 Link Span

一個 Span 可以連接一個或多個因果相關(guān)的其他 Span 。鏈接可用于表示批處理操作,其中一個 Span 的初始化由多個 Span 初始化構(gòu)成,其中每個 Span 表示批處理中處理的單個輸入項。

Span child = tracer.spanBuilder(spanName)
		.addLink(span(1))
		.addLink(span(2))
		.addLink(span(3))
		.startSpan();

創(chuàng)建 Event

Span 可以攜帶零個或多個 Span 屬性的命名事件進行注釋,每一個事件都是一個 key:value 鍵值對并自動攜帶相應(yīng)的時間戳。

span.addEvent(eventName);
span.addEvent(eventName,Attributes);

recordException 是 addEvent 的特殊變體,用于記錄異常事件。

創(chuàng)建一個嵌套的 Span

通過 setParent(parentSpan) 設(shè)置 parentSpan

void parent() {
	Span parentSpan = tracer.spanBuilder("parent")
		.startSpan();
	childSpan(parentSpan);
	parentSpan.end();
}
void childSpan(Span parentSpan) {
	Span childSpan = tracer.spanBuilder("childSpan")
		.setParent(parentSpan)
		.startSpan();
	// do stuff
	childSpan.end();
}

Baggage 用法

Baggage 可以在整個鏈路傳播,適用于全局埋點,比如用戶id埋點、用戶名埋點,以便追蹤業(yè)務(wù)數(shù)據(jù)。

gateway方法 set Baggage

// Baggage 用法,此處set
	Baggage.current().toBuilder().put("app.username", "gateway").build().makeCurrent();
	logger.info("gateway set baggage[app.username] value: gateway");

resource 方法 get Baggage

 // Baggage 用法,此get
	String baggage = Baggage.current().getEntryValue("app.username");
	logger.info("resource get baggage[app.username] value: {}", baggage);

通過已知的traceId和spanId,來構(gòu)造一個新span。

Tracer 構(gòu)造 span 提供了setParent(context)方法,便于為自定義的 span 構(gòu)造一個父 span。

tracer.spanBuilder(spanName).setParent(context)

其中 setParent 需要傳入 Context 參數(shù),所以需要構(gòu)造一個上下文。

而 OpenTelemetry sdk 只提供了一個 create 方法用于創(chuàng)建 SpanContext,其中可以自定義 traceId 和 spanId。

SpanContext create(String traceIdHex, String spanIdHex, TraceFlags traceFlags, TraceState traceState)

SpanContext 作為表示 Span 的一部分,他必須可以進行序列化,并沿著分布式上下文進行傳播。SpanContext 是不可變的。

OpenTelemetry SpanContext 符合 W3C TraceContext 規(guī)范。這包含兩個標(biāo)識符 - TraceId 和 SpanId - 一套通用 TraceFlags 和 系統(tǒng)特定 TraceState。

TraceId 一個有效的 TraceId 是一個 16 字節(jié)的數(shù)組,且至少有一個非零字節(jié)。

SpanId 一個有效的 SpanId 是一個 8 字節(jié)的數(shù)組,且至少有一個非零字節(jié)。

TraceFlags 包含該 trace 的詳情。不像 TraceFlags,TraceFlags 影響所有的 traces。當(dāng)前版本和定義的 Flags 只有 sampled 。

TraceState 攜帶特定 trace 標(biāo)識數(shù)據(jù),通過一個 KV 對數(shù)組進行標(biāo)識。TraceState允許多個跟蹤系統(tǒng)參與同一個 Trace。完整定義請參考 W3C Trace Context specification

本 API 必須實現(xiàn)創(chuàng)建 SpanContext 的方法。這些方法應(yīng)當(dāng)是唯一的方法用于創(chuàng)建 SpanContext。這個功能必須在 API 中完全實現(xiàn),并且不應(yīng)當(dāng)可以被覆蓋。

但 SpanContext 并不是 Context,因而還需要做一層轉(zhuǎn)換。

private Context withSpanContext(SpanContext spanContext, Context context) {
	return context.with(Span.wrap(spanContext));
}

完整代碼如下:

    /***
     * @Description 通過已知的traceId和spanId,來構(gòu)造一個新span。
     * @Param [spanName, traceId, spanId]
     * @return java.lang.String
     **/
    @GetMapping("/customSpanByTraceIdAndSpanId")
    @ResponseBody
    public String customSpanByTraceIdAndSpanId(String spanName,String traceId,String spanId){
        assert StringUtils.isEmpty(spanName):"spanName 不能為空";
        assert StringUtils.isEmpty(traceId):"traceId 不能為空";
        assert StringUtils.isEmpty(spanId):"spanId 不能為空";
        Context context =
                withSpanContext(
                        SpanContext.create(
                                traceId, spanId, TraceFlags.getSampled(), TraceState.getDefault()),
                        Context.current());
        Span span = tracer.spanBuilder(spanName)
                .setParent(context)
                .startSpan();
        span.setAttribute("attribute.a2", "some value");
        span.setAttribute("func","attr");
        span.setAttribute("app","otel3");
        span.end();
        return buildTraceUrl(span.getSpanContext().getTraceId());
    }
    private Context withSpanContext(SpanContext spanContext, Context context) {
        return context.with(Span.wrap(spanContext));
    }

需要特別注意,依據(jù)當(dāng)前測試寫法的請求自身會產(chǎn)生一個新的 trace 信息。新構(gòu)造的 span 是依據(jù)傳入的參數(shù)進行構(gòu)造。

我們可以通過訪問鏈接來觀察結(jié)果

http://localhost:8080/customSpanByTraceIdAndSpanId?spanName=tSpan&traceId=24baeeddfbb35fceaf4c18e7cae58fe1&spanId=ff1955b4f0eacc4f

指標(biāo)(Metrics)

OpenTelemetry 還提供了 metric 相關(guān)操作的 API。

span 提供關(guān)于應(yīng)用程序的詳細信息,但生成的數(shù)據(jù)與系統(tǒng)上的負載成正比。相比之下,度量將單個度量組合成聚合,并生成作為系統(tǒng)負載函數(shù)的常量數(shù)據(jù)。聚合缺乏診斷低級問題所需的細節(jié),但是通過幫助識別趨勢和提供應(yīng)用程序運行時遙測來補充跨度。

度量 API 定義了各種工具。儀器記錄測量值,這些測量值由度量 SDK 聚合,并最終導(dǎo)出到進程外。儀器有同步和異步兩種。同步儀器記錄測量結(jié)果。異步儀器注冊回調(diào),每次采集調(diào)用一次,并記錄該時間點的測量值。下列儀器可供選擇:

LongCounter/DoubleCounter: 只記錄正數(shù)值,有同步和異步選項。用于計算事物,例如通過網(wǎng)絡(luò)發(fā)送的字節(jié)數(shù)。默認情況下,計數(shù)器測量被聚合為始終遞增的單調(diào)和。

LongUpDownCounter/DoubleUpDownCounter: 記錄正負值,有同步和異步選項。對于計算上升和下降的東西很有用,比如隊列的大小。默認情況下,向上向下計數(shù)器測量被聚合為非單調(diào)和。

LongGauge/DoubleGauge: 用異步回調(diào)測量瞬時值。用于記錄不能跨屬性合并的值,如 CPU 使用率百分比。默認情況下,量規(guī)測量被聚合為量規(guī)。

LongHistogram/DoubleHistogram(長直方圖/雙直方圖): 記錄對直方圖分布分析最有用的測量值。沒有異步選項可用。用于記錄 HTTP 服務(wù)器處理請求所花費的時間等。默認情況下,直方圖測量被聚合為顯式的桶直方圖。

獲取 Meter 對象

API定義了一個 Meter 接口。該接口由一組 instrument 構(gòu)造器,和一個使用原子方式批量獲取測量值的工具組成。Meter 可以通過 MeterProvider 的 getMeter(name)方法來創(chuàng)建一個新實例。 MeterProvider 通常被期望作為單例來使用。 其實現(xiàn)應(yīng)作為 MeterProvider 全局的唯一實現(xiàn)。通過 Meter 對象可以構(gòu)建不同類型的 metric。

    @Bean
    public Meter meter() {
        return openTelemetry().getMeter(appName);
    }

這里跳過了 MeterProvider 的細節(jié),主要原因在于 OpenTelemetry Interface 提供了 MeterProvider 的默認 noop 實現(xiàn)。

    default MeterProvider getMeterProvider() {
        return MeterProvider.noop();
    }

構(gòu)建 gauge 類型的 metric

	meter().gaugeBuilder("connections")
		.setDescription("當(dāng)前Socket.io連接數(shù)")
		.setUnit("1")
		.buildWithCallback(
				result -> {
					System.out.println("metrics");
					for (int i = 1; i < 4; i++) {
						result.record(
								i,
								Attributes.of(
										AttributeKey.stringKey("id"),
										"a" + i));
					}
				});

buildWithCallback 是一個回調(diào)函數(shù),是支持異步 API 并按需收集度量數(shù)據(jù)的附加工具,按間隔收集數(shù)據(jù),默認 1min 一次。

參考

springboot-opentelemetry-otlp-server

opentelemetry api

opentelemetry java

opentelemetry 參數(shù)配置

以上就是OpenTelemetry Java SDK 高級用法解析的詳細內(nèi)容,更多關(guān)于OpenTelemetry Java SDK的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java序列化(Serialization) 機制

    Java序列化(Serialization) 機制

    本篇文章是對Java中對象的序列化(Serialization) 機制進行了詳細的分析介紹,并附實例,需要的朋友可以參考下
    2016-07-07
  • itext生成PDF設(shè)置頁眉頁腳的實例詳解

    itext生成PDF設(shè)置頁眉頁腳的實例詳解

    這篇文章主要介紹了itext生成PDF設(shè)置頁眉頁腳的實例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • Java實現(xiàn)非對稱加密的三種方法

    Java實現(xiàn)非對稱加密的三種方法

    本文主要介紹了Java實現(xiàn)非對稱加密的三種方法,主要包括非對稱加密算法--DH(密鑰交換),非對稱加密算法--RSA,非對稱加密算法--EIGamal,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 最新評論