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

關聯網絡質量分析器與Trace服務

重要

本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業務造成影響,請務必仔細閱讀。

在使用網絡質量分析器排查問題時可能需要把業務數據串聯起來。本文主要介紹在app中同時集成網絡質量分析器SDK和Trace SDK來實現數據的交互串聯。

前提條件

已開通Trace應用。具體操作,請參見開通Trace應用

重要

Trace應用開通后,記錄projectproject關聯的endpoint實例ID,用于后續配置SDK參數時使用。

SDK集成

  • Android

    在app或module級別的build.gradle文件中加入以下配置內容:

    // sls android SDK,如果已經集成,可以不更新版本號
    implementation 'io.github.aliyun-sls:aliyun-log-android-sdk:2.7.0@aar'
    
    // 網絡探測SDK
    implementation 'io.github.aliyun-sls:sls-android-network-diagnosis:2.2.1@aar'
    implementation 'io.github.aliyun-sls:sls-android-core:1.0.8@aar'
    implementation 'io.github.aliyun-sls:sls-android-ot:1.0.8.1@aar'
    
    // opentelemetry extension
    implementation 'io.github.aliyun-sls:android-otel-common:1.1.0@aar'
    implementation 'io.github.aliyun-sls:android-exporter-otlp:1.1.1@aar'
      
    // opentelemetry sdk
    implementation(platform("io.opentelemetry:opentelemetry-bom:1.30.0"))
    implementation("io.opentelemetry:opentelemetry-api")
    implementation("io.opentelemetry:opentelemetry-context")
    implementation('io.opentelemetry:opentelemetry-sdk')
    implementation("io.opentelemetry:opentelemetry-semconv:1.30.0-alpha")
  • iOS

    iOS新版本的依賴包與之前版本有所不同,建議按照以下方式導入依賴。

    在項目Podfile加入以下內容:

    use_frameworks!
    source 'https://gitee.com/aliyun-sls/Specs.git'
    target '${your_target}' do |t|
      # SLS iOS SDK
      pod 'AliyunLogProducer', '4.1.0'
      # OpenTelemetry Extension
      pod 'AliyunLogOTelCommon', '4.1.0'
      pod 'AliyunLogOtlpExporter', '4.1.0'
      # 網絡探測SDK
      pod 'AliyunLogNetworkDiagnosis', '4.1.0'
    end

