如何以三种不同的方式将OTel数据发送到Lightstep

408 阅读18分钟

在过去的几周里,我花了大量时间研究向Lightstep发送OpenTelemetry(OTel)数据的不同方法。

如果这个超级明显的标题没有提示你,有三种不同的方法可以做到。

在这篇文章中,我将详细介绍这三种方法中的每一种,并附上代码片段,解释如何将数据输入Lightstep Observability。让我们开始吧!

注意。如果你正在寻找完整的代码列表,不要惊慌!你可以在LightstepOTel示例库中看到它们。

前提条件

在我们继续之前,这里有一些你需要的东西。

如果你想运行完整的代码示例,你还需要。

OpenTelemetry和Lightstep

Lightstep Observability支持本地OpenTelemetry协议(OTLP)。它可以通过HTTPgRPC 接收 OTLP 格式的数据。你需要在你的代码中指定你希望使用的方法,我们将在接下来的代码片段中看到。

如果你对OpenTelemetry使用gRPC和HTTP感到好奇,请查看这些文档

注意:其他支持OTLP的Observability工具包括HoneycombGrafanaJaeger

如果你开始用OpenTelemetry来检测你的应用程序,这可能是大多数初学者最常采取的路线。顾名思义,我们是直接从我们的应用程序代码中向一个特定的Observability后端发送数据。

otel-to-ls-direct

要做到这一点,我们必须做以下工作:

  • 安装所需的OpenTelemetry包,并导入它们
  • 配置一个导出器
  • 配置一个TracerProvider
  • 初始化Exporter和TracerProvider,将数据发送到Lightstep。

如果你不知道这一切意味着什么,不要惊慌。我们很快就会深入研究的。

注意:你可以在这里看到通过 OTLP over gRPC 直接向 Lightstep 发送 OTel 数据的完整例子。HTTP版本可以在这里找到。

它是如何工作的

1- 安装所需的OTel库

这些是所需的库 以将数据发送到Observability后端(如Lightstep)。

go get go.opentelemetry.io/otel \
	go.opentelemetry.io/otel/exporters/otlp/otlptrace \
	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc \
	go.opentelemetry.io/otel/propagation \
	go.opentelemetry.io/otel/sdk/resource \
	go.opentelemetry.io/otel/sdk/trace \
	go.opentelemetry.io/otel/semconv/v1.10.0 \
	go.opentelemetry.io/otel/trace

在我们的应用程序代码中,我们需要导入相同的库。

import (
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
	"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.10.0"
	"go.opentelemetry.io/otel/trace"
)

如果你希望使用 HTTP 而不是 gRPC,请将otlptracegrpc 替换为otlptracehttp

2- 配置出口器

Exporter是我们向OpenTelemetry发送数据的方式。正如我前面提到的,Lightstep接受OTLP格式的数据,所以我们需要定义一个OTLP导出器。

注意:有些供应商不接受 OTLP 格式的数据,这意味着你需要使用供应商特定的导出器来发送数据给他们。

我们像这样配置我们的Exporter。

var (
   tracer         trace.Tracer
   endpoint       = "ingest.lightstep.com:443"
   lsToken        = ""
)

func newExporter(ctx context.Context) (*otlptrace.Exporter, error) {

   var headers = map[string]string{
       "lightstep-access-token": lsToken,
   }

   client := otlptracegrpc.NewClient(
       otlptracegrpc.WithHeaders(headers),
       otlptracegrpc.WithEndpoint(endpoint),
   )
   return otlptrace.New(ctx, client)
}

一些值得注意的项目。

  • endpoint 被设置为ingest.lightstep.com:443 ,它指向Lightstep的公共微卫星池。如果你使用的是内部的卫星池,那么请查看这些文档

  • 你必须用你自己的Lightstep Access Token为 ,提供一个值。

  • 我们正在通过gRPC向Lightstep发送数据。如果你希望使用HTTP而不是gRPC,你的客户端连接将看起来像这样。

    client := otlptracehttp.NewClient(
      otlptracehttp.WithHeaders(headers),
      otlptracehttp.WithEndpoint(endpoint),
      otlptracehttp.WithURLPath("traces/otlp/v0.9"),
    )
    

    请注意,我们必须添加一个额外的配置选项,WithURLPath 。这个配置选项允许我们覆盖发送跟踪的默认URL路径默认值是 /v1/traces ;但是,对于HTTP连接,Lightstep希望这个值是traces/otlp/v0.9

