2023-12-11 20:18:58 +00:00
|
|
|
package tracing
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
2023-12-18 21:04:22 +00:00
|
|
|
"github.com/distribution/distribution/v3/internal/dcontext"
|
2023-12-11 20:18:58 +00:00
|
|
|
"github.com/distribution/distribution/v3/version"
|
|
|
|
"go.opentelemetry.io/contrib/exporters/autoexport"
|
|
|
|
"go.opentelemetry.io/otel"
|
2023-12-18 21:04:22 +00:00
|
|
|
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
|
2023-12-11 20:18:58 +00:00
|
|
|
"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.4.0"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// ServiceName is trace service name
|
|
|
|
serviceName = "distribution"
|
|
|
|
|
|
|
|
// DefaultSamplingRatio default sample ratio
|
|
|
|
defaultSamplingRatio = 1
|
2023-12-18 21:04:22 +00:00
|
|
|
|
|
|
|
// AttributePrefix defines a standardized prefix for custom telemetry attributes
|
|
|
|
// associated with the CNCF Distribution project.
|
|
|
|
AttributePrefix = "io.cncf.distribution."
|
2023-12-11 20:18:58 +00:00
|
|
|
)
|
|
|
|
|
2023-12-18 21:04:22 +00:00
|
|
|
// loggerWriter is a custom writer that implements the io.Writer interface.
|
|
|
|
// It is designed to redirect log messages to the Logger interface, specifically
|
|
|
|
// for use with OpenTelemetry's stdouttrace exporter.
|
|
|
|
type loggerWriter struct {
|
|
|
|
logger dcontext.Logger // Use the Logger interface
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write logs the data using the Debug level of the provided logger.
|
|
|
|
func (lw *loggerWriter) Write(p []byte) (n int, err error) {
|
|
|
|
lw.logger.Debug(string(p))
|
|
|
|
return len(p), nil
|
|
|
|
}
|
|
|
|
|
2023-12-11 20:18:58 +00:00
|
|
|
// InitOpenTelemetry initializes OpenTelemetry for the application. This function sets up the
|
|
|
|
// necessary components for collecting telemetry data, such as traces.
|
|
|
|
func InitOpenTelemetry(ctx context.Context) error {
|
|
|
|
res := resource.NewWithAttributes(
|
|
|
|
semconv.SchemaURL,
|
|
|
|
semconv.ServiceNameKey.String(serviceName),
|
2023-12-19 18:02:44 +00:00
|
|
|
semconv.ServiceVersionKey.String(version.Version()),
|
2023-12-11 20:18:58 +00:00
|
|
|
)
|
|
|
|
|
2023-12-18 21:04:22 +00:00
|
|
|
autoExp, err := autoexport.NewSpanExporter(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
lw := &loggerWriter{
|
|
|
|
logger: dcontext.GetLogger(ctx),
|
|
|
|
}
|
|
|
|
|
|
|
|
loggerExp, err := stdouttrace.New(stdouttrace.WithWriter(lw))
|
2023-12-11 20:18:58 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-12-18 21:04:22 +00:00
|
|
|
compositeExp := newCompositeExporter(autoExp, loggerExp)
|
|
|
|
|
|
|
|
sp := sdktrace.NewBatchSpanProcessor(compositeExp)
|
2023-12-11 20:18:58 +00:00
|
|
|
provider := sdktrace.NewTracerProvider(
|
|
|
|
sdktrace.WithSampler(sdktrace.TraceIDRatioBased(defaultSamplingRatio)),
|
|
|
|
sdktrace.WithResource(res),
|
|
|
|
sdktrace.WithSpanProcessor(sp),
|
|
|
|
)
|
|
|
|
otel.SetTracerProvider(provider)
|
|
|
|
|
|
|
|
pr := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
|
|
|
|
otel.SetTextMapPropagator(pr)
|
|
|
|
|
|
|
|
return nil
|
2023-12-11 20:22:38 +00:00
|
|
|
}
|