更新时间:2025-09-29 GMT+08:00
分享

探针接入

目前支持的探针类型包括Skywalking和OpenTelemetry两类。

表1 探针接入列表

探针类型

目前支持的接入类型

目前支持的局点

Skywalking

JAVA应用,Python应用,GO应用,Nodejs应用,PHP应用以及.Net应用接入。

华北-北京四,华东-上海一,华东-上海二,华南-广州以及华北-乌兰察布二零一。

OpenTelemetry

JAVA应用,PHP应用,GO应用,Python应用,Nodejs应用、C++应用以及.Net应用接入。

华北-北京四,华东-上海一,华东-上海二,华南-广州、华北-乌兰察布二零一、西南-贵阳一以及华北-乌兰察布汽车一。

Skywalking接入

  1. 登录APM控制台
  2. 单击左侧,选择“管理与监管 > 应用性能管理 APM”,进入APM服务页面。
  3. 在左侧导航栏中选择“链路追踪 > 探针接入”,进入接入应用页面。
  4. 选择“区域”和“应用”。
  5. 选择接入类型“Skywalking”。如果当前应用支持Skywalking类型,则OpenTelemetry类型置灰,不支持选择。

    图1 接入Skywalking类型

  6. 根据应用类型选择接入对应的接入方式,按照步骤接入。请注意,同一个应用下的组件名称不能重复。

    • JAVA应用接入
      1. 下载 Skywalking。

        前往Skywalking 官网,推荐下载 Java Agent 8.9.0 及以上版本,解压后 Agent 文件放至在 Java 进程有访问权限的目录。

        如需配置插件,在启动阶段将新的插件放进/plugins目录中,即可令插件生效。将插件从该目录删除,即可令其失效。

        日志文件默认输出到/logs目录中。

      2. 添加启动命令并重启应用。

        接入 Agent 配置相关参数,有如下两种配置方式。

        • 在应用程序的启动命令行中配置。
          java -javaagent:skywalking-agent-path -Dskywalking.collector.backend_service=***.**.**.**:***** -Dskywalking.agent.authentication=******* -Dskywalking.agent.service_name=应用名称.组件名称.环境名称 -jar <yourApp>.jar
        • 在 agent/config/agent.config 中配置。
          collector.backend_service=100.79.29.107:11800
          agent.authentication=*****
          agent.service_name=应用名称.组件名称.环境名称
          //配置 javaagent 路径,并重新启动应用。
          java -javaagent:skywalking-agent-path -jar yourApp.jar

        如果您两种方式均进行配置,则只在启动命令行中的配置生效。

    • Python应用接入
      1. 前往Skywalking 官网下载 Skywalking。
      2. 通过 PyPi 安装 Python 代理模块。
        pip install "apache-skywalking"
        pip install "apache-skywalking[http]"
        pip install "apache-skywalking[kafka]"
        pip install apache-skywalking==0.7.0

        通过 pip 成功安装 Skywalking Python 代理后,会在您的环境中安装一个命令行脚本 sw-python。

      3. 接入 Agent。

        接入 Agent 需要配置 接入点、令牌(Token)、应用名称三个参数,在您的启动文件中配置如下参数:

        from skywalking import agent, config
                  config.init(
                  collector_address='***.**.**.**:*****',
                  authentication='*******',
                  service_name='apply name',
                  )
                  agent.start()
      4. 重启应用。

        目前,sw-pythonCLI 提供了一个 run 选项,您可以使用该选项来执行您的应用程序。

        如果您之前运行 gunicorn 应用程序的命令是:

        gunicorn app.wsgi

        请将其改为:

        sw-python run gunicorn app.wsgi

        Skywalking Python 代理将很快与您的应用程序一起启动。

    • GO应用接入
      1. 前往Skywalking 官网下载 Skywalking。
      2. 安装 Skywalking go sdk,命令如下。
        go get -u github.com/SkyAPM/go2sky-plugins/sql
      3. 接入 sdk。

        在 main.go 文件导入 sdk 包。

        import (
                "github.com/SkyAPM/go2sky"
                "github.com/SkyAPM/go2sky/reporter"
              )

        在 main 方法里接入 sdk

        r, err := reporter.NewGRPCReporter(***.**.**.**:*****,
        reporter.WithCDS(0),
        reporter.WithAuthentication(******))
        if err != nil {
            log.Fatalf("new reporter error %v \n", err)
        }
        defer r.Close()
        tracer, err := go2sky.NewTracer(<应用名称.组件名称.环境名称>,
        go2sky.WithReporter(r))
        if err != nil {
            log.Fatalf("create tracer error %v \n", err)
        }
        go2sky.SetGlobalTracer(tracer)
    • Nodejs应用接入
      1. 前往Skywalking 官网下载 Skywalking。
      2. 使用官方推荐的新库来接入,原来的模块为:SkyAPM-nodejs,版本要求 NodeJS >= 10,控制台输入命令:
        npm i skywalking-backend-js
      3. 接入 Agent。

        接入 Agent 需要配置 接入点、令牌 Token、应用名称三个必填参数,在您的启动文件中配置如下参数:

        const { default: agent } = require('skywalking-backend-js');
              agent.start({
                serviceName: '应用名称.组件名称.环境名称',
                collectorAddress: '***.**.**.**:*****',
                authorization: '*********'
              });
      4. 重启应用。按照正常命令启动项目,无报错,数据正常上报即启动成功。如出现报错,请检查配置与版本;如无上报数据,请检查 token 与应用名称是否正确。
    • PHP应用接入
      1. 前往Skywalking 官网下载 Skywalking。
        • 使用官方推荐的 pecl.net 安装,控制台输入命令:
          pecl install skywalking_agent
        • 或通过源代码的方式安装:
          git clone --recursive https://github.com/apache/skywalking-php.git
          cd skywalking-php
          phpize
          ./configure
          make
          make install
      2. 接入 Agent。

        修改 php.ini 文件如下配置项:

        [skywalking]
        extension=skywalking.so
        skywalking.app_code = 应用名称.组件名称.环境名称
        skywalking.enable = 1
        skywalking.version = 8
        skywalking.grpc = ***.**.**.***:*****
        skywalking.authentication = ******
        skywalking.error_handler_enable = 0
      3. 重启应用。
        • 方法一: 将修改 php-fpm.conf 的配置项中启动方式为 daemonize = no
        • 方法二:使用 nohup 命令重启 php-fpm:
          nohup /usr/local/services/php7/sbin/php-fpm > /usr/local/services/php7/log/php-fpm-output.log 2>&1 &
    • .Net应用接入
      1. 前往Skywalking 官网下载 Skywalking。

        添加库SkyAPM .NET Core Agent。

        dotnet add package SkyAPM.Agent.AspNetCore
      2. 接入 Agent。

        下载配置文件生成工具:SkyAPM.DotNet.CLI。

        dotnet tool install -g SkyAPM.DotNet.CLI 

        使用工具生成 skyapm.json 文件。

        dotnet skyapm config 应用名称.组件名称.环境名称 ***.**.**.***:*****

        修改 skyapm.json 中的 Authentication。

        Authentication: "***********"

        在项目 Properties 下的 launchSettings.json 文件,添加环境变量:ASPNETCORE_HOSTINGSTARTUPASSEMBLIES 和 SKYWALKING__SERVICENAME。

        environmentVariables: {
              "SKYWALKING__SERVICENAME": "应用名称.组件名称.环境名称",
              "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SkyAPM.Agent.AspNetCore"
              } 