SDK初始化

  1. 網絡質量探測SDK初始化

    具體操作,請參見SDK插件使用說明

    以下是初始化示例代碼,供參考:

    Android

    Credentials credentials = new Credentials();
    NetworkDiagnosisCredentials networkDiagnosisCredentials = credentials.getNetworkDiagnosisCredentials();
    networkDiagnosisCredentials.endpoint = "${ipa_endpoint}";
    networkDiagnosisCredentials.project = "${ipa_project}";
    networkDiagnosisCredentials.secretKey = "${ipa_secretKey}"
    
    final OptionConfiguration optionConfiguration = configuration -> {
        configuration.enableNetworkDiagnosis = true;
    };
    
    // 預先初始化。在用戶同意數據隱私合規之前調用
    SLSAndroid.preInit(context, credentials, optionConfiguration);
    
    // 用戶同意數據隱私合規協議后,完整初始化
    SLSAndroid.initialize(context, credentials, optionConfiguration);
    
    // 注冊SDK回調
    SLSAndroid.registerCredentialsCallback(new Callback() {
        @Override
        public void onCall(String feature, LogProducerResult result) {
            // 參數錯誤,或AK沒有設置
            if (LogProducerResult.LOG_PRODUCER_SEND_UNAUTHORIZED == result ||
                LogProducerResult.LOG_PRODUCER_PARAMETERS_INVALID == result) {
                // 處理token過期,AK失效等鑒權類問題
                Credentials credentials = new Credentials();
                credentials.accessKeyId = "${ipa_accesskey_id}";
                credentials.accessKeySecret = "${ipa_accesskey_secret}";
                // credentials.securityToken = "${ipa_accesskey_token}";// 僅當通過STS方式獲取的AK時才需要設置
    
                // 如果是僅更新 AK 的話,可以不對NetworkDiagnosisCredentials進行更新
                //NetworkDiagnosisCredentials networkDiagnosisCredentials = credentials
                // .getNetworkDiagnosisCredentials();
                // networkDiagnosisCredentials.endpoint = "${ipa_endpoint}";
                // networkDiagnosisCredentials.project = "${ipa_project}";
                // networkDiagnosisCredentials.secretKey = ""; // secretKey不支持動態更新
    
                SLSAndroid.setCredentials(credentials);
            }
        }
    });

    iOS

    // 導入依賴模塊
    import AliyunLogNetworkDiagnosis
    
    let credentials = SLSCredentials()
    let networkDiagnosisCredentials = credentials.createNetworkDiagnosisCredentials()
    networkDiagnosisCredentials.endpoint = "${ipa_endpoint}"
    networkDiagnosisCredentials.project = "${ipa_project}"
    networkDiagnosisCredentials.secretKey = "${ipa_secretKey}"
    
    let configutaionHandler: ((SLSConfiguration) -> Void) = { configuration in
        configuration.enableNetworkDiagnosis = true
    }
    
    // 預先初始化。在用戶同意數據隱私合規之前調用
    SLSCocoa.sharedInstance().preInit(credentials, configuration: configutaionHandler)
    // 用戶同意數據隱私合規協議后,完整初始化
    SLSCocoa.sharedInstance().initialize(credentials, configuration: configutaionHandler)
    
    // 注冊SDK回調
    SLSCocoa.sharedInstance().registerCredentialsCallback { feature, code in
        // 參數錯誤,或AK沒有設置
        if ("LogProducerParametersInvalid" == code) {
            let credentials = SLSCredentials()
            let networkDiagnosisCredentials = credentials.createNetworkDiagnosisCredentials()
            networkDiagnosisCredentials.endpoint = "${ipa_endpoint}"
            networkDiagnosisCredentials.project = "${ipa_project}"
            // networkDiagnosisCredentials.secretKey 不支持動態更新
            
            credentials.accessKeyId = "${ipa_accesskey_id}"
            credentials.accessKeySecret = "${ipa_accesskey_secret}"
            // networkDiagnosisCredentials.securityToken = "${ipa_accesskey_token}" // 僅當通過STS方式獲取的AK時才需要設置
            
            SLSCocoa.sharedInstance().setCredentials(credentials)
        }
        
        // AK過期或無效
        if ("LogProducerSendUnauthorized" == code) {
            let credentials = SLSCredentials()
            credentials.accessKeyId = "${ipa_accesskey_id}"
            credentials.accessKeySecret = "${ipa_accesskey_secret}"
            // credentials.securityToken = "${ipa_accesskey_token}" // 僅當通過STS方式獲取的AK時才需要設置
            
            SLSCocoa.sharedInstance().setCredentials(credentials)
        }
    }
  2. Trace SDK初始化

    警告

    必須確保網絡探測SDK已經初始化,才能進行這一步。

    示例代碼如下:

    Android

    // 全局設置
    // 參數配置錯誤,或者AK訪問失效時會回調以下方法
    ConfigurationManager.getInstance().setProvider(
        scope -> {
            if ("ipa".equalsIgnoreCase(scope)) {
                return AccessKey.accessKey(
                    "${ipa_accesskey_id}",
                    "${ipa_accesskey_secret}",
                    "${ipa_accesskey_token}" 
                );
            }
    
            if ("trace".equalsIgnoreCase(scope)) {
                AccessKey.accessKey(
                    "${trace_accesskey_id}",
                    "${trace_accesskey_secret}",
                    "${trace_accesskey_token}" 
                );
            }
    
            return null;
        },
        scope -> {
            if ("ipa".equalsIgnoreCase(scope)) {
                return Workspace.workspace(
                    "${ipa_endpoint}",
                    "${ipa_project}",
                    "ipa-${ipa_instanceId}-raw"
                );
            }
    
            if ("trace".equalsIgnoreCase(scope)) {
                return Workspace.workspace(
                    "${trace_endpoint}",
                    "${trace_project}",
                    "${trace_instanceId}-traces"
                );
            }
    
            return null;
        },
        scope -> {
            // 該配置用不到,直接返回null即可
            return null;
        }
    );
    
    // 初始化Trace Exporter,用于導出數據到Trace
    OtlpSLSSpanExporter exporter = OtlpSLSSpanExporter.builder()
        .setScope("trace")
        .setEndpoint("${trace_endpoint}")
        .setProject("${trace_project}")
        .setLogstore("${trace_instanceId}-traces")
        .setAccessKey(PreferenceUtils.getAccessKeyId(this), PreferenceUtils.getAccessKeySecret(this), null) // 初始化時可以先不設置AK
        .build();
    
    SdkTracerProviderBuilder builder = SdkTracerProvider.builder()
        .addSpanProcessor(BatchSpanProcessor.builder(exporter).build())
        .setResource(io.opentelemetry.sdk.resources.Resource.create(Attributes.builder()
            .put(ResourceAttributes.SERVICE_NAME, "network-Trace") // 建議根據實際業務情況填寫
            .put(ResourceAttributes.SERVICE_NAMESPACE, "AndroidExamples") // 建議填寫應用名稱
            .put(ResourceAttributes.SERVICE_VERSION, BuildConfig.VERSION_NAME)
            .put(ResourceAttributes.HOST_NAME, Build.HOST)
            .put(ResourceAttributes.OS_NAME, "Android")
            .put(ResourceAttributes.OS_TYPE, "Android")
            .put(ResourceAttributes.DEVICE_ID, Utdid.getInstance().getUtdid(this)) // 設置設備Id
            .build()));
    
    // 初始化網絡質量探測 Exporter,用于導出數據到網絡質量探測
    NetworkDiagnosis.getInstance().setupTracer(builder);
    
    SdkTracerProvider tracerProvider = builder.build();
    
    OpenTelemetrySdk.builder()
        .setTracerProvider(tracerProvider)
        .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
        .buildAndRegisterGlobal();
    
    NetworkDiagnosis.getInstance().setOpenTelemetrySdk(GlobalOpenTelemetry.get());

    iOS

    // 導入依賴模塊
    import AliyunLogOTelCommon
    import OpenTelemetryApi
    import OpenTelemetrySdk
    
    // 全局配置
    // 參數配置錯誤,或者AK訪問失效時會回調以下方法
    ConfigurationManager.shared.setProvider (
        accessKeyProvider: { scope in
            // 根據scope的不同,返回對應的AccessKey,按照實際情況填寫
            // 網絡質量探測
            if ("ipa" == scope) {
                return AccessKey.`init`(
                    accessKeyId: "${ipa_accesskey_id}",
                    accessKeySecret: "${ipa_accesskey_secret}",
                    accessKeySecuritToken: "${ipa_accesskey_token}"
                )
            }
    
            // Trace
            if ("trace" == scope) {
                return AccessKey.`init`(
                    accessKeyId: "${trace_accesskey_id}",
                    accessKeySecret: "${trace_accesskey_secret}",
                    accessKeySecuritToken: "${trace_accesskey_token}"
                )
            }
            
            return nil
        },
        workspaceProvider: { scope in
            // 根據scope的不同,返回Workspace(包含endpoint、project、logstore)
            // 網絡質量探測默認不用設置,如果需要動態更新endpoint、project等相關參數,則需要按照下述方式處理
            // if ("ipa" == scope) {
            //     return Workspace.`init`(
            //         endpoint: "${ipa_endpoint}",
            //         project: "${ipa_project}",
            //         instanceId: "ipa-\("${ipa_instanceId}")-raw"
            //     )
            // }
            
            // Trace 如果涉及到動態更新,按照以下方式設置
            if ("trace" == scope) {
                return Workspace.`init`(
                    endpoint: "${trace_endpoint}",
                    project: "${trace_project}",
                    instanceId: "\("${trace_instanceId}")-traces"
                )
            }
            
            return nil
        })
    
    // 初始化Trace Exporter,用于導出數據到Trace
    let exporter = OtlpSLSSpanExporter.builder("trace")
        .setEndpoint("${trace_endpoint}")
        .setProject("${trace_project}")
        .setLogstore("${trace_instanceId}-traces")
        .build()
    
    // 初始化網絡質量探測 Exporter,用于導出數據到網絡質量探測
    let ipaExporter = NetworkDiagnosisHelper.exporter()
    
    let spanExporters = MultiSpanExporter(spanExporters: [exporter, ipaExporter])
    let spanProcessor = BatchSpanProcessor(spanExporter: spanExporters)
    let tracerProviderBuilder = TracerProviderBuilder()
        .add(spanProcessor: spanProcessor)
        .with(resource: Resource(attributes: [
            ResourceAttributes.serviceName.rawValue: AttributeValue.string("iOS-Trace"), // 可根據業務情況填寫
            ResourceAttributes.serviceNamespace.rawValue: AttributeValue.string("iOSExamples"), // 建議填寫App名稱
            ResourceAttributes.serviceVersion.rawValue: AttributeValue.string("1.0.0"), // 建議填寫App版本號
            ResourceAttributes.osName.rawValue: AttributeValue.string("iOS"), // 手機系統
            ResourceAttributes.deviceId.rawValue: AttributeValue.string(SLSUtdid.getUtdid()) // 設備Id
        ]))
    OpenTelemetry.registerTracerProvider(tracerProvider:tracerProviderBuilder.build())
  3. 變量說明

    上文SDK初始化過程使用到的變量說明如下:

    變量名

    描述

    示例

    ${ipa_endpoint}

    網絡質量分析器Endpoint。

    https://cn-hagnzhou.log.aliyuncs.com

    ${ipa_project}

    選擇目標Project。

    日志服務將自動在該Project下生成Logstore,用于存儲網絡探測數據。

    test-project

    ${ipa_secretKey}

    網絡質量分析器SecretKey,接入端應用的密鑰。更多信息,請參見使用網絡質量分析器

    ey********************************************************************************************************************************************=

    ${ipa_accesskey_id}

    網絡質量分析器AccessKey ID。

    建議您使用只具備日志服務Project寫入權限的RAM用戶的AccessKey(包括AccessKey ID和AccessKey Secret)。授予RAM用戶向指定Project寫入數據權限的具體操作,請參見RAM自定義授權示例。如何獲取AccessKey的具體操作,請參見訪問密鑰

    LA*****************

    ${ipa_accesskey_secret}

    網絡質量分析器AccessKey Secret。

    建議您使用只具備日志服務Project寫入權限的RAM用戶的AccessKey。

    fR*****************

    ${ipa_accesskey_token}

    網絡質量分析器AccessKey SecurityToken。僅當使用STS進行臨時訪問時候才需要配置的。

    T****************v

    ${trace_endpoint}

    Trace實例對應的Endpoint。

    https://cn-hangzhou.log.aliyuncs.com

    ${trace_project}

    Trace實例對應的Project名稱。

    test-project

    ${trace_instanceId}

    全棧可觀測服務實例ID。更多信息,請參見創建Trace實例

    test-traces

    ${trace_accesskey_id}

    Trace AccessKey ID。

    建議您使用只具備日志服務Project寫入權限的RAM用戶的AccessKey(包括AccessKey ID和AccessKey Secret)。授予RAM用戶向指定Project寫入數據權限的具體操作,請參見RAM自定義授權示例。如何獲取AccessKey的具體操作,請參見訪問密鑰

    LA*****************

    ${trace_accesskey_secret}

    Trace AccessKey Secret。

    建議您使用只具備日志服務Project寫入權限的RAM用戶的AccessKey。

    fR*****************

    ${trace_accesskey_token}

    Trace AccessKey SecurityToken。僅當使用STS進行臨時訪問時候才需要配置的。

    T****************v

    ${ipa_instanceId}

    網絡質量分析器應用ID。在網絡質量分析器應用中的接入端管理頁面獲取。

    Mq********************