3- 配置TracerProvider

TracerProvider ,作为OpenTelemetry API的入口点。它提供了对Tracers的访问。一个Tracer ,负责创建一个Span来追踪给定的操作。

我们像这样配置我们的TracerProvider。

var (
   tracer         trace.Tracer
   serviceName    = "test-go-server-grpc"
   serviceVersion = "0.1.0"
   lsEnvironment  = "dev"
)

func newTraceProvider(exp *otlptrace.Exporter) *sdktrace.TracerProvider {

   resource, rErr :=
       resource.Merge(
           resource.Default(),
           resource.NewWithAttributes(
               semconv.SchemaURL,
               semconv.ServiceNameKey.String(serviceName),
               semconv.ServiceVersionKey.String(serviceVersion),
               attribute.String("environment", lsEnvironment),
           ),
       )

   if rErr != nil {
       panic(rErr)
   }

   return sdktrace.NewTracerProvider(
       sdktrace.WithBatcher(exp),
       sdktrace.WithResource(resource),
   )
}

有几个值得注意的项目。

  • 我们定义了一个资源,向OpenTelemetry提供了一堆识别我们服务的信息。这包括像serviceNameserviceVersion ,这些都是Lightstep需要设置的。顾名思义,serviceName 是你正在检测的微服务的名称。
  • sdktrace.WithBatcher 告诉OpenTelemetry使用BatchSpanProcessor。就是说,它说要分批输出数据。在这个例子中,我们不需要做任何花哨的事情。

4- 初始化Exporter和TracerProvider,向Lightstep发送数据

我们终于准备好向Lightstep发送数据了!我们通过从我们的main 函数中调用上面的newExporternewTraceProvider 函数来完成这个任务。

试试吧

让我们看看这个代码例子的实际效果。在这个例子中,我们将运行一个带有/ping 端点的服务器。该服务器将通过OTLP通过gRPC直接向Lightstep发送OTel数据。我们将使用curl 打击该端点。

1- 克隆该版本

git clone git@github.com:lightstep/opentelemetry-examples.git

2- 打开一个终端窗口并运行服务器程序

cd opentelemetry-examples/go/opentelemetry/otlp/server
export LS_ACCESS_TOKEN=
go run server.go

请确保用你自己的Lightstep访问令牌替换 。

3- 打开一个新的终端窗口并点击端点

curl http://localhost:8081/ping

从服务器输出和curl 命令中并列输出样本。

Sample output direct example

4- 在Lightstep中看到它

go-server-direct-ls

注意:想运行HTTP版本?用go run server-http.go 替换步骤2中的go run server.go

开放式遥测采集器

向Observability后端发送数据的下一个方法是通过OpenTelemetry Collector。对于非开发设置,这是推荐的将OpenTelemetry数据发送到Observability后端的方法。

otel-to-ls-via-collector

要通过采集器将仪器数据发送到 Observability 后端,我们必须做到以下几点。

  • 在某个地方运行一个 OpenTelemetry 采集器实例(在本地运行是最简单的)。
  • 安装所需的OpenTelemetry软件包,并将其导入
  • 配置一个出口器
  • 配置一个TracerProvider
  • 初始化出口商和TracerProvider

注意:你可以在这里看到完整的代码列表。

看起来和直接方法几乎一样,不是吗?差不多

我们很快就会了解到其中的差别。

如何工作

1- 安装所需的 OTel 库

这些是需要的库 以将数据发送到Observability后端(如Lightstep)。.

