-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodule.go
More file actions
147 lines (125 loc) · 4.05 KB
/
module.go
File metadata and controls
147 lines (125 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package observability
import (
"context"
"fmt"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"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"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
)
// InitializeObservabilityProvider initializes all observability components properly
func InitializeObservabilityProvider(ctx context.Context, logConfig *LogConfig, tracingConfig *TracingConfig, metricsConfig *MetricsConfig) (*ObservabilityProvider, func(), error) {
// Initialize logger
logger, err := NewLogger(logConfig)
if err != nil {
return nil, nil, fmt.Errorf("failed to initialize logger: %w", err)
}
// Initialize tracer
tracer, tracerShutdown, err := setupTracing(ctx, tracingConfig)
if err != nil {
return nil, nil, fmt.Errorf("failed to initialize tracer: %w", err)
}
// Initialize metrics
metrics, err := NewMetrics(ctx, *metricsConfig)
if err != nil {
tracerShutdown(ctx)
return nil, nil, fmt.Errorf("failed to initialize metrics: %w", err)
}
// Create cleanup function
cleanup := func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := metrics.Shutdown(ctx); err != nil {
logger.Error(ctx, "Error shutting down metrics", zap.Error(err))
}
if err := tracerShutdown(ctx); err != nil {
logger.Error(ctx, "Error shutting down tracer", zap.Error(err))
}
if err := logger.Sync(); err != nil {
fmt.Printf("Error syncing logger: %v\n", err)
}
}
// Create and return the provider
return &ObservabilityProvider{
Logger: logger,
Tracer: tracer,
Metrics: metrics,
serviceName: tracingConfig.ServiceName,
serviceVersion: tracingConfig.ServiceVersion,
}, cleanup, nil
}
// setupTracing initializes the OpenTelemetry tracer provider
func setupTracing(ctx context.Context, config *TracingConfig) (*Tracer, func(context.Context) error, error) {
if !config.Enabled {
// Return a no-op tracer when disabled
tracer := NewTracer(config.ServiceName)
return tracer, func(context.Context) error { return nil }, nil
}
// Create resource
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceNameKey.String(config.ServiceName),
semconv.ServiceVersionKey.String(config.ServiceVersion),
semconv.DeploymentEnvironmentKey.String(config.Environment),
),
)
if err != nil {
return nil, nil, fmt.Errorf("failed to create resource: %w", err)
}
// Create OTLP exporter
client := otlptracegrpc.NewClient(
otlptracegrpc.WithEndpoint(config.Endpoint),
otlptracegrpc.WithInsecure(),
)
exporter, err := otlptrace.New(ctx, client)
if err != nil {
return nil, nil, fmt.Errorf("failed to create OTLP exporter: %w", err)
}
// Create a sampler
var sampler sdktrace.Sampler
if config.SamplingRate >= 1.0 {
sampler = sdktrace.AlwaysSample()
} else if config.SamplingRate <= 0.0 {
sampler = sdktrace.NeverSample()
} else {
sampler = sdktrace.TraceIDRatioBased(config.SamplingRate)
}
// Create and register the trace provider
tp := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sampler),
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
)
otel.SetTracerProvider(tp)
// Set global propagator
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
))
// Create our custom tracer
tracer := NewTracer(config.ServiceName)
// Return tracer and shutdown function
return tracer, tp.Shutdown, nil
}
// GetTraceID extracts trace ID from context
func GetTraceID(ctx context.Context) string {
spanCtx := trace.SpanContextFromContext(ctx)
if spanCtx.IsValid() {
return spanCtx.TraceID().String()
}
return ""
}
// GetSpanID extracts span ID from context
func GetSpanID(ctx context.Context) string {
spanCtx := trace.SpanContextFromContext(ctx)
if spanCtx.IsValid() {
return spanCtx.SpanID().String()
}
return ""
}