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

通過OpenTelemetry接入iOS Trace數據

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

前提條件

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

步驟一:集成SDK

Swift項目

  1. 導入opentelemetry-swift。

    1. 在Xcode中,選擇File>Add Package

    2. 在添加Package文本框中,輸入如下鏈接。

      https://github.com/open-telemetry/opentelemetry-swift
    3. 選擇Dependency RuleExact Version,設置版本號為1.4.0

      更多信息,請參見OpenTelemetry iOS SDK Releaseimage

  2. 選擇Swift Products。

    建議選擇以下Products。

    • OpenTelemetryApi

    • OpenTelemetryProtocolExporter

    • OpenTelemetrySdk

    • URLSessionInstrumentation

    • StdoutExporter

    • ResourceExtension

    關于Swift Products的更多信息,請參見附錄:OpenTelemetry Products說明image

Objc項目

opentelemetry-swift對Objc語言的兼容較差,日志服務基于opentelemetry-swift實現了一個Objc擴展。Objc項目除了需要完成Swift項目的配置外,還需要增加opentelemetry-objc-extension。

  1. 完成Swift項目的配置。

  2. 導入opentelemetry-objc-extension。

    1. 在Xcode中,選擇File>Add Package

    2. 在添加Package文本框中,輸入如下鏈接。

      https://github.com/aliyun-sls/opentelemetry-objc-extension
    3. 選擇Dependency RuleExact Version,輸入版本號為1.0.0

      更多信息,請參見OpenTelemetry iOS Objc Extension SDK Releaseimage

  3. 選擇Objc Extension Products。

    建議選擇以下Products。

    • OpenTelemetryApiObjc

    • OpenTelemetryProtocolExporterObjc

    • OpenTelemetrySdkObjc

    • ResourceExtensionObjc

    • URLSessionInstrumentationObjc

    • StdoutExporterObjc

關于Objc Extension Products的更多信息,請參見附錄:OpenTelemetry Products說明

步驟二:初始化SDK

一般建議在AppDelegate類的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中進行SDK初始化。

Swift項目

// 導入如下模塊。
import GRPC
import NIO
import OpenTelemetryApi
import OpenTelemetrySdk
import OpenTelemetryProtocolExporter
import StdoutExporter
import URLSessionInstrumentation

// 初始化Exporter。Exporter用于導出Trace數據到日志服務Logstore。
let client = ClientConnection.usingPlatformAppropriateTLS(for: MultiThreadedEventLoopGroup(numberOfThreads: 1))
.connect(host: "${endpoint}", port: ${port})	
let otlpTraceExporter = OtlpTraceExporter(
 channel: client,
 config: OtlpConfiguration(
 timeout: OtlpConfiguration.DefaultTimeoutInterval,
 headers:
 [
 ("x-sls-otel-project", "${project}"),
 ("x-sls-otel-instance-id", "${instanceId}"),
 ("x-sls-otel-ak-id", "${access-key-id}"),
 ("x-sls-otel-ak-secret", "${access-key-secret}")
 ]
 )
)

// 初始化tracer provider。tracer provider用于暴露主要的API,對Span進行預處理、自定義Clock,
// 自定義TraceId、SpanId生成規則,自定義采樣器等。您可以根據實際的需要進行配置。
let spanExporters = MultiSpanExporter(spanExporters: [StdoutExporter(isDebug: true), otlpTraceExporter])
let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporters)
OpenTelemetry.registerTracerProvider(
 tracerProvider: TracerProviderBuilder()
 .add(spanProcessor: spanProcessor)
 .with(resource: 
 Resource(attributes:
 [
 ResourceAttributes.serviceName.rawValue: AttributeValue.string("${service}"),
 ResourceAttributes.serviceNamespace.rawValue: AttributeValue.string("${service.namespace}"),
 ResourceAttributes.serviceVersion.rawValue: AttributeValue.string("${version}"),
 ResourceAttributes.hostName.rawValue: AttributeValue.string("${host}"),
 ResourceAttributes.deploymentEnvironment.rawValue: AttributeValue.string("${environment}"),
 ]
 )
 )
 .build()
)

// 配置其他的Instrumentation采集器。請根據實際業務需要進行配置。如下配置是開啟采集NSUrlSession網絡庫的請求信息。
URLSessionInstrumentation(configuration: URLSessionInstrumentationConfiguration(
 shouldInstrument: { request in
 return true
 })
)
let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "OTel Application", instrumentationVersion: "1.0.0")

Objc 項目

