日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

通過OpenTelemetry接入Android Trace數據

本文介紹通過OpenTelemetry Java SDK將Android應用的Trace數據接入到日志服務的操作步驟。

前提條件

已創建Trace實例。更多信息,請參見創建Trace實例

步驟一:SDK集成

在App或Module級別的build.gradle文件中添加如下配置。

// BOM清單,用于同步依賴版本。
implementation(platform("io.opentelemetry:opentelemetry-bom:1.22.0"))
// API接口
implementation("io.opentelemetry:opentelemetry-api")
implementation("io.opentelemetry:opentelemetry-context")
// API extensions
implementation("io.opentelemetry:opentelemetry-extension-kotlin")
// SDK
implementation('io.opentelemetry:opentelemetry-sdk')
implementation('io.opentelemetry:opentelemetry-sdk-logs')
// semantic conventions
implementation("io.opentelemetry:opentelemetry-semconv")
// Exporters
// 官方gRPC Exporter
implementation("io.opentelemetry:opentelemetry-exporter-otlp")

更多信息,請參見OpenTelemetry Java SDK Release

步驟二:權限配置

上報Trace數據時,需申請網絡權限,即需要在AndroidManifest.xml文件中添加如下權限申明。

<uses-permission android:name="android.permission.INTERNET" />

步驟三:初始化SDK

一般建議在Application類的onCreate方法中進行SDK初始化。

// 初始化Exporter。Exporter用于導出Trace數據到日志服務Logstore。
OtlpGrpcSpanExporter grpcSpanExporter = OtlpGrpcSpanExporter.builder()
  .setEndpoint("https://${endpoint}") 
  .addHeader("x-sls-otel-project", "${project}")
  .addHeader("x-sls-otel-instance-id", "${instanceId}")
  .addHeader("x-sls-otel-ak-id", "${access-key-id}")
  .addHeader("x-sls-otel-ak-secret", "${access-key-secret}")
  .build();

// 初始化tracer provider。tracer provider用于暴露主要的API接口,對Span進行預處理、自定義Clock。
// 自定義TraceId、SpanId生成規則,自定義采樣器等。您可以根據實際需求進行配置。
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
  .addSpanProcessor(BatchSpanProcessor.builder(grpcSpanExporter).build())
  .setResource(Resource.create(Attributes.builder()
                               .put(ResourceAttributes.SERVICE_NAME, "${service}")
                               .put(ResourceAttributes.SERVICE_NAMESPACE, "${service.namespace}")
                               .put(ResourceAttributes.SERVICE_VERSION, "${version}")
                               .put(ResourceAttributes.HOST_NAME, "${host}")
                               .put(ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "${environment}")
                               .build()
                              )
              )
  .build();

// 初始化OpenTelemetrySdk。
OpenTelemetrySdk telemetrySdk = OpenTelemetrySdk.builder()
  .setTracerProvider(tracerProvider)
  .build(); // 如果通過build() 方法生成實例,則需要根據實際情況判斷是否需要全局持有telemetrySdk。

// 您也可以初始化一個全局的OpenTelemetrySdk。
// OpenTelemetrySdk telemetrySdk = OpenTelemetrySdk.builder()
//    .setTracerProvider(tracerProvider)
//    .buildAndRegisterGlobal(); // 后續可通過GlobalOpenTelemetry.get()或GlobalOpenTelemetry.getTracer()進行訪問。

變量

說明

示例

${endpoint}

服務入口是訪問一個Project及其內部數據的URL,日志服務提供私網域名和公網域名。更多信息,請參見服務入口

  • Port:網絡端口,固定為10010。

cn-hangzhou.log.aliyuncs.com:10010

${project}

日志服務Project名稱,更多信息,請參見管理Project

test-project

${instance}

Trace服務實例ID。更多信息,請參見創建Trace實例

test-traces

${access-key-id}

AccessKey ID用于標識用戶,更多信息,請參見訪問密鑰

建議您遵循最小化原則,按需授予RAM用戶必要的權限。關于授權的具體操作,請參見創建RAM用戶及授權RAM自定義授權示例

${access-key-secret}

AccessKey Secret是用戶用于加密簽名字符串和日志服務用來驗證簽名字符串的密鑰,必須保密。

${service.namespace}

服務歸屬的命名空間。

order

${service}

服務名,根據您的實際場景配置。

payment

${version}

服務版本號,建議按照va.b.c格式定義。

v1.0.0

${host}

主機名。

localhost

${environment}

部署環境,例如測試環境、生產環境。

pre

步驟四:使用SDK

創建Tracer

建議根據不同的業務場景創建Tracer。創建Tracer時,需傳入instrumentation scope name,利于按照scope區分不同的Trace數據。

Tracer tracer = telemetrySdk.getTracer("otel application", "1.0.0");

創建基本Span

Span代表了事務中的操作。每個Span都封裝了操作名稱、起止時間戳、屬性信息、事件信息和Context信息等。

final Span span = tracer.spanBuilder("root span").startSpan();
// do stuff
// ...
span.end();

創建嵌套Span

當您希望為嵌套操作關聯Span時,OpenTelemetry支持在進程內和跨遠程進程進行跟蹤。例如針對methodA調用methodB ,您可以通過以下方式創建嵌套Span。