Trace新增跳轉配置

為了能夠從Trace分析頁面跳轉到網絡探測詳情頁面,需要在Trace分析中增加事件配置。

  1. 在Trace詳情頁簽中,單擊事件配置

    image.png

  2. Drilldown配置面板中,完成如下配置:

    1. 單擊添加字段,然后選擇attribute.detection.type

      image.png

    2. 然后單擊添加事件,并選擇自定義HTTP鏈接

      image.png

      • 自定義名稱:建議輸入“網絡診斷”

      • 協議:選擇HTTPS

      • 鏈接地址:輸入以下固定鏈接

      • cms.console.aliyun.com/ipa?hide_sldebar=true&type=sls&page=detectionDetail&detectionType=${{attribute.detection.type}}&deviceId=${{attribute.detection.deviceId }}&traceId=${{attribute.detection.traceId}}&spanId=${{attribute.detection.spanId}}
      • 是否轉碼:默認配置即可

      • 打開新窗口:建議開啟

    3. 最后單擊確定按鈕保存配置

  3. 驗證配置

    按照以上方式接入數據后,您可以運行一下代碼以便產生數據。數據上報成功后,在Trace詳情頁面看到以下頁面即接入成功。

    image.png

    其中:玩家連接、玩家登錄賬號、GET /mall/api/productcategory/list 是業務Trace數據,http是網絡探測數據。

    在右側面板,鼠標放在“ping”字段上,會自動彈出一個浮層,單擊“網絡診斷”即可。

    image.png