// 導入以下模塊
@import OpenTelemetryApiObjc;
@import OpenTelemetrySdkObjc;
@import OpenTelemetryProtocolExporterObjc;
@import URLSessionInstrumentationObjc;
@import StdoutExporterObjc;

// 初始化Exporter。Exporter用于導出Trace數據到日志服務Logstore。
NSDictionary *headers = @{
 @"x-sls-otel-project": @"${project}",
 @"x-sls-otel-instance-id": @"${instanceId}",
 @"x-sls-otel-ak-id": @"${access-key-id}",
 @"x-sls-otel-ak-secret": @"${access-key-secret}"
};
OtlpConfigurationObjc *configuration = [OtlpConfigurationObjc configuration:OtlpConfigurationObjc.DefaultTimeoutInterval headers:headers];
OtlpTraceExporterObjc *exporter = [OtlpTraceExporterObjc exporter:@"https://${endpoint}"
 port:@"${port}"
 configuration:configuration
];

// 初始化tracer provider。tracer provider用于暴露主要的API,對Span進行預處理,自定義Clock。
// 自定義TraceId、SpanId生成規則,自定義采樣器等。您可以根據實際的需要進行配置。
NSArray *exporters = @[
 [StdoutExporterObjc stdoutExporter:true], // 開發調試時,建議開啟,實現在console中打印出Span的具體的內容。
 exporter
];
SpanProcessorObjc *spanProcessor = [BatchSpanProcessorObjc processor: [MultiSpanExporterObjc multiSpanExporter:exporters]];

TracerProviderBuilderObjc *providerBuilder = [TracerProviderBuilderObjc builder];
NSDictionary *resources = @{
 ResourceAttributesObjc.serviceName: [AttributeValueObjc string:@"${service}"], // 當前要追蹤Trace的服務名稱,建議取模塊的名稱,例如首頁、會員中心。
 ResourceAttributesObjc.serviceNamespace: [AttributeValueObjc string:@"${service.namespace}"], // 建議固定為iOS/iPadOS/macOS/tvOS/watchOS。
 ResourceAttributesObjc.serviceVersion: [AttributeValueObjc string:@"${version}"], // 建議和App版本號保持一致。
 ResourceAttributesObjc.hostName: [AttributeValueObjc string:@"${host}"], // 建議固定為iOS。
 ResourceAttributesObjc.deploymentEnvironment: [AttributeValueObjc string:@"${environment}"] // 開發環境,一般開發階段建議設置為dev,線上環境設置為prod。
};
providerBuilder = [providerBuilder withResource: [ResourceObjc resource:resources]];
providerBuilder = [providerBuilder addSpanProcessor: spanProcessor];

// 初始化OpenTelemetrySdk。
[OpenTelemetryObjc registerTracerProvider:[providerBuilder build]];

// 配置其他的Instrumentation采集器。請根據實際業務需要進行配置。如下配置是開啟采集NSUrlSession網絡庫的請求信息。
[URLSessionInstrumentationObjc urlSessionInstrumentation:
 [URLSessionInstrumentationConfigurationObjc urlSessionInstrumentationConfiguration:[TestURLSessionInstrumentation instrumentation]]
];

變量說明如下表所示:

變量

說明

示例

${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數據。

Swift示例

let tracer: Tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "OTel Application", instrumentationVersion: "1.0.0")

ObjC示例

TracerObjc *tracer = [OpenTelemetryObjc.instance.tracerProvider getWithInstrumentationName:@"app" instrumentationVersion:@"1.0"];

創建基本Span

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

Swift示例

let spanBuilder = tracer.spanBuilder(spanName: "operation name")
let span = spanBuilder .setSpanKind(spanKind: .client).startSpan()
// do stuff
// ...
span.end()

ObjC示例

SpanBuilderObjc *spanBuilder = [_tracer spanBuilder:@"operation name"];
SpanObjc *span = [[spanBuilder setSpanKind:SpanKindObjc.CLIENT] startSpan];
// do stuff
// ...
[span end];

創建嵌套Span

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

Swift示例

func methodA() {
 let span = tracer.spanBuilder(spanName: "operation methodA").setSpanKind(spanKind: .client).startSpan()
	method(span)
 span.end()
}

func methodB(_ parent: Span) {
 let spanBuilder = tracer.spanBuilder(spanName: "operation methodB")
 spanBuilder.setParent(parent)
 let child = spanBuilder .setSpanKind(spanKind: .client).startSpan()
 // do stuff
 // ...
 child.end()
}

ObjC示例

- (void) methodA {
 SpanObjc *span = [[[_tracer spanBuilder:@"operation methodA"] setSpanKind:SpanKindObjc.CLIENT] startSpan];
 [self methodB: span];
 [span end];
}