void methodA() {
  Span parentSpan = tracer.spanBuilder("operation A").startSpan();
  methodB(parentSpan);
  parentSpan.end();
}
void methodB(Span parentSpan) {
  Span childSpan = tracer.spanBuilder("operation B")
    .setParent(parentSpan)
    .startSpan();
  // do stuff
  childSpan.end();
}

OpenTemetry API還提供了一種自動化的方式來傳播parentSpan。

void methodA() {
  Span parentSpan = tracer.spanBuilder("operation A").startSpan();
  try (Scope scope = parentSpan.makeCurrent()) {
    methodB();
  } finally {
    parentSpan.end();
  }
}

void methodB() {
  Span childSpan = tracer.spanBuilder("operation B").startSpan();
  // do stuff
  childSpan.end();
}

創建帶屬性的Span

您可以通過屬性在Span上提供特定操作的上下文信息。例如執行結果、關聯的其他業務信息等。

Span span = tracer.spanBuilder("GET /resource/catalog").setSpanKind(Span.Kind.CLIENT).startSpan();
span.setAttribute("http.method", "GET");
span.setAttribute("http.url", url.toString());

創建攜帶事件的Span

您可以通過攜帶多個事件的方式對Span進行注釋。

span.addEvent("start");
// do stuff
// ...
span.addEvent("end");

// 也可以攜帶屬性。
Attributes eventAttributes = Attributes.of(
  "key1", AttributeValue.stringAttributeValue("value1"),
  "key2", AttributeValue.longAttributeValue(111L)
);
span.addEvent("End Computation", eventAttributes);

創建帶鏈接的Span

一個Span可以鏈接一個或多個因果相關的其他Span。

Link link1 = LinkData.create(parentSpan1.getContext());
Link link2 = LinkData.create(parentSpan2.getContext());
Span child = tracer.spanBuilder("child_with_link")
    .addLink(link1)
    .addLink(link2)
    .addLink(parentSpan3.getContext())
    .startSpan();

從遠程進程中讀取上下文信息的具體操作,請參見Context Propagation

給Span添加狀態

Span包含StatusCode.UNSETStatusCode.OKStatusCode.ERROR三個狀態,分別表示默認狀態、成功狀態、包含錯誤。

Span span = tracer.spanBuilder("operation name").startSpan();

try (Scope scope = span.makeCurrent()) {
  // do stuff
} catch (Throwable t) {
  span.setStatus(StatusCode.ERROR, "Something bad happened!");
  throw t;
} finally {
  span.end(); // 調用end()方法調用后,無法設置狀態信息。
}

給Span添加異常信息

建議在捕獲到異常信息之后,把異常信息添加到關聯的Span中。同時,也建議同步更新Span狀態。

Span span = tracer.spanBuilder("operation name").startSpan();
try (Scope scope = span.makeCurrent()) {
  // do stuff
} catch (Throwable throwable) {
  span.setStatus(StatusCode.ERROR, "Something bad happened!");
  span.recordException(throwable)
} finally {
  span.end();
}

傳播上下文信息

OpenTelemetry提供了一種基于文本的方法,傳播上下文信息。以下是使用HttpURLConnection發出HTTP請求的示例。

// 基于HttpURLConnection Header setter
TextMapSetter<HttpURLConnection> setter =
  new TextMapSetter<HttpURLConnection>() {
    @Override
    public void set(HttpURLConnection carrier, String key, String value) {
      // Insert the context as Header
      carrier.setRequestProperty(key, value);
    }
};

URL url = new URL("http://127.0.0.1:8088/resource/catalog");
Span httpSpan = tracer.spanBuilder("GET /resource/catalog").setSpanKind(SpanKind.CLIENT).startSpan();
try (Scope scope = httpSpan.makeCurrent()) {
  // 注入屬性信息,記錄HTTP請求的相關詳情。
  httpSpan.setAttribute(SemanticAttributes.HTTP_METHOD, "GET");
  httpSpan.setAttribute(SemanticAttributes.HTTP_URL, url.toString());
  HttpURLConnection transportLayer = (HttpURLConnection) url.openConnection();
  // 把當前的Context信息注入到HTTP請求中。
  telemetrySdk.getPropagators().getTextMapPropagator().inject(Context.current(), transportLayer, setter);
  // do stuff
} finally {
  httpSpan.end();
}

目前,OpenTelemetry SDK支持按照W3C Trace Context標準傳播上下文信息。更多信息,請參見W3CTraceContextPropagator類

關于OpenTelemetry SDK的更多信息,請參考官方文檔

常見問題

OpenTelemetry Java SDK使用了Java 8+ API特性后,你的設備上可能會出現如下錯誤信息。

FATAL EXCEPTION: main
Process: xx.xx.xx.xx, PID: 2810
java.lang.NoClassDefFoundError: io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder$$ExternalSyntheticLambda0
	at io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder.<init>(OtlpGrpcSpanExporterBuilder.java:38)
	at io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter.builder(OtlpGrpcSpanExporter.java:39)

針對上述問題,如果你的Android應用支持API 26以下的設備,則您需要打開coreLibraryDesugaringEnabled開關。具體操作,請參見 core library desugaring

打開coreLibraryDesugaringEnabled開關后,你的Android應用最低可以支持到API 21的設備。

說明

目前OpenTelemetry Java SDK不支持API 21以下的設備。