業務鏈路串聯示例

Trace SDK通過Span來跟蹤調用鏈路。在Trace SDK的設計理念中,每個Span表示應用程序執行路徑的一段操作。Span與Span之間通過TraceId、SpanId、ParentSpanId表示次序和依賴關系。如:

  • 不同的Span通過同樣的TraceId可以關聯為一條Trace,即調用鏈路;

  • 不同的Span通過ParentSpanId可以表示依賴關系,如:B的parentSpanId是A的spanId,則B是A的子操作。

這里舉一個調用鏈路的例子,供使用Trace SDK時作為參考。有以下玩家進入游戲的過程:

image.png

以上過程有以下特性:

  • “開始”表示用戶發起游戲連接起始,“結束”表示已經進入游戲,或游戲進入失敗

  • 進入游戲成功的條件:網絡連接、資源下載、進入游戲環節都成功

  • 每個環節都有主備鏈路,主鏈路調用失敗后會發起一次網絡探測

  • 每個環節的調用順序是串聯,只有前一個環節成功后,才會調用下一個環節

  • 每次“開始”,都是一次獨立的調用鏈路

1. 開始

“開始”表示用戶發起游戲連接,在這個業務流程中,“開始”表示一次完整業務調用的開始,因此需要針對“開始”這個操作進行埋點。

  • Android埋點如下:

    Tracer tracer = GlobalOpenTelemetry.get().getTracer("connect");
    final Span startSpan = tracer.spanBuilder("開始連接游戲").startSpan();
    // 由于后續流程的操作都需要和“開始”span關聯,我們需要把它設為“活躍”狀態,后續流程產生的Span就會和“開始”自動關聯,建議通過以下方式:
    try (Scope ignored = span.makeCurrent()) {
        // 后續流程的調用放在這里
    } finally {
        startSpan.end();
    }
    
  • iOS埋點如下:

    // 構建一個tracer,該tracer為當前流程共用
    let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "connect", instrumentationVersion: "1.0.0")
    
    // 產生一個“開始”span
    let startSpan = tracer.spanBuilder(spanName: "開始連接游戲").startSpan()
    // 由于后續流程的操作都需要和“開始”span關聯,我們需要把它設為“活躍”狀態,后續流程產生的Span就會和“開始”自動關聯
    OpenTelemetry.instance.contextProvider.setActiveSpan(span)