- (void) methodB: (SpanObjc *)parent {
 SpanBuilderObjc *spanBuilder = [_tracer spanBuilder:@"operation name"];
 [spanBuilder setParent: parent];
 SpanObjc *span = [[spanBuilder setSpanKind:SpanKindObjc.CLIENT] startSpan];
 // do stuff
 // ...
 [span end];
}

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

Swift示例

func methodA() {
 let span = tracer.spanBuilder(spanName: "operation methodA").setSpanKind(spanKind: .client).startSpan()
 OpenTelemetry.instance.contextProvider.setActiveSpan(span)
 
 methodB(span)
 
 span.end()
}

func methodB(_ parent: Span) {
 let child = tracer.spanBuilder(spanName: "operation methodB").setSpanKind(spanKind: .client).startSpan()
 // do stuff
 // ...
 child.end()
}

ObjC示例

- (void) methodA {
 SpanObjc *span = [[[_tracer spanBuilder:@"operation methodA"] setSpanKind:SpanKindObjc.CLIENT] startSpan];
 [OpenTelemetryObjc.instance.contextProvider setActiveSpan:span];
 [self methodB];
 // do stuff
 // ...
 [span end];
}

- (void) methodB {
 SpanBuilderObjc *spanBuilder = [_tracer spanBuilder:@"operation name"];
 SpanObjc *span = [[spanBuilder setSpanKind:SpanKindObjc.CLIENT] startSpan];
 // do stuff
 // ...
 [span end];
}

創建帶屬性的Span

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

Swift示例

let spanBuilder = tracer.spanBuilder(spanName: "GET /resource/catalog")
let span = spanBuilder .setSpanKind(spanKind: .client).startSpan()
span.setAttribute(key: "http.method", value: "GET")
span.setAttribute(key: "http.url", value: "http url")

ObjC示例

SpanBuilderObjc *spanBuilder = [_tracer spanBuilder:@"GET /resource/catalog"];
SpanObjc *span = [[spanBuilder setSpanKind:SpanKindObjc.CLIENT] startSpan];
[span setAttribute:@"http.method" stringValue:@"GET"];
[span setAttribute:@"http.url" stringValue:request.URL.baseURL];

創建帶事件的Span

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

Swift示例

span.addEvent(name: "start")
// do stuff
// ...
span.addEvent(name: "start")

// 也可以攜帶屬性。
span.addEvent(name: "event with attributes",
 attributes: [ "key1": AttributeValue.string("value1"),
 "key2": AttributeValue.double(2.2)
 ]
)

ObjC示例

[chilsSpan addEvent:@"start"];
// do stuff
// ...
[chilsSpan addEvent:@"end"];

// 也可以攜帶屬性。
[chilsSpan addEvent:@"event with attributes" attributes:@{
 @"key1": [AttributeValueObjc string:@"value1"],
 @"key2": [AttributeValueObjc double:1.1],
}];

創建帶鏈接的Span

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

Swift示例

spanBuilder.addLink(spanContext: parent.context)
let span = spanBuilder .setSpanKind(spanKind: .client).startSpan()

ObjC示例

SpanBuilderObjc *spanBuilder = [_tracer spanBuilder:@"Another"];
[spanBuilder addLink:parent.context];

SpanObjc *span = [[spanBuilder setSpanKind:SpanKindObjc.CLIENT] startSpan];

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

給Span添加狀態

Span包含StatusCode.UNSETStatusCode.OKStatusCode.ERROR三個狀態,分別表示默認狀態、成功狀態、操作包含錯誤。例如參考如下示例,為Span添加操作包含錯誤的狀態。

Swift示例

let span = tracer.spanBuilder(spanName: "operation name").startSpan()
do {
 try expression
 // do stuff
 // ...
} catch {
 span.status = .error(description: "\(error)")
}

ObjC示例

SpanObjc *span = [[_tracer spanBuilder:@"operation name"] startSpan];
@try {
 // do stuff
 // ...
} @catch (NSException *exception) {
 [span setStatus:[StatusObjc error: exception.description]];
} @finally {
 [span end];
}

傳播上下文信息

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

Swift示例

// 在SDK初始化時,需要完成URLSessionInstrumentation的初始化。
// 按需傳入對應的參數。
URLSessionInstrumentation(
 configuration: URLSessionInstrumentationConfiguration(
 shouldInstrument: { request in
 // 是否采集該request的數據。
 return true
 }
 )
)

ObjC示例