go get go.opentelemetry.io/otel \
	go.opentelemetry.io/otel/exporters/otlp/otlptrace \
	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc \
	go.opentelemetry.io/otel/propagation \
	go.opentelemetry.io/otel/sdk/resource \
	go.opentelemetry.io/otel/sdk/trace \
	go.opentelemetry.io/otel/semconv/v1.10.0 \
	go.opentelemetry.io/otel/trace

在我们的应用代码中,我们需要导入相同的库。

import (
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
	"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.10.0"
	"go.opentelemetry.io/otel/trace"
)

如果你希望使用 HTTP 而不是 gRPC,请将otlptracegrpc 改为otlptracehttp

2- 配置出口器

正如我们在直接例子中所看到的,我们通过OTLP导出我们的数据(见返回类型是otlptrace.Exporter )。不同的是,我们不是直接将数据导出到 Lightstep,而是将数据导出到 OTel 收集器,该收集器恰好也从我们的应用程序中摄取 OTLP 格式的 OTel 数据。

在我们的直接例子中,在我们可以创建一个新的出口器之前,我们首先需要创建一个新的跟踪客户端(otlptracegrpc.NewClient ),这样我们就可以告诉OpenTelemetry如何将数据发送到Lightstep。当我们使用采集器时,我们不需要这样做,因为采集器会在幕后为我们创建一个跟踪客户端,使用采集器配置YAML中的信息来完成。

我们像这样配置我们的输出器。

var (
   endpoint = "localhost:4317"
)

func newExporter(ctx context.Context) (*otlptrace.Exporter, error) {
	exporter, err :=
		otlptracegrpc.New(ctx,
			otlptracegrpc.WithInsecure(),
			otlptracegrpc.WithEndpoint(endpoint),
		)

	return exporter, err
}

一些值得注意的项目。

  • endpoint 是你的采集器的URL。

  • 在下面的例子中,收集器endpoint 被设置为localhost:4317 ,这意味着OpenTelemetry收集器正在本地运行,使用Docker,监听gRPC端口4317

  • 你不需要提供Lightstep访问令牌作为该配置的一部分,因为该值在OTel采集器的配置YAML文件中设置。

  • 请注意,WithInsecure 选项已被设置。如果你使用采集器,这是必须的,而且只有在采集器中没有配置证书的情况下。(这是另一篇博客文章。😜)。

  • 我们正在通过gRPC向采集器发送数据。如果你希望使用HTTP而不是gRPC,只需像这样用otlptracehttp ,就可以替换otlptracegrpc

    exporter, err :=
        otlptracehttp.New(ctx,
      	  otlptracehttp.WithInsecure(),
      	  otlptracehttp.WithEndpoint(endpoint),
    )
    

3- 配置TracerProvider

我们的TracerProvider ,与我们在直接例子中配置的相同。

var (
   tracer         trace.Tracer
   serviceName    = "test-go-server-grpc"
   serviceVersion = "0.1.0"
   lsEnvironment  = "dev"
)

func newTraceProvider(exp *otlptrace.Exporter) *sdktrace.TracerProvider {

   resource, rErr :=
       resource.Merge(
           resource.Default(),
           resource.NewWithAttributes(
               semconv.SchemaURL,
               semconv.ServiceNameKey.String(serviceName),
               semconv.ServiceVersionKey.String(serviceVersion),
               attribute.String("environment", lsEnvironment),
           ),
       )

   if rErr != nil {
       panic(rErr)
   }

   return sdktrace.NewTracerProvider(
       sdktrace.WithBatcher(exp),
       sdktrace.WithResource(resource),
   )
}

4- 初始化Exporter和TracerProvider,向Lightstep发送数据

我们终于准备好向Lightstep发送数据了!我们通过从我们的main 函数中调用上面的newExporternewTraceProvider 函数来完成这个任务。

请注意,这与我们在直接例子中看到的是一样的。只有newExporter 函数中的底层代码是不同的。

试试吧

让我们看看这个代码例子的实际效果。在这个例子中,我们将运行一个带有/ping 端点的服务器。该服务器将通过收集器,通过gRPC把OTel数据发送到Lightstep。我们将使用curl 打击该端点。

1- 克隆 repo

