结账服务
该服务负责处理用户的结账订单。结账服务将调用许多其他服务来处理订单。
追踪
初始化追踪
OpenTelemetry SDK在main
中使用initTracerProvider
函数进行初始化。
func initTracerProvider() *sdktrace.TracerProvider {
ctx := context.Background()
exporter, err := otlptracegrpc.New(ctx)
if err != nil {
log.Fatal(err)
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(initResource()),
)
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
return tp
}
在服务关闭时,您应调用TracerProvider.Shutdown()
以确保所有跨度都被导出。该服务在主函数中使用延迟函数进行此调用。
tp := initTracerProvider()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Printf("关闭跟踪器提供程序出错:%v", err)
}
}()
添加 gRPC 自动仪表化
该服务接收 gRPC 请求,这些请求在主函数中作为 gRPC 服务器创建的一部分进行仪表化。
var srv = grpc.NewServer(
grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()),
)
该服务将发起多个出站 gRPC 调用,这些调用都通过包含仪表化的 gRPC 客户端进行仪表化。
func createClient(ctx context.Context, svcAddr string) (*grpc.ClientConn, error) {
return grpc.DialContext(ctx, svcAddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
)
}
添加Kafka(Sarama)自动仪表化
该服务将处理结果写入一个 Kafka 主题,然后由其他微服务处理。为了仪表化 Kafka 客户端,必须在创建 Producer 后对其进行封装。
saramaConfig := sarama.NewConfig()
producer, err := sarama.NewAsyncProducer(brokers, saramaConfig)
if err != nil {
return nil, err
}
producer = otelsarama.WrapAsyncProducer(saramaConfig, producer)
添加属性以进行自动仪表化的跨度
在自动仪表化的代码执行过程中,您可以从上下文中获取当前跨度。
span := trace.SpanFromContext(ctx)
使用跨度对象上的SetAttributes
方法可以为跨度添加属性。在PlaceOrder
函数中,将为跨度添加多个属性。
span.SetAttributes(
attribute.String("app.order.id", orderID.String()), shippingTrackingAttribute,
attribute.Float64("app.shipping.amount", shippingCostFloat),
attribute.Float64("app.order.amount", totalPriceFloat),
attribute.Int("app.order.items.count", len(prep.orderItems)),
)
添加跨度事件
使用跨度对象上的AddEvent
方法可以添加跨度事件。在PlaceOrder
函数中,添加了多个跨度事件。其中一些事件具有附加属性,其他事件没有。
添加没有属性的跨度事件:
span.AddEvent("prepared")
添加具有附加属性的跨度事件:
span.AddEvent("charged",
trace.WithAttributes(attribute.String("app.payment.transaction.id", txID)))
指标
初始化指标
OpenTelemetry SDK在main
中使用initMeterProvider
函数进行初始化。
func initMeterProvider() *sdkmetric.MeterProvider {
ctx := context.Background()
exporter, err := otlpmetricgrpc.New(ctx)
if err != nil {
log.Fatalf("初始化 otlp 指标 gRPC 导出器失败:%v", err)
}
mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)))
global.SetMeterProvider(mp)
return mp
}
在服务关闭时,您应调用MeterProvider.Shutdown()
以确保所有记录都被导出。该服务在主函数中使用延迟函数进行此调用。
mp := initMeterProvider()
defer func() {
if err := mp.Shutdown(context.Background()); err != nil {
log.Printf("关闭计量器提供程序出错:%v", err)
}
}()
添加 Golang 运行时自动仪表化
在主函数中对 Golang 运行时进行仪表化。
err := runtime.Start(runtime.WithMinimumReadMemStatsInterval(time.Second))
if err != nil {
log.Fatal(err)
}
日志
待定
最后修改 December 13, 2023: improve glossary translation (46f8201b)