// 在SDK初始化時,需要完成URLSessionInstrumentationObjc的初始化。
// 初始化URLSessionInstrumentationObjc時,需要傳入一個實現了URLSessionInstrumentationConfigurationImpl協議的類(可參見下面的TestURLSessionInstrumentation實現)
[URLSessionInstrumentationObjc urlSessionInstrumentation:
 [URLSessionInstrumentationConfigurationObjc urlSessionInstrumentationConfiguration:[TestURLSessionInstrumentation instrumentation]]
];

// TestURLSessionInstrumentation的實現示例。
#pragma mark - URLSessionInstrumentation
@interface TestURLSessionInstrumentation: NSObject<URLSessionInstrumentationConfigurationImpl>
+ (instancetype) instrumentation;
@end

@implementation TestURLSessionInstrumentation
+ (instancetype) instrumentation {
 return [[TestURLSessionInstrumentation alloc] init];
}
- (void)createdRequest:(NSURLRequest * _Nonnull)request span:(SpanObjc * _Nonnull)span {
 // request被創建時回調。
 [span setAttribute:@"createdRequest" stringValue:@"request created"];
}
- (void)injectCustomHeaders:(NSURLRequest * _Nonnull)request span:(SpanObjc * _Nullable)span {
 // 注入自定義請求頭。
 [(NSMutableURLRequest *)request addValue:@"custom header" forHTTPHeaderField:@"injectCustomHeaders"];
}
- (NSString * _Nullable)nameSpan:(NSURLRequest * _Nonnull)request {
 // 重命名Span。
 if ([request.URL.host containsString:@"dns.alidns.com"]) {
 return @"請求解析DNS";
 }
 return nil;
}
- (void)receivedError:(NSError * _Nonnull)error dataOrFile:(NSObject * _Nullable)dataOrFile span:(SpanObjc * _Nonnull)span {
 // 接口失敗時回調。
}
- (void)receivedResponse:(NSURLResponse * _Nonnull)response dataOrFile:(NSObject * _Nullable)dataOrFile span:(SpanObjc * _Nonnull)span {
 // 接口成功時回調。
 NSLog(@"receivedResponse: %@", dataOrFile);
}
- (BOOL)shouldInjectTracingHeaders:(NSURLRequest * _Nonnull)request {
 // 注入tracing headers。
 return YES;
}
- (BOOL)shouldInstrument:(NSURLRequest * _Nonnull)request {
 // 是否采集該request的數據。
 return YES;
}
- (BOOL)shouldRecordPayload:(NSURLSession * _Nonnull)session {
 // 是否采集請求體信息。
 return YES;
}
- (void)spanCustomization:(NSURLRequest * _Nonnull)request spanBuilder:(SpanBuilderObjc * _Nonnull)spanBuilder {
 // 自定義Span信息。
 [spanBuilder setAttribute:@"spanCustomization" stringValue:@"customize span"];
}
@end

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

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

附錄:OpenTelemetry Products說明

Swift

Objc

用途

OpenTelemetryApi

OpenTelemetryApiObjc

OpenTelemetry API的約定和最小實現。

OpenTelemetrySdk

OpenTelemetrySdkObjc

OpenTelemetry API的最小實現。

OpenTelemetryProtocolExporter

OpenTelemetryProtocolExporterObjc

OpenTelemetry Protocol實現。

StdoutExporter

StdoutExporterObjc

標準輸出Exporter,用于將Trace數據打印在console。

ResourceExtension

ResourceExtensionObjc

Resource的擴展采集實現。

URLSessionInstrumentation

URLSessionInstrumentationObjc

URLSession網絡庫的自動采集實現。

常見問題

  • 問題:使用Swift SDK后,無數據上報到日志服務。

  • 解決方法:當前SDK需要通過OtlpTraceExporter進行數據上報,請確認OtlpTraceExporter的配置是否正確。以下為正確配置的示例。

    重要
    • host中不能添加 http:// https://

    • port必須設置為10010。

    let client = ClientConnection
    .usingPlatformAppropriateTLS(for: MultiThreadedEventLoopGroup(numberOfThreads: 1))
    .connect(host: "cn-beijing.log.aliyuncs.com", port: 10010)
    
    let otlpTraceExporter = OtlpTraceExporter(channel: client, config: OtlpConfiguration(timeout: OtlpConfiguration.DefaultTimeoutInterval, headers: [
     ("x-sls-otel-project", "your trace project"),
     ("x-sls-otel-instance-id", "your trace instance id"),
     ("x-sls-otel-ak-id", "your access key id"),
     ("x-sls-otel-ak-secret", "your access key secret")
    ]))