NestJS 6 services use getNodeAutoInstrumentations(). Python 2 services use FastAPIInstrumentor. Go 2 services use otelgin.
74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package observability
|
||
|
||
import (
|
||
"context"
|
||
"log"
|
||
"net/url"
|
||
"time"
|
||
|
||
"go.opentelemetry.io/otel"
|
||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||
"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.26.0"
|
||
)
|
||
|
||
// InitTracer 初始化 OpenTelemetry tracer.
|
||
//
|
||
// endpoint 为 "http://host:port" 格式(如 "http://localhost:4318");
|
||
// 为空时跳过初始化(tracing disabled)。
|
||
//
|
||
// 返回 shutdown 函数,应在服务退出时调用以 flush 待发送 span.
|
||
func InitTracer(serviceName, endpoint string) func() {
|
||
if endpoint == "" {
|
||
log.Println("OTEL endpoint not set, tracing disabled")
|
||
return func() {}
|
||
}
|
||
|
||
u, err := url.Parse(endpoint)
|
||
if err != nil || u.Host == "" {
|
||
log.Printf("invalid OTEL endpoint %q, tracing disabled", endpoint)
|
||
return func() {}
|
||
}
|
||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
defer cancel()
|
||
|
||
exporter, err := otlptracehttp.New(ctx,
|
||
otlptracehttp.WithEndpoint(u.Host),
|
||
otlptracehttp.WithInsecure(),
|
||
)
|
||
if err != nil {
|
||
log.Printf("failed to create OTLP exporter: %v, tracing disabled", err)
|
||
return func() {}
|
||
}
|
||
|
||
res, err := resource.New(ctx,
|
||
resource.WithAttributes(semconv.ServiceName(serviceName)),
|
||
)
|
||
if err != nil {
|
||
log.Printf("failed to create resource: %v", err)
|
||
return func() {}
|
||
}
|
||
|
||
tp := sdktrace.NewTracerProvider(
|
||
sdktrace.WithBatcher(exporter),
|
||
sdktrace.WithResource(res),
|
||
)
|
||
otel.SetTracerProvider(tp)
|
||
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
|
||
propagation.TraceContext{},
|
||
propagation.Baggage{},
|
||
))
|
||
|
||
log.Printf("OpenTelemetry tracer initialized for %s (endpoint=%s)", serviceName, u.Host)
|
||
return func() {
|
||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
defer cancel()
|
||
if err := tp.Shutdown(shutdownCtx); err != nil {
|
||
log.Printf("failed to shutdown tracer: %v", err)
|
||
}
|
||
}
|
||
}
|