@@ -18,6 +18,8 @@ package main
18
18
import (
19
19
"bytes"
20
20
"context"
21
+ "errors"
22
+ "fmt"
21
23
"os"
22
24
"os/signal"
23
25
"runtime"
@@ -32,6 +34,7 @@ import (
32
34
33
35
"github.com/optimizely/agent/config"
34
36
"github.com/optimizely/agent/pkg/metrics"
37
+ "github.com/optimizely/agent/pkg/middleware"
35
38
"github.com/optimizely/agent/pkg/optimizely"
36
39
"github.com/optimizely/agent/pkg/routers"
37
40
"github.com/optimizely/agent/pkg/server"
@@ -44,6 +47,14 @@ import (
44
47
// Initiate the loading of the odpCache plugins
45
48
_ "github.com/optimizely/agent/plugins/odpcache/all"
46
49
"github.com/optimizely/go-sdk/pkg/logging"
50
+ "go.opentelemetry.io/otel"
51
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
52
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
53
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
54
+ "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
55
+ "go.opentelemetry.io/otel/sdk/resource"
56
+ sdktrace "go.opentelemetry.io/otel/sdk/trace"
57
+ semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
47
58
)
48
59
49
60
// Version holds the admin version
@@ -119,6 +130,97 @@ func initLogging(conf config.LogConfig) {
119
130
}
120
131
}
121
132
133
+ func getStdOutTraceProvider (conf config.OTELTracingConfig ) (* sdktrace.TracerProvider , error ) {
134
+ f , err := os .Create (conf .Services .StdOut .Filename )
135
+ if err != nil {
136
+ return nil , fmt .Errorf ("failed to create the trace file, error: %s" , err .Error ())
137
+ }
138
+
139
+ exp , err := stdouttrace .New (
140
+ stdouttrace .WithPrettyPrint (),
141
+ stdouttrace .WithWriter (f ),
142
+ )
143
+ if err != nil {
144
+ return nil , fmt .Errorf ("failed to create the collector exporter, error: %s" , err .Error ())
145
+ }
146
+
147
+ res , err := resource .New (
148
+ context .Background (),
149
+ resource .WithAttributes (
150
+ semconv .ServiceNameKey .String (conf .ServiceName ),
151
+ semconv .DeploymentEnvironmentKey .String (conf .Env ),
152
+ ),
153
+ )
154
+ if err != nil {
155
+ return nil , fmt .Errorf ("failed to create the otel resource, error: %s" , err .Error ())
156
+ }
157
+
158
+ return sdktrace .NewTracerProvider (
159
+ sdktrace .WithBatcher (exp ),
160
+ sdktrace .WithResource (res ),
161
+ sdktrace .WithIDGenerator (middleware .NewTraceIDGenerator (conf .TraceIDHeaderKey )),
162
+ ), nil
163
+ }
164
+
165
+ func getOTELTraceClient (conf config.OTELTracingConfig ) (otlptrace.Client , error ) {
166
+ switch conf .Services .Remote .Protocol {
167
+ case config .TracingRemoteProtocolHTTP :
168
+ return otlptracehttp .NewClient (
169
+ otlptracehttp .WithInsecure (),
170
+ otlptracehttp .WithEndpoint (conf .Services .Remote .Endpoint ),
171
+ ), nil
172
+ case config .TracingRemoteProtocolGRPC :
173
+ return otlptracegrpc .NewClient (
174
+ otlptracegrpc .WithInsecure (),
175
+ otlptracegrpc .WithEndpoint (conf .Services .Remote .Endpoint ),
176
+ ), nil
177
+ default :
178
+ return nil , errors .New ("unknown remote tracing protocal" )
179
+ }
180
+ }
181
+
182
+ func getRemoteTraceProvider (conf config.OTELTracingConfig ) (* sdktrace.TracerProvider , error ) {
183
+ res , err := resource .New (
184
+ context .Background (),
185
+ resource .WithAttributes (
186
+ semconv .ServiceNameKey .String (conf .ServiceName ),
187
+ semconv .DeploymentEnvironmentKey .String (conf .Env ),
188
+ ),
189
+ )
190
+ if err != nil {
191
+ return nil , fmt .Errorf ("failed to create the otel resource, error: %s" , err .Error ())
192
+ }
193
+
194
+ traceClient , err := getOTELTraceClient (conf )
195
+ if err != nil {
196
+ return nil , fmt .Errorf ("failed to create the remote trace client, error: %s" , err .Error ())
197
+ }
198
+
199
+ traceExporter , err := otlptrace .New (context .Background (), traceClient )
200
+ if err != nil {
201
+ return nil , fmt .Errorf ("failed to create the remote trace exporter, error: %s" , err .Error ())
202
+ }
203
+
204
+ bsp := sdktrace .NewBatchSpanProcessor (traceExporter )
205
+ return sdktrace .NewTracerProvider (
206
+ sdktrace .WithSampler (sdktrace .ParentBased (sdktrace .TraceIDRatioBased (conf .Services .Remote .SampleRate ))),
207
+ sdktrace .WithResource (res ),
208
+ sdktrace .WithSpanProcessor (bsp ),
209
+ sdktrace .WithIDGenerator (middleware .NewTraceIDGenerator (conf .TraceIDHeaderKey )),
210
+ ), nil
211
+ }
212
+
213
+ func initTracing (conf config.OTELTracingConfig ) (* sdktrace.TracerProvider , error ) {
214
+ switch conf .Default {
215
+ case config .TracingServiceTypeRemote :
216
+ return getRemoteTraceProvider (conf )
217
+ case config .TracingServiceTypeStdOut :
218
+ return getStdOutTraceProvider (conf )
219
+ default :
220
+ return nil , errors .New ("unknown tracing service type" )
221
+ }
222
+ }
223
+
122
224
func setRuntimeEnvironment (conf config.RuntimeConfig ) {
123
225
if conf .BlockProfileRate != 0 {
124
226
log .Warn ().Msgf ("Setting non-zero blockProfileRate is NOT recommended for production" )
@@ -140,6 +242,22 @@ func main() {
140
242
conf := loadConfig (v )
141
243
initLogging (conf .Log )
142
244
245
+ if conf .Tracing .Enabled {
246
+ tp , err := initTracing (conf .Tracing .OpenTelemetry )
247
+ if err != nil {
248
+ log .Panic ().Err (err ).Msg ("Unable to initialize tracing" )
249
+ }
250
+ defer func () {
251
+ if err := tp .Shutdown (context .Background ()); err != nil {
252
+ log .Error ().Err (err ).Msg ("Failed to shutdown tracing" )
253
+ }
254
+ }()
255
+ otel .SetTracerProvider (tp )
256
+ log .Info ().Msg (fmt .Sprintf ("Tracing enabled with service %q" , conf .Tracing .OpenTelemetry .Default ))
257
+ } else {
258
+ log .Info ().Msg ("Tracing disabled" )
259
+ }
260
+
143
261
conf .LogConfigWarnings ()
144
262
145
263
setRuntimeEnvironment (conf .Runtime )
@@ -164,7 +282,7 @@ func main() {
164
282
cancel ()
165
283
}()
166
284
167
- apiRouter := routers .NewDefaultAPIRouter (optlyCache , conf . API , agentMetricsRegistry )
285
+ apiRouter := routers .NewDefaultAPIRouter (optlyCache , * conf , agentMetricsRegistry )
168
286
adminRouter := routers .NewAdminRouter (* conf )
169
287
170
288
log .Info ().Str ("version" , conf .Version ).Msg ("Starting services." )
0 commit comments