git clone git@github.com:lightstep/opentelemetry-examples.git

2- 运行采集器

打开一个新的终端窗口。首先,你需要编辑collector.yml文件。确保用你自己的Lightstep Access Token替换${LIGHTSTEP_ACCESS_TOKEN}

现在你可以启动收集器了。

cd opentelemetry-examples/collector/vanilla
docker run -it --rm -p 4317:4317 -p 4318:4318 \
    -v $(pwd)/collector.yaml:/otel-config.yaml \
    --name otelcol otel/opentelemetry-collector-contrib:0.53.0  \
    "/otelcol-contrib" \
    "--config=otel-config.yaml"  

注意:如果你是第一次拉动采集器图像,这可能需要一点时间。

输出样本。

collector-startup

3- 打开一个新的终端窗口,运行服务器程序

cd opentelemetry-examples/go/opentelemetry/collector/server
go run server.go

4- 打开第三个终端窗口,并点击端点

curl http://localhost:8081/ping

并列的服务器输出和curl 命令的输出样本。

sample-output-go-server-collector

你的收集器输出应该看起来像这样。

sample-collector-output

5- 在Lightstep中看到它

go-server-collector-ls

启动器

我们今天要探讨的最后一个方法是启动器。如果你浏览了OpenTelemetry的文档,没有看到任何地方提到Launcher,那是因为它们本身不是OTel的一部分。

你可以把启动器看作是OTel SDK的包装器。启动器最初是由Lightstep的一些天才工程师创建的,目的是为OpenTelemetry的设置和配置提供一种封装方式。简单地说,启动器的诞生是由于他们厌倦了重复SDK的设置代码。再一次,开发者的懒惰是胜利的标志(在此声明,我坚信开发者的懒惰是造就伟大软件的原因。我们只是讨厌重复!)启动器还增加了一层验证,让用户更好地了解所有需要的参数。关于启动器的更多信息,请查看Ted Young篇文章。

我们目前有GoPythonJavaNode.JS的启动器。

好了......现在我们明白了为什么会有Launchers,让我们来看看如何使用它们来发送OTel数据到Lightstep。

要做到这一点,我们必须做以下工作。

  • 安装所需的OpenTelemetry和Launcher软件包,并导入它们
  • 配置启动器
  • 初始化启动器

看起来与其他两个例子有点不同,不是吗?正如你所看到的,Launcher负责配置和初始化Exporter和TracerProvider。

让我们深入了解一下。

注意:你可以在这里看到使用Go Launcher通过gRPC的采集器向Lightstep发送OTel数据的完整例子。直接(通过发射器)的版本可以在这里找到。

它是如何工作的

1- 安装所需的OTel库

go get github.com/lightstep/otel-launcher-go/launcher \ 
	go.opentelemetry.io/otel \ 
	go.opentelemetry.io/otel/semconv/v1.10.0 \ 
	go.opentelemetry.io/otel/trace

在我们的应用程序代码中,我们需要导入相同的库。

import (
	"github.com/lightstep/otel-launcher-go/launcher"
	"go.opentelemetry.io/otel"
	semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
	"go.opentelemetry.io/otel/trace"
)

哼......要安装和导入的包更少了!

2- 配置启动器

在这里,我们要配置启动器,类似于我们配置Exporter和TracerProvider时的做法。除了这一切都被封装在这个可爱的launcher.ConfigureOpentelemetry !超级酷。😎

var (
	tracer         trace.Tracer
	serviceName    = "test-go-server-launcher"
	serviceVersion = "0.1.0"
	endpoint       = "ingest.lightstep.com:443"
	lsToken        = ""
)

func newLauncher() launcher.Launcher {

	otelLauncher := launcher.ConfigureOpentelemetry(
		launcher.WithServiceName(serviceName),
		launcher.WithServiceVersion(serviceVersion),
		launcher.WithAccessToken(lsToken),
		launcher.WithSpanExporterEndpoint(endpoint),
		launcher.WithMetricExporterEndpoint(endpoint),    
		launcher.WithPropagators([]string{"tracecontext", "baggage"}),
		launcher.WithResourceAttributes(map[string]string{
			string(semconv.ContainerNameKey): "my-container-name",
		}),
	)

	return otelLauncher
}

