
# 应用通过OpenTelemetry探针接入APM实现链路追踪指标监控
Java应用，PHP应用，GO应用，Python应用，Nodejs应用、C++应用以及.Net应用支持通过OpenTelemetry探针接入APM实现链路追踪指标监控。
![](https://support.huaweicloud.com/usermanual-apm2/public_sys-resources/note_3.0-zh-cn.png)
当前支持的Region有：华北-北京四，华东-上海一，华东-上海二，华南-广州、华北-乌兰察布二零一、西南-贵阳一以及华北-乌兰察布汽车一。
#### 前提条件
已创建应用，具体操作请参考[创建应用](https://support.huaweicloud.com/usermanual-apm2/apm_07_0101.html#apm_07_0101__section19801653566)。
#### 应用通过OpenTelemetry探针接入APM实现链路追踪指标监控
1. 登录[APM控制台](https://console.huaweicloud.com/apm2/)。
2. 在左侧导航栏中选择"链路追踪 \> 探针接入"，进入接入应用页面。
3. 选择应用和区域。
4. 选择接入类型"OpenTelemetry"。如果当前应用支持OpenTelemetry类型，则SkyWalking类型置灰，不支持选择。 
   图1接入OpenTelemetry类型   
   ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002549695683.png "点击放大")
   
   
5. 根据应用类型选择接入对应的接入方式，按照步骤接入。请注意，同一个应用下的组件名称不能重复。 
   - JAVA应用接入。
     1. 下载 OpenTelemetry Java Agent。前往[Agent下载地址](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases)，下载后将 Agent 文件放在 Java 进程有访问权限的目录。
     
     2. 添加启动命令并重启应用。
        ```
        java -javaagent:探针安装路径 \
        -Dotel.exporter.otlp.protocol=grpc \
        -Dotel.exporter.otlp.traces.endpoint=http://***.**.**.***:**** \
        -Dotel.exporter.otlp.headers=Authentication= ****** \
        -Dotel.service.name=应用名称.组件名称.环境名称 \
        -Dotel.metrics.exporter=none \
        -Dotel.logs.exporter=none \
        -jar < 用户应用 >.jar
        ```
        启动命令示例：
        ```
        curl http://***.**.**.***:****/rolldice?player=Alex
        ```
        其中，"http://\*\*\*.\*\*.\*\*.\*\*\*:\*\*\*\*"与endpoint相同。
        表1参数说明 
        | 参数              | 说明                                                                                                                   |
        |:---|:---|
        | protocol        | 数据的OTLP传输协议。                                                                                                         |
        | traces.endpoint | 对接服务上报数据的ip以及端口。                                                                                                     |
        | Authentication  | 对接服务token信息。                                                                                                         |
        | service.name    | 应用名称格式：应用.子应用.组件.环境。 子应用：选填。该参数可以为空，为空代表应用挂载在根应用下面，子应用可以多层次，最多三层。比如a/b/c，其中，a、b、c各代表一层。 |
           
        关于Dotel.resource.attributes可选字段的配置说明如下：
        本配置用于支持OpenTelemetry的实例级指标与调用链监控。您可以通过设置以下字段来优化实例的标识与展示：
        - **host.name**
          - 默认值：非侵入式接入时，默认取所在环境的host名；侵入式接入时，默认为undef-hostname。
          
          - 说明：通常无需手动设置，仅在需要自定义时配置。
           
        
        - **instance.name**
          - 默认值：undef-instancename。
          
          - 说明：建议显式设置该字段以提升实例可读性及管理便利性。
           
        
        - **host.ip**
          - 默认值：若未设置，则系统会尝试从span中提取IP地址；若提取失败，则默认为undef-ip。
          
          - 说明：该字段仅用于前端页面展示，并不影响数据聚合。
           
        
        - **实例划分规则**
          - OpenTelemetry优先使用service.instance.id字段作为唯一标识（该字段用于实例划分）。
          
          - 若service.instance.id存在 （非侵入式接入默认生成该字段；侵入式接入则默认不生成）， 则系统将以此字段为依据进行实例划分。
          
          - 若service.instance.id不存在，系统将自动组合host.name与instance.name作为实例划分的依据。
           
        
        - **建议**由于service.instance.id为UUID类型，对用户不友好，页面可读性较差，因此建议您手动设置instance.name和host.ip，以便在监控页面中更直观地识别和管理实例。
          
      
   
   - PHP应用接入。
     - 方式一 非侵入式接入。
       1. 接入环境准备。
          - 已安装PHP 8.0+、PECL和composer。
          
          - 安装好以后需在shell脚本下验证PHP、composer版本。
           
       
       2. 安装OpenTelemetry扩展组件。
          1. 安装必须构建工具。
             ```
             sudo apt-get install gcc make autoconf
             ```
             
          
          2. 使用构建安装扩展组件。
             ```
             sudo apt-get install php-dev
             pecl install opentelemetry
             pecl install grpc
             pecl install protobuf-3.21.12
             ```
             
          
          3. 将扩展名添加到您的文件中：php.ini。
             ```
             [opentelemetry]
             extension=opentelemetry.so
             [PHP]
             extension=grpc.so
             extension=protobuf.so
             ```
             
          
          4. 验证扩展是否已安装并启用。
             ```
             php --ri opentelemetry
             php --ri grpc
             php --ri protobuf
             ```
             
           
       
       3. 安装服务框架所需opentelemetry依赖包。
          1. 安装服务框架所依赖的opentelemetry自动插件包，比如slim框架需安装open-telemetry/opentelemetry-auto-slim。
             ```
             composer config allow-plugins.php-http/discovery false
             composer require open-telemetry/sdk
             composer require open-telemetry/exporter-otlp
             composer require open-telemetry/transport-grpc
             composer require open-telemetry/opentelemetry-auto-slim
             composer update
             ```
             
          
          2. 接入Agent需要在环境变量或者php.ini中添加以下配置项。
             ```
             OTEL_EXPORTER_OTLP_ENDPOINT=http://***.**.**.***:*** // 对接服务上报数据的 ip 以及端口
             OTEL_EXPORTER_OTLP_HEADERS=Authentication=**** // 对接服务 token 信息
             OTEL_EXPORTER_OTLP_PROTOCOL=grpc// 数据的 OTLP 传输协议
             OTEL_PHP_AUTOLOAD_ENABLED=true
             OTEL_SERVICE_NAME=应用名称.组件名称.环境名称// 对接服务的服务名
             ```
             
           
        
     
     - 侵入式接入：请参考[官网](https://opentelemetry.io/docs/languages/php/getting-started/)。
      
   
   - GO应用接入。 使用GRPC协议上报数据。
     1. 添加OpenTelemetry依赖。
        ```
        import (
        "context"
        "go.opentelemetry.io/otel"
        "go.opentelemetry.io/otel/attribute"
        "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
        "go.opentelemetry.io/otel/sdk/resource"
        sdktrace "go.opentelemetry.io/otel/sdk/trace"
        "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
        )
        ```
        
     
     2. 对接OpenTelemetry。
        ```
        const (
        SERVICE_NAME = "应用名称.组件名称.环境名称"
        APM_ENDPOINT="***.**.**.***:****"
        APM_TOKEN= "****"
        )
        func main() {
        cleanup := initTracer()
        defer cleanup(context.Background())
        r := gin.Default()
        r.Use(otelgin.Middleware(SERVICE_NAME))
        ..业务代码
        }
        func initTracer() func(context.Context) error {
        headers := map[string]string{"Authentication": APM_TOKEN}
        exporter, err := otlptracegrpc.New(
        context.Background(),
        otlptracegrpc.WithInsecure(),
        otlptracegrpc.WithEndpoint(APM_ENDPOINT),
        otlptracegrpc.WithHeaders(headers),
        )
        if err != nil {
        log.Fatalf("Failed to create exporter: %v", err)
        }
        resources, err := resource.New(
        context.Background(),
        resource.WithAttributes(
        attribute.String("service.name", SERVICE_NAME),
        attribute.String("library.language", "go"),
        ),
        )
        if err != nil {
        log.Fatalf("Could not set resources: %v", err)
        }
        otel.SetTracerProvider(
        sdktrace.NewTracerProvider(
        sdktrace.WithSampler(sdktrace.AlwaysSample()),
        sdktrace.WithBatcher(exporter),
        sdktrace.WithResource(resources),
        ),
        )
        return exporter.Shutdown
        }
        ```
        
     
     
     表2参数说明 
     | 参数           | 说明                                                                                                                  |
     |:---|:---|
     | APM_ENDPOINT | 对接服务上报数据的ip以及端口。                                                                                                    |
     | APM_TOKEN    | 对接服务token信息。                                                                                                        |
     | SERVICE_NAME | 应用名称格式：应用.子应用.组件.环境。 子应用：选填。该参数可以为空，为空代表应用挂载在根应用下面，子应用可以多层次，最多三层。比如a/b/c，其中，a、b、c各代表一层。 |
        
     
   
   - Python应用接入。
     - 非侵入式接入。
       1. 下载相关包。
          ```
          pip install opentelemetry-distro
          pip install opentelemetry-exporter-otlp
          opentelemetry-bootstrap -a install
          ```
          
       
       2. 在启动python应用时，使用下面命令。 接入Agent需要配置token、endpoint、服务名、主机名四个参数，在您的启动文件中配置如下参数：
          ```
          opentelemetry-instrument \
          --traces_exporter otlp \
          --traces_exporter none \
          --service_name 应用名称.组件名称.环境名称 \
          --resource_attributes host.name=host.name \
          --exporter_otlp_endpoint http://***.**.**.***:**** \
          --exporter_otlp_headers Authentication=**** \
          python myapp.py
          ```
          表3参数说明 
          | 参数                     | 说明                                                                                                                    |
          |:---|:---|
          | endpoint               | 对接服务上报数据的ip以及端口。                                                                                                      |
          | headers Authentication | 对接服务token信息。                                                                                                          |
          | service_name           | 应用名称格式：应用.子应用.组件.环境。 子应用：选填。该参数可以为空，为空代表应用挂载在根应用下面，子应用可以多层次，最多三层。比如a/b/c，其中，a、b、c各代表一层。 |
             
          
        
      
   
   - Nodejs应用接入。
     - 侵入式接入。
       1. 添加依赖。
          ```
          npm install @opentelemetry/sdk-node @opentelemetry/api @opentelemetry/auto-instrumentations-node @opentelemetry/sdk-metrics @opentelemetry/sdk-trace-node
          ```
          
       
       2. 对接OpenTelemetry。 在express入口文件业务代码前面加上如下内容：
          ```
          export OTEL_TRACES_EXPORTER="otlp"
          export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
          export OTEL_EXPORTER_OTLP_ENDPOINT="http://100.79.29.106:4317"
          export OTEL_NODE_RESOURCE_DETECTORS="env,host,os"
          export OTEL_SERVICE_NAME="应用名称.组件名称.环境名称"
          export OTEL_EXPORTER_OTLP_HEADERS="Authentication=*****"
          export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
          ```
          表4参数说明 
          | 参数                    | 说明                                                                                                                     |
          |:---|:---|
          | PROTOCOL              | 数据的OTLP传输协议.                                                                                                           |
          | ENDPOINT              | 对接服务上报数据的ip以及端口。                                                                                                       |
          | EXPORTER_OTLP_HEADERS | 对接服务token信息。                                                                                                           |
          | SERVICE_NAME          | 应用名称格式：应用.子应用.组件.环境。 子应用：选填。该参数可以为空，为空代表应用挂载在根应用下面，子应用可以多层次，最多三层。比如a/b/c，其中，a、b、c各代表一层。 |
             
          
        
     
     - 其他框架接入。 请参考[官方仓库实例](https://opentelemetry.io/docs/instrumentation/php/getting-started/)。
       
     
     - 非侵入式接入。 请参考[官方网站](https://opentelemetry.io/docs/instrumentation/php/getting-started/)。
       
      
   
   - C++应用接入。 接入步骤参考[cmake构建接入opentelemetry流程](https://github.com/open-telemetry/opentelemetry-cpp/blob/v1.10.0/INSTALL.md)。
     1. 环境要求。
        1. C++版本 ≥ 14（低版本opentelemetry-cpp需要≥ C++11）。
        
        2. 请在[Supported C++ Versions and Development Platforms](https://github.com/open-telemetry/opentelemetry-cpp#supported-c-versions)中查看支持的C++版本和开发平台。
         
     
     2. 环境准备。
        1. 安装构建工具bazel，安装步骤可以参考[bazel 安装指导](https://docs.bazel.build/versions/3.7.0/install.html)。
        
        2. 通过构建OpenTelemetry C++ Library检查环境已经搭建好。
           ```
           git clone https://github.com/open-telemetry/opentelemetry-cpp.git
               cd opentelemetry-cpp
               bazel build //...
           ```
           
         
     
     3. 在项目中使用OpenTelemetry C++ Library。
        - WORKSPACE文件，内容如下：
          ```
          load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
          load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
          load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
          http_archive(
              name = "io_opentelemetry_cpp",
              sha256 = "<sha256>", # specify sha256 based on the URL specified in the urls parameter.
              strip_prefix = "opentelemetry-cpp-1.10.0",
              urls = [
                  "https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.10.0.tar.gz"
              ],
          )
          # Load OpenTelemetry dependencies after load.
          load("@io_opentelemetry_cpp//bazel:repository.bzl", "opentelemetry_cpp_deps")
          opentelemetry_cpp_deps()
          # (required after v1.8.0) Load extra dependencies required for OpenTelemetry
          load("@io_opentelemetry_cpp//bazel:extra_deps.bzl", "opentelemetry_extra_deps")
          opentelemetry_extra_deps()
          # Load gRPC dependencies after load.
          load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
          grpc_deps()
          # Load extra gRPC dependencies due to https://github.com/grpc/grpc/issues/20511
          load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
          grpc_extra_deps()
          ```
          
        
        - BUILD文件，内容如下：
          ```
          # Copyright The OpenTelemetry Authors
          # SPDX-License-Identifier: Apache-2.0
          cc_binary(
              name = "example_http_server",
              srcs = [
                  "server.cc",
                  "server.h",
              ],
              tags = ["ostream"],
              deps = [
                  "@io_opentelemetry_cpp//api",
                  "@io_opentelemetry_cpp//exporters/ostream:ostream_span_exporter",
                  "@io_opentelemetry_cpp//ext:headers",
                  "@io_opentelemetry_cpp//sdk/src/trace",
                  "@io_opentelemetry_cpp//exporters/otlp:otlp_grpc_exporter",
              ],
          )
          ```
          
        
        - 测试代码包含server.cc、server.h两个文件。 server.cc文件，内容如下：
          ```
          #include "server.h"
            #include "opentelemetry/trace/context.h"
            #include "opentelemetry/trace/semantic_conventions.h"
            #include "opentelemetry/exporters/ostream/span_exporter_factory.h"
            #include "opentelemetry/sdk/trace/exporter.h"
            #include "opentelemetry/sdk/trace/processor.h"
            #include "opentelemetry/sdk/trace/simple_processor_factory.h"
            #include "opentelemetry/sdk/trace/tracer_context.h"
            #include "opentelemetry/sdk/trace/tracer_context_factory.h"
            #include "opentelemetry/sdk/trace/tracer_provider_factory.h"
            #include "opentelemetry/trace/provider.h"
            #include "opentelemetry/context/propagation/global_propagator.h"
            #include "opentelemetry/context/propagation/text_map_propagator.h"
            #include "opentelemetry/trace/propagation/http_trace_context.h"
            #include <cstring>
            #include <string>
            #include <unistd.h>
            #include <iostream>
            #include <vector>
            #include "opentelemetry/ext/http/client/http_client.h"
            #include "opentelemetry/nostd/shared_ptr.h"
            #include "opentelemetry/sdk/trace/tracer_provider.h"
            #include "opentelemetry/exporters/otlp/otlp_grpc_exporter_factory.h"
            #include <iostream>
            #include <thread>
            namespace trace = opentelemetry::trace;
            namespace trace_sdk = opentelemetry::sdk::trace;
            namespace otlp = opentelemetry::exporter::otlp;
            namespace {
              using namespace opentelemetry::trace;
              namespace context = opentelemetry::context;
              opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
              uint16_t server_port = 8800;
              constexpr const char *server_name = "localhost";
              std::string getHostName() {
                  char hostname[256];
                  if (gethostname(hostname, sizeof(hostname)) == 0) {
                      return hostname;
                  } else {
                      return "default_hostname";
                  }
              }
              template<typename T>
              class HttpTextMapCarrier : public opentelemetry::context::propagation::TextMapCarrier {
              public:
                  HttpTextMapCarrier(T &headers) : headers_(headers) {}
                  HttpTextMapCarrier() = default;
                  virtual opentelemetry::nostd::string_view Get(opentelemetry::nostd::string_view key) const noexcept override {
                      std::string key_to_compare = key.data();
                      // Header's first letter seems to be  automatically capitaliazed by our test http-server, so
                      // compare accordingly.
                      if (key == opentelemetry::trace::propagation::kTraceParent) {
                          key_to_compare = "Traceparent";
                      } else if (key == opentelemetry::trace::propagation::kTraceState) {
                          key_to_compare = "Tracestate";
                      }
                      auto it = headers_.find(key_to_compare);
                      if (it != headers_.end()) {
                          return it->second;
                      }
                      return "";
                  }
                  virtual void Set(opentelemetry::nostd::string_view key, opentelemetry::nostd::string_view value) noexcept override {
                      headers_.insert(std::pair<std::string, std::string>(std::string(key), std::string(value)));
                  }
                  T headers_;
              };
              void InitTracer() {
                  // Change this parameter based on the configuration of the access site.
                std::string endpoint = "http://***.**.**.***:****";
                std::string token = "*****";
                std::string serviceName = "应用名称.组件名称.环境名称";
                opts.endpoint = endpoint;
                opts.metadata.insert(std::pair<std::string, std::string>("authentication", token));
                // Create OTLP exporter instance
                auto exporter = otlp::OtlpGrpcExporterFactory::Create(opts);
                auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
                opentelemetry::sdk::resource::ResourceAttributes attributes = {
                    {"service.name", serviceName},
                    {"host.name",    getHostName()}
                };
                auto resource = opentelemetry::sdk::resource::Resource::Create(attributes);
                std::shared_ptr <opentelemetry::trace::TracerProvider> provider = trace_sdk::TracerProviderFactory::Create(std::move(processor), std::move(resource));
                // Set the global trace provider
                trace::Provider::SetTracerProvider(provider);
              }
              void CleanupTracer() {
                // We call ForceFlush to prevent to cancel running exportings, It's optional.
                opentelemetry::nostd::shared_ptr <opentelemetry::trace::TracerProvider> provider = trace::Provider::GetTracerProvider();
                if (provider) {
                    static_cast<trace_sdk::TracerProvider *>(provider.get())->ForceFlush();
                }
                std::shared_ptr <opentelemetry::trace::TracerProvider> none;
                trace::Provider::SetTracerProvider(none);
              }
              opentelemetry::nostd::shared_ptr <opentelemetry::trace::Tracer> get_tracer(std::string tracer_name) {
                auto provider = opentelemetry::trace::Provider::GetTracerProvider();
                return provider->GetTracer(tracer_name);
              }
              class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback {
              public:
                virtual int onHttpRequest(HTTP_SERVER_NS::HttpRequest const &request, HTTP_SERVER_NS::HttpResponse &response) override {
                    StartSpanOptions options;
                    options.kind = SpanKind::kServer;  // server
                    std::string span_name = request.uri;
                    // extract context from http header
                    std::map <std::string, std::string> &request_headers =
                            const_cast<std::map <std::string, std::string> &>(request.headers);
                    const HttpTextMapCarrier<std::map < std::string, std::string>>
                    carrier(request_headers);
                    auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
                    auto current_ctx = context::RuntimeContext::GetCurrent();
                    auto new_context = prop->Extract(carrier, current_ctx);
                    options.parent = GetSpan(new_context)->GetContext();
                    // start span with parent context extracted from http header
                    auto span = get_tracer("http-server")
                            ->StartSpan(span_name,
                            {{"server.address", server_name},
                            {"server.port",    server_port},
                            {"http.method",    request.method},
                            {"url.scheme",     "http"},
                            {"http.request.body.size",
                            static_cast<uint64_t>(request.content?.length())},
                            {"client.address", request.client}},
                            options);
                    auto scope = get_tracer("http_server")->WithActiveSpan(span);
                    for (auto &kv : request.headers) {
                        span->SetAttribute("http.header." + std::string(kv.first.data()), kv.second);
                    }
                    if (request.uri == "/helloworld") {
                        span->AddEvent("Processing request");
                        response.headers[HTTP_SERVER_NS::CONTENT_TYPE] = HTTP_SERVER_NS::CONTENT_TYPE_TEXT;
                        response.body = "Welcome to the APM demo!";
                        span->End();
                        return 200;
                    }
                    span->End();
                    return 404;
                }
              };
            }  // namespace
            int main(int argc, char *argv[]) {
                InitTracer();
                // The port the validation service listens to can be specified via the command line.
                if (argc > 1) {
                  server_port = (uint16_t) atoi(argv[1]);
                }
                HttpServer http_server(server_name, server_port);
                RequestHandler req_handler;
                http_server.AddHandler("/helloworld", &req_handler);
                auto root_span = get_tracer("http_server")->StartSpan(__func__);
                Scope scope(root_span);
                http_server.Start();
                std::cout << "Server is running..Press ctrl-c to exit...
          ";
                while (1) {
                  std::this_thread::sleep_for(std::chrono::seconds(100));
                }
                http_server.Stop();
                root_span->End();
                CleanupTracer();
                return 0;
            }
          ```
          表5参数说明 
          | 参数          | 说明                                                                                                                    |
          |:---|:---|
          | endpoint    | 对接服务上报数据的ip以及端口。                                                                                                      |
          | token       | 对接服务token信息。                                                                                                          |
          | serviceName | 应用名称格式：应用.子应用.组件.环境。 子应用：选填。该参数可以为空，为空代表应用挂载在根应用下面，子应用可以多层次，最多三层。比如a/b/c，其中，a、b、c各代表一层。 |
             
          server.h 文件，内容如下：
          ```
          // Copyright The OpenTelemetry Authors
          // SPDX-License-Identifier: Apache-2.0
          #pragma once
          #include <atomic>
          #include <string>
          #include "opentelemetry/ext/http/server/http_server.h"
          namespace {
              class HttpServer : public HTTP_SERVER_NS::HttpRequestCallback {
              protected:
                  HTTP_SERVER_NS::HttpServer server_;
                  std::string server_url_;
                  uint16_t port_;
                  std::atomic<bool> is_running_{false};
              public:
                  HttpServer(std::string server_name = "test_server", uint16_t port = 8800) : port_(port) {
                      server_.setServerName(server_name);
                      server_.setKeepalive(false);
                  }
                  void AddHandler(std::string path, HTTP_SERVER_NS::HttpRequestCallback *request_handler) {
                      server_.addHandler(path, *request_handler);
                  }
                  void Start() {
                      if (!is_running_.exchange(true)) {
                          server_.addListeningPort(port_);
                          server_.start();
                      }
                  }
                  void Stop() {
                      if (is_running_.exchange(false)) {
                          server_.stop();
                      }
                  }
                  ~HttpServer() { Stop(); }
              };
          }  // namespace
          ```
          
         
      
   
   - .Net应用接入。
     1. 添加OpenTelemetry依赖。
        ```
        curl -L -O https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh 
        chmod +x otel-dotnet-auto-install.sh 
        ./otel-dotnet-auto-install.sh
        ```
        
     
     2. 对接OpenTelemetry。
        ```
        export OTEL_TRACES_EXPORTER=otlp \
        OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
        OTEL_METRICS_EXPORTER=none OTEL_LOGS_EXPORTER=none \
        OTEL_SERVICE_NAME=应用名称.组件名称.环境名称 \
        OTEL_EXPORTER_OTLP_ENDPOINT=***.**.**.***:**** \
        OTEL_EXPORTER_OTLP_HEADERS="Authentication=****
        . $HOME/.otel-dotnet-auto/instrument.sh
        ```
        表6参数说明 
        | 参数             | 说明                                                                                                                     |
        |:---|:---|
        | PROTOCOL       | 数据的 OTLP 传输协议。                                                                                                         |
        | ENDPOINT       | 对接服务上报数据的 ip 以及端口。                                                                                                     |
        | Authentication | 对接服务 token 信息。                                                                                                         |
        | SERVICE_NAME   | 应用名称格式：应用.子应用.组件.环境。 子应用：选填。该参数可以为空，为空代表应用挂载在根应用下面，子应用可以多层次，最多三层。比如a/b/c，其中，a、b、c各代表一层。 |
           
        
      
   
   
   
   
 