2. 網關鏈接

網關存在主備鏈路,當連接失敗時,需要對當前鏈路發起一次網絡探測。

  • Android示例代碼:

    public void connectProxy() {
        final Span connectSpan = tracer.spanBuilder("連接網關")
                            .startSpan()
        // 后續主備線路的連接產生的span都作為connectSpan的子節點存在
        OpenTelemetry.instance.contextProvider.setActiveSpan(span)
        var success = connectProxy("主線路")
        // 如果連接失敗,則鏈接備用線路
        success = connectProxy("備用線路1")
    
        // 不管連接成功或失敗,都需要結束connectSpan
        connectSpan.end()
    }
    
    private boolean connectProxy(String line) {
      final Span proxySpan = tracer.spanBuilder("連接網關")
                            .setAttribute("proxy_line", line)
                            .startSpan();
      // 連接的具體過程省略
      // ...
      
      // 如果連接失敗,需要發起tcp類型的網絡探測
      try (Scope ignored = proxySpan.makeCurrent()) {
          TcpPingRequest request = new TcpPingRequest();
          request.domain = "www.aliyun.com";
          request.port = 8888;
          NetworkDiagnosis.getInstance().tcpPing(request);
      } finally {
          // 連接過程結束后,結束proxySpan
          proxySpan.end()
      }
      return true
    }
  • iOS:

    func connectProxy() {
        let connectSpan = tracer.spanBuilder(spanName: "連接網關").startSpan()
        // 后續主備線路的連接產生的span都作為connectSpan的子節點存在
        OpenTelemetry.instance.contextProvider.setActiveSpan(span)
        var success = connectProxy("主線路")
        // 如果連接失敗,則鏈接備用線路
        success = connectProxy("備用線路1")
    
        // 不管連接成功或失敗,都需要結束connectSpan
        connectSpan.end()
    }
    
    func connectProxy(line: String) -> Bool {
      let proxySpan = tracer.spanBuilder(spanName: "連接網關")
                            .setAttribute(key: "proxy_name", value: line)
                            .startSpan()
      // 連接的具體過程省略
      // ...
      
      // 如果連接失敗,需要發起tcp類型的網絡探測
      OpenTelemetry.instance.contextProvider.setActiveSpan(proxySpan) // 可選,如果增加這一行,網絡探測的Span會作為proxySpan的子span存在
      let request = SLSTcpPingRequest()
      request.domain = "www.aliyun.com"
      request.port = 8888
      SLSNetworkDiagnosis.sharedInstance().tcpPing2(request)
      
      // 連接過程結束后,結束proxySpan
      proxySpan.end()
    
      return true
    }

3. 資源下載、進入游戲

與網關連接的操作相似,這里省略。

4. 結束

不管整個流程成功或是失敗,結束流程都需要處理。

  • Android已經在 finally 代碼塊中結束了startSpan,不需要額外處理。

  • iOS:

    // 結束startSpan即可
    startSpan.end()