一些值得注意的项目。

  • endpoint 被设置为ingest.lightstep.com:443 ,它指向Lightstep的公共微卫星池。如果你使用的是内部的卫星池,那么请查看这些文档
  • 你必须用你自己的Lightstep Access Token为 ,提供一个值。
  • 发射器只使用gRPC。说实话,这并不是一个破绽。

呃......这一切都很好,但如果你想使用一个收集器呢?我不是说过,这是非开发人员设置的首选方法吗?是的,我当然说过!但是,如果你想使用一个收集器,那怎么办?不用担心,因为你可以使用发射器将OTel数据发送到采集器而不是直接发送到Lightstep。要做到这一点,你只需要

  • endpoint 的值改为localhost:4317

  • WithSpanExporterInsecure 设为true

  • WithMetricExporterInsecure 设为true

  • 删除WithAccessToken 设置(因为这是由OTel 收集器的配置YAML 文件处理的

    这意味着你的代码将看起来像这样。

    var (
        tracer         trace.Tracer
        serviceName    = "test-go-server-launcher"
        serviceVersion = "0.1.0"
        endpoint       = "ingest.lightstep.com:443"
    )
    
    func newLauncher() launcher.Launcher {
        otelLauncher := launcher.ConfigureOpentelemetry(
      	  launcher.WithServiceName(serviceName),
      	  launcher.WithServiceVersion(serviceVersion),
      	  launcher.WithSpanExporterInsecure(true),
      	  launcher.WithSpanExporterEndpoint(endpoint),
      	  launcher.WithMetricExporterEndpoint(endpoint),
      	  launcher.WithMetricExporterInsecure(true),
      	  launcher.WithPropagators([]string{"tracecontext", "baggage"}),
      	  launcher.WithResourceAttributes(map[string]string{
      	    string(semconv.ContainerNameKey): "my-container-name",
      	  }),
        )
    
      return otelLauncher
    }
    

3- 初始化启动器

我们需要做的就是调用我们的newLauncher 函数,然后我们就完成了!

总的来说,与其他两个sans-Launcher方法相比,Launcher方法需要更少的代码。

试试吧

让我们看看这个代码例子的实际效果。在这个例子中,我们将运行一个带有/ping 端点的服务器。该服务器将使用Go Launcher通过采集器,通过gRPC向Lightstep发送OTel数据。我们将使用curl 打击该端点。

1- 克隆 repo

git clone git@github.com:lightstep/opentelemetry-examples.git

2- 运行收集器

打开一个新的终端窗口。首先,你需要编辑collector.yml文件。确保用你自己的Lightstep Access Token替换${LIGHTSTEP_ACCESS_TOKEN}

现在你可以启动收集器了。

cd opentelemetry-examples/collector/vanilla
docker run -it --rm -p 4317:4317 -p 4318:4318 \
    -v $(pwd)/collector.yaml:/otel-config.yaml \
    --name otelcol otel/opentelemetry-collector-contrib:0.53.0  \
    "/otelcol-contrib" \
    "--config=otel-config.yaml"  

注意:如果你是第一次提取采集器图像,这可能需要一点时间。

输出样本。

collector-startup

3- 打开一个新的终端窗口,运行服务器程序

cd opentelemetry-examples/go/launcher/server
go run server.go

4- 打开第三个终端窗口,并点击端点

curl http://localhost:8081/ping

并列的服务器输出和curl 命令的输出样本。

sample-output-go-server-launcher-collector

你的收集器输出应该看起来像这样。

sample-collector-output

go-server-launcher-collector-ls

注意:想用Launcher来运行直接版本?只需跳过第2步。在步骤3中设置LS_ACCESS_TOKEN 环境变量。export LS_ACCESS_TOKEN=, 其中 是你自己的Lightstep Access Token,用go run server-otlp.go 替换go run server.go

缺点

当我在使用这三种方法时,我遇到了一些问题,所以我想在这里分享一下。

1- gRPC的调试

gRPC是我生存的祸根。特别是当我看到那条可爱的context deadline exceeded 消息时。这让我热血沸腾。幸运的是,我在Lighstep的OTel朋友告诉我有两个漂亮的小标志,使gRPC的调试更容易一些。

export GRPC_GO_LOG_VERBOSITY_LEVEL=99
export GRPC_GO_LOG_SEVERITY_LEVEL=info

设置这些漂亮的标志,你就能比较快地知道你是否不能连接到你的gRPC端点。这就是成功连接的样子。

2022/07/26 16:28:36 Using default LS endpoint ingest.lightstep.com:443
2022/07/26 16:28:36 INFO: [core] [Channel #1] Channel created
2022/07/26 16:28:36 INFO: [core] [Channel #1] original dial target is: "ingest.lightstep.com:443"
2022/07/26 16:28:36 INFO: [core] [Channel #1] parsed dial target is: {Scheme:ingest.lightstep.com Authority: Endpoint:443 URL:{Scheme:ingest.lightstep.com Opaque:443 User: Host: Path: RawPath: ForceQuery:false RawQuery: Fragment: RawFragment:}}
2022/07/26 16:28:36 INFO: [core] [Channel #1] fallback to scheme "passthrough"
2022/07/26 16:28:36 INFO: [core] [Channel #1] parsed dial target is: {Scheme:passthrough Authority: Endpoint:ingest.lightstep.com:443 URL:{Scheme:passthrough Opaque: User: Host: Path:/ingest.lightstep.com:443 RawPath: ForceQuery:false RawQuery: Fragment: RawFragment:}}
2022/07/26 16:28:36 INFO: [core] [Channel #1] Channel authority set to "ingest.lightstep.com:443"
2022/07/26 16:28:36 INFO: [core] [Channel #1] Resolver state updated: {
  "Addresses": [
    {
      "Addr": "ingest.lightstep.com:443",
      "ServerName": "",
      "Attributes": null,
      "BalancerAttributes": null,
      "Type": 0,
      "Metadata": null
    }
  ],
  "ServiceConfig": null,
  "Attributes": null
} (resolver returned new addresses)
2022/07/26 16:28:36 INFO: [core] [Channel #1] Channel switches to new LB policy "pick_first"
2022/07/26 16:28:36 INFO: [core] [Channel #1 SubChannel #2] Subchannel created
2022/07/26 16:28:36 Using default service name test-go-client-grpc
2022/07/26 16:28:36 Using default service version 0.1.0
2022/07/26 16:28:36 Using default environment dev
2022/07/26 16:28:36 INFO: [core] [Channel #1 SubChannel #2] Subchannel Connectivity change to CONNECTING
2022/07/26 16:28:36 INFO: [core] [Channel #1 SubChannel #2] Subchannel picks a new address "ingest.lightstep.com:443" to connect
2022/07/26 16:28:36 INFO: [core] pickfirstBalancer: UpdateSubConnState: 0x14000380100, {CONNECTING }
2022/07/26 16:28:36 INFO: [core] [Channel #1] Channel Connectivity change to CONNECTING
Get "http://localhost:8081/ping": dial tcp [::1]:8081: connect: connection refused
2022/07/26 16:28:37 INFO: [core] [Channel #1 SubChannel #2] Subchannel Connectivity change to READY
2022/07/26 16:28:37 INFO: [core] pickfirstBalancer: UpdateSubConnState: 0x14000380100, {READY }
2022/07/26 16:28:37 INFO: [core] [Channel #1] Channel Connectivity change to READY

2- 调试跨度(仅指启动器)

如果你使用的是Launcher,而你的Spans不知道在Lightstep中显示出来,你可以在运行你的代码之前设置OTEL_LOG_LEVEL 标志。

export OTEL_LOG_LEVEL=debug
go run .go

你的调试输出看起来像这样。

2022/07/26 15:39:10 debug logging enabled
2022/07/26 15:39:10 configuration
2022/07/26 15:39:10 {
        "SpanExporterEndpoint": "localhost:4317",
        "SpanExporterEndpointInsecure": true,
        "ServiceName": "test-go-client-launcher",
        "ServiceVersion": "0.1.0",
        "Headers": null,
        "MetricExporterEndpoint": "localhost:4317",
        "MetricExporterEndpointInsecure": true,
        "MetricExporterTemporalityPreference": "cumulative",
        "MetricsEnabled": true,
        "LogLevel": "debug",
        "Propagators": [
                "tracecontext",
                "baggage"
        ],
...
}

哪种方法是最好的?

当我在2021年第一次开始我的OTel之旅时(在我的Lightstep之前的日子),我通过OTel采集器将OTel数据发送到我的Observability后端。对我来说,这是一个没有头脑的问题,因为采集器可以。

  • 从多个来源摄取数据(包括应用程序和基础设施指标)
  • 粘贴/删除元数据
  • 屏蔽数据
  • 采样数据
  • 同时向多个后端发送数据(如果你正在评估不同的供应商或从一个供应商过渡到另一个供应商,那就太好了)。

我个人是采集器的超级粉丝,我坚持我的说法,即在Pre-Prod/Prod环境中运行OTel采集器,将你的OpenTelemetry数据发送到Observability后端,是很好的做法。

但是......我不得不承认,我更多地是从操作的角度来考虑这个问题,而不是从开发者的角度。

问题是,当你开始使用 OTel 时,你有可能是从零开始的。这意味着你已经不得不弄清楚整个仪表的问题。这已经够紧张的了。再加上试图在这一切之上建立一个采集器,你已经有了太多的活动部件和一个可能非常不堪重负的开发人员......即使你用最简单的配置来运行它(即本地,通过Docker)。还有,当你只是做本地开发时,你真的需要运行一个采集器吗?这可能比它值得的更多努力。

但是......我也从个人经验中了解到,通过直接方法连接到Observability后端是一件非常麻烦的事情。文档非常稀少。例子也不完整。不用说,这是一个非常艰难的旅程。而且我在使用HTTP和gRPC时都遇到了困难。

所以这就引出了一个问题--有什么好的、简单的方法来检测你的代码并将其发送到Observability后端?嗯,这就是Launchers发挥作用的地方!因为它们给你提供了两个方面的优点。因为它们给你提供了两个世界中最好的东西。你可以直接连接到Observability后端,也可以通过OTel Collector连接。此外,发射器并不限制你使用 Lightstep 作为你的 Observability 后端,因为。

  1. 如果你从启动器连接到一个收集器,收集器会自动给你发送多个Observability后端的能力
  2. 如果你选择直接连接到一个非Lightstep的Observability后端,它接受来自Launcher的OTLP格式的OTel数据

我必须承认,在我使用Go Launcher之前,我对它持相当怀疑的态度。毕竟,它不是vanilla OTel,这让我觉得...... "啊哦......供应商锁定了!"。这不正是OTel试图避免的吗?"

但有两件事改变了我对它的看法。首先,你没有被锁定在一个特定的供应商(见上文)。第二,我们在Honeycomb的朋友一直在努力把Launcher带到社区,就像这里所做的工作一样,所以有可能,Launcher可能是(vanilla)OTel的未来!

我的结论是:启动器胜出,因为它的灵活性和整体上比同类产品简单。

最后的思考

我们已经了解了如何以三种不同的方式将我们的OTel数据发送到Lightstep。

  • 直接从我们的应用程序发送
  • 通过OTel收集器
  • 使用启动器,它可以直接向Lightstep或通过采集器发送数据

在非开发设置中,使用收集器是将数据发送到Observability后端的首选方式;但是,如果你刚刚开始使用OTel,将OTel数据直接发送到Observability后端是最有意义的,因为你要处理的移动部件更少。

也就是说,使用vanilla OTel来完成上述任何一项工作都会有点力不从心,这就是Launchers的用武之地,因为它们抽象了一堆连接性的东西,因此使得向Observability后端发送数据更加容易,无论是直接发送还是通过采集器发送。