70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
package telemetry
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"go.opentelemetry.io/otel"
|
||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||
"go.opentelemetry.io/otel/propagation"
|
||
"go.opentelemetry.io/otel/sdk/trace"
|
||
"time"
|
||
)
|
||
|
||
func InitTelemetry(ctx context.Context) (shutdown func(context.Context) error, err error) {
|
||
var shutdownFuncs []func(context.Context) error
|
||
|
||
// shutdown 会调用通过 shutdownFuncs 注册的清理函数。
|
||
// 调用产生的错误会被合并。
|
||
// 每个注册的清理函数将被调用一次。
|
||
shutdown = func(ctx context.Context) error {
|
||
var err error
|
||
for _, fn := range shutdownFuncs {
|
||
err = errors.Join(err, fn(ctx))
|
||
}
|
||
shutdownFuncs = nil
|
||
return err
|
||
}
|
||
|
||
// handleErr 调用 shutdown 进行清理,并确保返回所有错误信息。
|
||
handleErr := func(inErr error) {
|
||
err = errors.Join(inErr, shutdown(ctx))
|
||
}
|
||
|
||
// 设置传播器
|
||
prop := newPropagator()
|
||
otel.SetTextMapPropagator(prop)
|
||
|
||
// 设置 trace provider.
|
||
tracerProvider, err := newJaegerTraceProvider(ctx)
|
||
if err != nil {
|
||
handleErr(err)
|
||
return
|
||
}
|
||
shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown)
|
||
otel.SetTracerProvider(tracerProvider)
|
||
|
||
return
|
||
}
|
||
|
||
func newPropagator() propagation.TextMapPropagator {
|
||
return propagation.NewCompositeTextMapPropagator(
|
||
propagation.TraceContext{},
|
||
propagation.Baggage{},
|
||
)
|
||
}
|
||
|
||
func newJaegerTraceProvider(ctx context.Context) (*trace.TracerProvider, error) {
|
||
// 创建一个使用 HTTP 协议连接本机Jaeger的 Exporter
|
||
traceExporter, err := otlptracehttp.New(ctx,
|
||
otlptracehttp.WithEndpointURL("https://oltp.jerryyan.top/v1/traces"))
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
traceProvider := trace.NewTracerProvider(
|
||
trace.WithBatcher(traceExporter,
|
||
// 默认为 5s。为便于演示,设置为 1s。
|
||
trace.WithBatchTimeout(time.Second)),
|
||
)
|
||
return traceProvider, nil
|
||
}
|