OpenTelemetry接入

  1. 在左侧导航栏中选择“链路追踪 > 探针接入”,进入接入应用页面。
  2. 选择“区域”和“应用”。
  3. 选择接入类型“OpenTelemetry”。

    如果当前应用支持OpenTelemetry类型,则Skywalking类型置灰,不支持选择。

    图2 接入OpenTelemetry类型

  4. 根据应用类型选择接入对应的接入方式,按照步骤接入。请注意,同一个应用下的组件名称不能重复。

    • JAVA应用接入
      1. 下载 OpenTelemetry Java Agent。前往Agent 下载地址,推荐下载1.x版本,下载后将 Agent 文件放在 Java 进程有访问权限的目录。
      2. 添加启动命令并重启应用。
        java -javaagent:opentelemetry-agent-path -Dotel.exporter.otlp.traces.endpoint=http://***.**.**.***:**** -Dotel.exporter.otlp.headers=Authentication=***** -Dotel.service.name=应用名称.组件名称.环境名称 -Dotel.metrics.exporter=none -jar 用户应用.jar

        启动命令示例:

        java -javaagent:/root/my-dir/opentelemetry-javaagent.jar -Dotel.exporter.otlp.traces.endpoint=http://100.79.29.106:4317 -Dotel.exporter.otlp.headers=Authentication=QxHHU69weF2c66b5DaCSNiGJAmqnRrH55DUikIJaf3ghVygIMMzgmuNioIZsH6hyE8GEOGVbXzjIXCPUjoYuUYEdjdvB6rm00nOZTXeADOfjSR84hKPNquiQg39egulwtTzORW3pLHgi03D2mynBncuna1afpx0tCxEFrETXex2o7SPJRijJK9Z3k7PHTqgk7WiMVohcMid7TLjMRPTqj7ziFOZk2EljkQi2DSpKbOKEOBE1iHEUeYO5dB167ic5 -Dotel.service.name=default.my-service.dev -Dotel.metrics.exporter=none -jar myApp.jar
    • PHP应用接入
      • 方式一 非侵入式接入。
        1. 接入环境准备。

          PHP 8.0+、PECL以及composer。安装好以后需在 shell 脚本下验证 PHP、composer 版本。

        2. 安装 OpenTelemetry 扩展组件。
          1. 安装必须构建工具。
            sudo apt-get install gcc make autoconf
          2. 使用构建安装扩展组件。
            pecl install opentelemetry-beta
            pecl install grpc
            pecl install protobuf-3.8.0
          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://***.**.**.***:****
            OTEL_EXPORTER_OTLP_HEADERS=Authentication=******
            OTEL_EXPORTER_OTLP_PROTOCOL=grpc
            OTEL_PHP_AUTOLOAD_ENABLED=true
            OTEL_SERVICE_NAME=应用名称.组件名称.环境名称
      • 侵入式接入:参考官网
    • GO应用接入

      使用 GRPC 协议上报数据

      1. 添加 OpenTelemetry依赖。
        import (
         "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
         "go.opentelemetry.io/otel"
         "go.opentelemetry.io/otel/baggage"
         "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
         "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
         "google.golang.org/grpc"
         "go.opentelemetry.io/otel/propagation"
         "go.opentelemetry.io/otel/sdk/resource"
         sdktrace "go.opentelemetry.io/otel/sdk/trace"
         semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
        )
      2. 对接 OpenTelemetry。
        const (
         SERVICE_NAME = "应用名称.组件名称.环境名称"
         GRPC_ENDPOINT="***.**.**.***:****"
         GRPC_TOKEN= "****"
        )
        
        func main() {
         init := initialization()
         defer init()
         grpc := otel.Tracer("服务本身名称")
         method, _ := baggage.NewMember("method", "repl")
         client, _ := baggage.NewMember("client", "cli")
         bag, _ := baggage.New(method, client)
         context := baggage.ContextWithBaggage(context.Background(), bag)
         for {
          ctx, span := grpc.Start(context, "CreateSpan")
          createSpan(ctx)
          span.End()
          time.Sleep(time.Duration(1) * time.Second)
         }
        }
        func initialization() func() {
         ctx := context.Background()
         headers := map[string]string{"Authentication": APM_TOKEN}
         traceClientGrpc := otlptracegrpc.NewClient(
          otlptracegrpc.WithInsecure(),
          otlptracegrpc.WithEndpoint(APM_ENDPOINT),
          otlptracegrpc.WithHeaders(headers),
          otlptracegrpc.WithDialOption(grpc.WithBlock()))
         traceExp, err := otlptrace.New(ctx, traceClientGrpc)
         if err != nil {
          log.Fatalf("%s: %v", "can not create exporter", err)
         }
         res, err := resource.New(ctx,
         resource.WithFromEnv(),
         resource.WithProcess(),
         resource.WithTelemetrySDK(),
         resource.WithHost(),
         resource.WithAttributes(
          semconv.ServiceNameKey.String(SERVICE_NAME),
          semconv.HostNameKey.String(APM_ENDPOINT),
         ),
         )
         if err != nil {
          log.Fatalf("%s: %v", "can not create exporter", err)
         }
         bsp := sdktrace.NewBatchSpanProcessor(traceExp)
         tracerProvider := sdktrace.NewTracerProvider(
          sdktrace.WithSampler(sdktrace.AlwaysSample()),
          sdktrace.WithResource(res),
          sdktrace.WithSpanProcessor(bsp),
         )
         otel.SetTextMapPropagator(propagation.TraceContext{})
         otel.SetTracerProvider(tracerProvider)
         return func() {
          cxt, cancel := context.WithTimeout(ctx, time.Second)
          defer cancel()
          if err := traceExp.Shutdown(cxt); err != nil {
           otel.Handle(err)
          }
         }
        }
        func createSpan(ctx context.Context) {
         address := "远程服务端地址"
         client := http.Client {
          Transport: otelhttp.NewTransport(http.DefaultTransport),
         }
         req, err := http.NewRequestWithContext(ctx, "GET", address, nil)
         res, err := client.Do(req)
         if err != nil {
          log.Println(err)
         } else {
          res.Body.Close()
         }
        }
        
    • 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     --service_name 应用名称.组件名称.环境名称     --resource_attributes host.name=host.name     --exporter_otlp_endpoint http://***.**.**.***:****     --exporter_otlp_headers Authentication=********
               python myapp.py
    • Nodejs应用接入
      • 侵入式接入
        1. 添加依赖。
          npm install --save @grpc/grpc-js @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/instrumentation-express @opentelemetry/instrumentation-http @opentelemetry/resources @opentelemetry/sdk-node @opentelemetry/sdk-trace-base @opentelemetry/semantic-conventions
        2. 对接 OpenTelemetry。

          在 express入口文件业务代码前面加上如下内容:

              const { NodeSDK } = require("@opentelemetry/sdk-node");
              const { Resource } = require("@opentelemetry/resources");
              const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-grpc");
              const { ExpressInstrumentation } = require("@opentelemetry/instrumentation-express");
              const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
              const { SemanticResourceAttributes } = require("@opentelemetry/semantic-conventions");
              const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
              const grpc = require("@grpc/grpc-js");
          
                const service_name = "应用名称.组件名称.环境名称";
                const endpoint = "http://***.**.**.***:****";
                const authentication = "****";
          
          
              const metadata = new grpc.Metadata();
              metadata.set("Authentication", authentication);
              const exporter = new OTLPTraceExporter({url: endpoint, metadata});
              const sdk = new NodeSDK({
                spanProcessor: new BatchSpanProcessor(exporter),
                resource: new Resource({
                  [SemanticResourceAttributes.HOST_NAME]: require("os").hostname(), // your host name
                  [SemanticResourceAttributes.SERVICE_NAME]: service_name,
                }),
                instrumentations: [HttpInstrumentation, ExpressInstrumentation],
              });
              sdk.start();
          
      • 非侵入式接入

        请参考官方网站

    • C++应用接入
      1. cmake 构建接入 opentelemetry 流程
      2. 环境要求。
        1. C++ 版本 ≥ 14(低版本 opentelemetry-cpp 需要≥ C++11)。
        2. 请在 Supported C++ Versions and Development Platforms 中查看支持的 C++ 版本和开发平台。
      3. 环境准备。
        1. 安装构建工具 bazel,安装步骤可以参考 bazel 安装指导
        2. 通过构建 OpenTelemetry C++ Library 检查环境已经搭建好。
          git clone https://github.com/open-telemetry/opentelemetry-cpp.git
              cd opentelemetry-cpp
              bazel build //...
      4. 在项目中使用 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;
            }
          

          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依赖。
        dotnet add package OpenTelemetry
        dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
        dotnet add package OpenTelemetry.Extensions.Hosting
      2. 对接 OpenTelemetry。

        入口文件顶部加上如下代码:

        using OpenTelemetry;
        using OpenTelemetry.Resources;
        using OpenTelemetry.Trace;
        using OpenTelemetry.Exporter;

        在入口文件处 WebApplication.CreateBuilder()之后,builder.Build()之前加入下面的内容:

        builder.Services.AddOpenTelemetry()
          .ConfigureResource(resource => resource
              .AddService(应用名称.组件名称.环境名称)
              .AddAttributes(new Dictionary<string, object> {
                  ["host.name"] = System.Net.Dns.GetHostName()
              })
          )
          .WithTracing(tracing => tracing
              .AddAspNetCoreInstrumentation()
              .AddOtlpExporter(opt => {
                  opt.Endpoint = new Uri(***.**.**.***:****);
                  opt.Headers = "Authentication=" + ******;
                  opt.Protocol = OtlpExportProtocol.Grpc;
              })
          );

        非侵入式接入可参考官方网站

相关文档