1
+ //go:build ignore
2
+
1
3
// Copyright (c) 2024 Alibaba Group Holding Ltd.
2
4
//
3
5
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,14 +28,14 @@ import (
26
28
"log"
27
29
http2 "net/http"
28
30
"os"
31
+ "runtime"
29
32
"strings"
30
33
31
34
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/core/meter"
32
35
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api-semconv/instrumenter/http"
33
36
"github.com/alibaba/opentelemetry-go-auto-instrumentation/test/verifier"
34
- "go.opentelemetry.io/contrib/instrumentation/runtime"
37
+ otelruntime "go.opentelemetry.io/contrib/instrumentation/runtime"
35
38
"go.opentelemetry.io/otel"
36
- _ "go.opentelemetry.io/otel"
37
39
_ "go.opentelemetry.io/otel/baggage"
38
40
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
39
41
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
@@ -43,7 +45,6 @@ import (
43
45
"go.opentelemetry.io/otel/propagation"
44
46
"go.opentelemetry.io/otel/sdk/metric"
45
47
"go.opentelemetry.io/otel/sdk/trace"
46
- _ "go.opentelemetry.io/otel/sdk/trace"
47
48
)
48
49
49
50
// set the following environment variables based on https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables
@@ -57,7 +58,19 @@ const metrics_exporter = "OTEL_METRICS_EXPORTER"
57
58
const prometheus_exporter_port = "OTEL_EXPORTER_PROMETHEUS_PORT"
58
59
const default_prometheus_exporter_port = "9464"
59
60
61
+ var (
62
+ spanExporter trace.SpanExporter
63
+ traceProvider * trace.TracerProvider
64
+ metricsProvider * metric.MeterProvider
65
+ batchSpanProcessor trace.SpanProcessor
66
+ )
67
+
60
68
func init () {
69
+ ctx := context .Background ()
70
+ // graceful shutdown
71
+ runtime .ExitHook = func () {
72
+ gracefullyShutdown (ctx )
73
+ }
61
74
path , err := os .Executable ()
62
75
if err != nil {
63
76
panic (err )
@@ -66,7 +79,7 @@ func init() {
66
79
if strings .HasSuffix (path , exec_name ) {
67
80
return
68
81
}
69
- if err = initOpenTelemetry (); err != nil {
82
+ if err = initOpenTelemetry (ctx ); err != nil {
70
83
log .Fatalf ("%s: %v" , "Failed to initialize opentelemetry resource" , err )
71
84
}
72
85
}
@@ -78,32 +91,27 @@ func newSpanProcessor(ctx context.Context) trace.SpanProcessor {
78
91
simpleProcessor := trace .NewSimpleSpanProcessor (traceExporter )
79
92
return simpleProcessor
80
93
} else {
81
- var traceExporter trace.SpanExporter
82
94
var err error
83
95
if os .Getenv (report_protocol ) == "grpc" || os .Getenv (trace_report_protocol ) == "grpc" {
84
- traceExporter , err = otlptrace .New (ctx , otlptracegrpc .NewClient ())
96
+ spanExporter , err = otlptrace .New (ctx , otlptracegrpc .NewClient ())
85
97
if err != nil {
86
98
log .Fatalf ("%s: %v" , "Failed to create the OpenTelemetry trace exporter" , err )
87
99
}
88
100
} else {
89
- traceExporter , err = otlptrace .New (ctx , otlptracehttp .NewClient ())
101
+ spanExporter , err = otlptrace .New (ctx , otlptracehttp .NewClient ())
90
102
if err != nil {
91
103
log .Fatalf ("%s: %v" , "Failed to create the OpenTelemetry trace exporter" , err )
92
104
}
93
105
}
94
- batchSpanProcessor : = trace .NewBatchSpanProcessor (traceExporter )
106
+ batchSpanProcessor = trace .NewBatchSpanProcessor (spanExporter )
95
107
return batchSpanProcessor
96
108
}
97
109
}
98
110
99
- func initOpenTelemetry () error {
100
- ctx := context .Background ()
101
-
102
- var batchSpanProcessor trace.SpanProcessor
111
+ func initOpenTelemetry (ctx context.Context ) error {
103
112
104
113
batchSpanProcessor = newSpanProcessor (ctx )
105
114
106
- var traceProvider * trace.TracerProvider
107
115
if batchSpanProcessor != nil {
108
116
traceProvider = trace .NewTracerProvider (
109
117
trace .WithSpanProcessor (batchSpanProcessor ))
@@ -118,10 +126,9 @@ func initOpenTelemetry() error {
118
126
119
127
func initMetrics () error {
120
128
ctx := context .Background ()
121
- var mp * metric.MeterProvider
122
129
// TODO: abstract the if-else
123
130
if verifier .IsInTest () {
124
- mp = metric .NewMeterProvider (
131
+ metricsProvider = metric .NewMeterProvider (
125
132
metric .WithReader (verifier .ManualReader ),
126
133
)
127
134
} else {
@@ -130,7 +137,7 @@ func initMetrics() error {
130
137
if err != nil {
131
138
log .Fatalf ("new otlp metric prometheus exporter failed: %v" , err )
132
139
}
133
- mp = metric .NewMeterProvider (
140
+ metricsProvider = metric .NewMeterProvider (
134
141
metric .WithReader (exporter ),
135
142
)
136
143
go serveMetrics ()
@@ -139,24 +146,24 @@ func initMetrics() error {
139
146
if err != nil {
140
147
log .Fatalf ("new otlp metric grpc exporter failed: %v" , err )
141
148
}
142
- mp = metric .NewMeterProvider (
149
+ metricsProvider = metric .NewMeterProvider (
143
150
metric .WithReader (metric .NewPeriodicReader (exporter )),
144
151
)
145
152
} else {
146
153
exporter , err := otlpmetrichttp .New (ctx )
147
154
if err != nil {
148
155
log .Fatalf ("new otlp metric http exporter failed: %v" , err )
149
156
}
150
- mp = metric .NewMeterProvider (
157
+ metricsProvider = metric .NewMeterProvider (
151
158
metric .WithReader (metric .NewPeriodicReader (exporter )),
152
159
)
153
160
}
154
161
}
155
- if mp == nil {
162
+ if metricsProvider == nil {
156
163
return errors .New ("No MeterProvider is provided" )
157
164
}
158
- otel .SetMeterProvider (mp )
159
- m := mp .Meter ("opentelemetry-global-meter" )
165
+ otel .SetMeterProvider (metricsProvider )
166
+ m := metricsProvider .Meter ("opentelemetry-global-meter" )
160
167
meter .SetMeter (m )
161
168
// init http metrics
162
169
http .InitHttpMetrics (m )
@@ -167,7 +174,7 @@ func initMetrics() error {
167
174
// nacos experimental metrics
168
175
experimental .InitNacosExperimentalMetrics (m )
169
176
// DefaultMinimumReadMemStatsInterval is 15 second
170
- return runtime .Start (runtime .WithMeterProvider (mp ))
177
+ return otelruntime .Start (otelruntime .WithMeterProvider (metricsProvider ))
171
178
}
172
179
173
180
func serveMetrics () {
@@ -183,3 +190,26 @@ func serveMetrics() {
183
190
return
184
191
}
185
192
}
193
+
194
+ func gracefullyShutdown (ctx context.Context ) {
195
+ if metricsProvider != nil {
196
+ if err := metricsProvider .Shutdown (ctx ); err != nil {
197
+ log .Printf ("%s: %v" , "Failed to shutdown the OpenTelemetry metric provider" , err )
198
+ }
199
+ }
200
+ if traceProvider != nil {
201
+ if err := traceProvider .Shutdown (ctx ); err != nil {
202
+ log .Printf ("%s: %v" , "Failed to shutdown the OpenTelemetry trace provider" , err )
203
+ }
204
+ }
205
+ if spanExporter != nil {
206
+ if err := spanExporter .Shutdown (ctx ); err != nil {
207
+ log .Printf ("%s: %v" , "Failed to shutdown the OpenTelemetry span exporter" , err )
208
+ }
209
+ }
210
+ if batchSpanProcessor != nil {
211
+ if err := batchSpanProcessor .Shutdown (ctx ); err != nil {
212
+ log .Printf ("%s: %v" , "Failed to shutdown the OpenTelemetry batch span processor" , err )
213
+ }
214
+ }
215
+ }
0 commit comments