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

OpenTelemetry?Java?SDK?高級(jí)用法解析

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

引言

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

啟動(dòng)命令

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ù)啟動(dòng)參數(shù) exporter 的不同,sdk 方式也需要引入對(duì)應(yīng)的 exporter ,否則啟動(dòng)失敗。如啟動(dòng)參數(shù)使用了 otlplogging 兩個(gè) exporter,則需要在 pom 添加對(duì)應(yīng)的兩個(gè) exporter 依賴。

如果沒有使用 sdk 相關(guān)依賴,則不需要做對(duì)應(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,也就是默認(rèn)的 provider,會(huì)根據(jù)啟動(dòng)參數(shù)來決定自行構(gòu)造 所需的 provider。
 * @return io.opentelemetry.api.OpenTelemetry
 **/
@Bean
public OpenTelemetry openTelemetry() {
    return AutoConfiguredOpenTelemetrySdk.builder()
            .setResultAsGlobal(false) // 這里填寫false,否則會(huì)與全局javaagent 沖突
            .build()
            .getOpenTelemetrySdk();
}

鏈路(Trace)

創(chuàng)建 Tracer

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

TracerProvider getTracerProvider();

通過openTelemetry() 來獲取 Tracer 對(duì)象

    @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 對(duì)象

獲取當(dāng)前 span 對(duì)象,可以為當(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

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

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

創(chuàng)建 Event

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

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

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

創(chuàng)建一個(gè)嵌套的 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 可以在整個(gè)鏈路傳播,適用于全局埋點(diǎn),比如用戶id埋點(diǎn)、用戶名埋點(diǎn),以便追蹤業(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)造一個(gè)新span。

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

tracer.spanBuilder(spanName).setParent(context)

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

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

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

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

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

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

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

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

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

本 API 必須實(shí)現(xiàn)創(chuàng)建 SpanContext 的方法。這些方法應(yīng)當(dāng)是唯一的方法用于創(chuàng)建 SpanContext。這個(gè)功能必須在 API 中完全實(shí)現(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)造一個(gè)新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)前測試寫法的請(qǐng)求自身會(huì)產(chǎn)生一個(gè)新的 trace 信息。新構(gòu)造的 span 是依據(jù)傳入的參數(shù)進(jìn)行構(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)用程序的詳細(xì)信息,但生成的數(shù)據(jù)與系統(tǒng)上的負(fù)載成正比。相比之下,度量將單個(gè)度量組合成聚合,并生成作為系統(tǒng)負(fù)載函數(shù)的常量數(shù)據(jù)。聚合缺乏診斷低級(jí)問題所需的細(xì)節(jié),但是通過幫助識(shí)別趨勢和提供應(yīng)用程序運(yùn)行時(shí)遙測來補(bǔ)充跨度。

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

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

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

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

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

獲取 Meter 對(duì)象

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

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

這里跳過了 MeterProvider 的細(xì)節(jié),主要原因在于 OpenTelemetry Interface 提供了 MeterProvider 的默認(rèn) noop 實(shí)現(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 是一個(gè)回調(diào)函數(shù),是支持異步 API 并按需收集度量數(shù)據(jù)的附加工具,按間隔收集數(shù)據(jù),默認(rèn) 1min 一次。

參考

springboot-opentelemetry-otlp-server

opentelemetry api

opentelemetry java

opentelemetry 參數(shù)配置

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

相關(guān)文章

  • Java序列化(Serialization) 機(jī)制

    Java序列化(Serialization) 機(jī)制

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

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

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

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

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