怎么在网上卖东西视频,淄博seo方案,做网站应该用多少分辨率,有限公司怎么注册上一个博文中#xff0c;我提到如何使用 OpenTelemery 的特定语言 API 来收集遥测数据#xff0c;包含手动和自动的埋点技术#xff0c;这很重要#xff01;但是#xff0c;收集遥测数据只是解决方案的第一步。
你需要把遥测数据路由转发到其他地方#xff0c;同时添加额…上一个博文中我提到如何使用 OpenTelemery 的特定语言 API 来收集遥测数据包含手动和自动的埋点技术这很重要但是收集遥测数据只是解决方案的第一步。
你需要把遥测数据路由转发到其他地方同时添加额外的元数据信息。这时就轮到 SDK 发挥作用了。
链路追踪生产者 Tracer Provider
链路追踪生产者是 SDK 中一个关键概念。用于将通过 API 收集的遥测数据与其他组件联系起来。在 Go 语言中TracerProvider 对象只有一个 Tracer 方法的接口方法签名如下
Tracer(instrumentationName string, opts ...TracerOption) TracerTracer 方法返回一个实现 Tracer 接口的对象这个接口也只有一个方法 Start,其方法签名如下
Start(ctx context.Context, spanName string, opts ...spanStartOption) (context.Context, Span)样例项目中通过链路追踪生产者创建了跨度( span ):
import go.opentelemetry.io/otel// ...ctx, span : otel.Tracer(telemetry.TelemetryLibrary).Start(ctx, get_product_price)可以发现通过otel.Tracer 查找并创建全局的链路追踪生产者最终返回 Tracer 对象需要注意要使用链路追踪生产者其初始化设置是不可缺少的。
Note: 在文中提及是获取‘全局’链路追踪生产者的方法。使用全局链路追踪最简单的一种方式就是调用 otel.Tracer 的 API 。不过实际使用中如果上面方案不满足还可以通过链路追踪生产者传递给消费者以替代全局查找的方法。
Note trace 代表整个请求的路径信息、span 代表链路中的具体节点信息
资源 Resource
链路追踪生产者还需要配置‘资源’对象它是元数据信息的一部分。资源是遥测数据产生描述过程或者服务的信息描述了服务本身的元数据有助于解析遥测数据。
这是样例项目中购物车服务的‘资源’对象定义
import (go.opentelemetry.io/otel/sdk/resourcesemconv go.opentelemetry.io/otel/semconv/v1.4.0
)// ...res, err : resource.New(ctx,resource.WithAttributes(semconv.ServiceNameKey.String(cart),semconv.ServiceVersionKey.String(v1.0.0),),
)资源对象定义的关键是设置属性参数OpenTelemetry 已经定义了一些资源属性的键值对可以参考这篇文档 OTel’s 资源语义约定。 例如你可以通过上面例子看到如何定义服务名称和版本号信息。但是可能还有更多信息你需要配置比如服务自身依赖的资源有哪些服务运行在云上吗需要约定不同的属性给不同的云服务供应商服务运行在 Kubernetes 吗是的话这里有份指导手册 Kubernetes 的资源语义约定。
最终样例项目中, 链路追踪数据中 span 都包含这样的‘资源’数据:
Resource labels:- service.name: STRING(cart)- service.version: STRING(v1.0.0)导出器 Exporter
既然我们已经创建了资源对象我们接下来定义一下遥测数据的目的地。
导出器的选择范围很广可以根据自己的需求选择不同的导出器不过在当前项目例子中我使用 OpenTelemetry 控制器会在下一篇细聊它支持 HTTP 和 gRPC 协议。我选择使用 gRPC 协议和 OTLP 导出器
import (go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpcgoogle.golang.org/grpc
)// ...hostIP : os.Getenv(HOST_IP)
if hostIP {return nil, fmt.Errorf(unexpected no host IP address for receiver)
}
receiverAddress : fmt.Sprintf(%s:%d, hostIP, 4317)conn, err : grpc.DialContext(ctx,receiverAddress,grpc.WithTransportCredentials(insecure.NewCredentials()),grpc.WithBlock(),
)
if err ! nil {return nil, fmt.Errorf(error creating client connection to collector: %w, err)
}otlpTraceExporter, err : otlptracegrpc.New(ctx,otlptracegrpc.WithGRPCConn(conn),
)Note: 文中例子是演示的程序使用的非安全的连接方式来获取数据,不过生产环境中你最起码应该要使用带鉴权的连接方式。
就导出器而言有多种方式输出结果渠道供你选择例如控制台输出输出到 stdout , Jaeger (直接发送数据给它), Prometheus 等。使用 OTLP 导出器并将数据发送到 OTel Collector 的好处是您可以创建数据副本、并行处理数据并拥有更多控制权将在下一篇文章中介绍。
由于使用 OTLP 导出器非常灵活我们可以根据需要在 Collector 中使用遥测数据输出到 stdout、发送到 Jaeger 等。下一篇文章将详细介绍这一点
整合 Tying it all together
现在我们有了资源生成遥测数据和导出器遥测数据的目的地我们将它们放在一起形成链路追踪生产者
tp : trace.NewTracerProvider(trace.WithSampler(trace.AlwaysSample()),trace.WithResource(res),trace.WithSpanProcessor(trace.NewBatchSpanProcessor(otlpTraceExporter)),
)当链路追踪生产者创建后我们需要将其设置为全局链路追踪生产者:
import (go.opentelemetry.io/otel
)// ...otel.SetTracerProvider(tp)接下来我们需要设置‘传播’。在后续博文中将深入讨论传播和附加数据 baggage 整个链路中传递业务自定义 KV 属性但现在只需要知道‘传播’可以将 OTel 链路追踪的上下文信息跨多个服务进行传递。让‘分布式’概念在‘分布式链路追踪’中实现。
import (go.opentelemetry.io/otel/propagation
)// ...otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{},propagation.Baggage{}),
)最后我们需要调用 TracerProvider.Shutdown 来清理并关闭跨度处理器在例子中我们使用批量 span 处理器按批次将 span 数据进行聚合和批量处理然后将完整的批处理结果发送给导出器
defer func() {if err : tp.Shutdown(context.Background()); err ! nil {fmt.Printf(Error shutting down tracer provider: %v, err)os.Exit(1)}
}()Note: 为了可靠性和可读性仅通过调用 defer tp.Shutdown(context.Background()) 是不够的需要处理函数返回的一些错误。
链路追踪生产者 Python 版 Python tracer provider
样例项目中大部分服务都用 Go 语言来编写用 Python 写了一个服务定价服务。为了完整起见以下是如何在 Python 中创建和设置类似的链路追踪生产者的例子
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource, SERVICE_NAME, SERVICE_VERSION
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessorresource Resource(attributes{SERVICE_NAME: price,SERVICE_VERSION: v1.0.0
})
tracer_provider TracerProvider(resourceresource)host_ip os.environ.get(HOST_IP)
if host_ip is None:print(Must pass in environment var HOST_IP)sys.exit(1)tracer_provider.add_span_processor(span_processorBatchSpanProcessor(OTLPSpanExporter(endpointf{host_ip}:4317, insecureTrue)
))
trace.set_tracer_provider(tracer_provider)其中资源、span 处理器和设置全局链路追踪生产者的实现与 Go 描述相同。
总结
很棒前进了一步按照上面步骤实现了通过 API 获取了遥测数据并将其从当前组件中被发送到一个导出器并向其中添加了一些元数据资源接下来我们将了解如何使用 OpenTelemetry 收集器来处理这来数据。
本文翻译自Observability with OpenTelemetry Part 3 - SDK and Exporting | Thomas Stringer
扩展阅读
方法论面向故障处理的可观测性体系建设白皮书事件 OnCall 中心建设方法好工具FlashDuty - 一站式告警处理平台告警降噪、排班OnCall