@@ -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"
@@ -42,6 +45,14 @@ import (
42
45
// Initiate the loading of the userprofileservice plugins
43
46
_ "github.com/optimizely/agent/plugins/userprofileservice/all"
44
47
"github.com/optimizely/go-sdk/pkg/logging"
48
+ "go.opentelemetry.io/otel"
49
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
50
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
51
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
52
+ "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
53
+ "go.opentelemetry.io/otel/sdk/resource"
54
+ sdktrace "go.opentelemetry.io/otel/sdk/trace"
55
+ semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
45
56
)
46
57
47
58
// Version holds the admin version
@@ -112,6 +123,97 @@ func initLogging(conf config.LogConfig) {
112
123
}
113
124
}
114
125
126
+ func getStdOutTraceProvider (conf config.OTELTracingConfig ) (* sdktrace.TracerProvider , error ) {
127
+ f , err := os .Create (conf .Services .StdOut .Filename )
128
+ if err != nil {
129
+ return nil , fmt .Errorf ("failed to create the trace file, error: %s" , err .Error ())
130
+ }
131
+
132
+ exp , err := stdouttrace .New (
133
+ stdouttrace .WithPrettyPrint (),
134
+ stdouttrace .WithWriter (f ),
135
+ )
136
+ if err != nil {
137
+ return nil , fmt .Errorf ("failed to create the collector exporter, error: %s" , err .Error ())
138
+ }
139
+
140
+ res , err := resource .New (
141
+ context .Background (),
142
+ resource .WithAttributes (
143
+ semconv .ServiceNameKey .String (conf .ServiceName ),
144
+ semconv .DeploymentEnvironmentKey .String (conf .Env ),
145
+ ),
146
+ )
147
+ if err != nil {
148
+ return nil , fmt .Errorf ("failed to create the otel resource, error: %s" , err .Error ())
149
+ }
150
+
151
+ return sdktrace .NewTracerProvider (
152
+ sdktrace .WithBatcher (exp ),
153
+ sdktrace .WithResource (res ),
154
+ sdktrace .WithIDGenerator (middleware .NewTraceIDGenerator (conf .TraceIDHeaderKey )),
155
+ ), nil
156
+ }
157
+
158
+ func getOTELTraceClient (conf config.OTELTracingConfig ) (otlptrace.Client , error ) {
159
+ switch conf .Services .Remote .Protocol {
160
+ case config .TracingRemoteProtocolHTTP :
161
+ return otlptracehttp .NewClient (
162
+ otlptracehttp .WithInsecure (),
163
+ otlptracehttp .WithEndpoint (conf .Services .Remote .Endpoint ),
164
+ ), nil
165
+ case config .TracingRemoteProtocolGRPC :
166
+ return otlptracegrpc .NewClient (
167
+ otlptracegrpc .WithInsecure (),
168
+ otlptracegrpc .WithEndpoint (conf .Services .Remote .Endpoint ),
169
+ ), nil
170
+ default :
171
+ return nil , errors .New ("unknown remote tracing protocal" )
172
+ }
173
+ }
174
+
175
+ func getRemoteTraceProvider (conf config.OTELTracingConfig ) (* sdktrace.TracerProvider , error ) {
176
+ res , err := resource .New (
177
+ context .Background (),
178
+ resource .WithAttributes (
179
+ semconv .ServiceNameKey .String (conf .ServiceName ),
180
+ semconv .DeploymentEnvironmentKey .String (conf .Env ),
181
+ ),
182
+ )
183
+ if err != nil {
184
+ return nil , fmt .Errorf ("failed to create the otel resource, error: %s" , err .Error ())
185
+ }
186
+
187
+ traceClient , err := getOTELTraceClient (conf )
188
+ if err != nil {
189
+ return nil , fmt .Errorf ("failed to create the remote trace client, error: %s" , err .Error ())
190
+ }
191
+
192
+ traceExporter , err := otlptrace .New (context .Background (), traceClient )
193
+ if err != nil {
194
+ return nil , fmt .Errorf ("failed to create the remote trace exporter, error: %s" , err .Error ())
195
+ }
196
+
197
+ bsp := sdktrace .NewBatchSpanProcessor (traceExporter )
198
+ return sdktrace .NewTracerProvider (
199
+ sdktrace .WithSampler (sdktrace .ParentBased (sdktrace .TraceIDRatioBased (conf .Services .Remote .SampleRate ))),
200
+ sdktrace .WithResource (res ),
201
+ sdktrace .WithSpanProcessor (bsp ),
202
+ sdktrace .WithIDGenerator (middleware .NewTraceIDGenerator (conf .TraceIDHeaderKey )),
203
+ ), nil
204
+ }
205
+
206
+ func initTracing (conf config.OTELTracingConfig ) (* sdktrace.TracerProvider , error ) {
207
+ switch conf .Default {
208
+ case config .TracingServiceTypeRemote :
209
+ return getRemoteTraceProvider (conf )
210
+ case config .TracingServiceTypeStdOut :
211
+ return getStdOutTraceProvider (conf )
212
+ default :
213
+ return nil , errors .New ("unknown tracing service type" )
214
+ }
215
+ }
216
+
115
217
func setRuntimeEnvironment (conf config.RuntimeConfig ) {
116
218
if conf .BlockProfileRate != 0 {
117
219
log .Warn ().Msgf ("Setting non-zero blockProfileRate is NOT recommended for production" )
@@ -133,6 +235,22 @@ func main() {
133
235
conf := loadConfig (v )
134
236
initLogging (conf .Log )
135
237
238
+ if conf .Tracing .Enabled {
239
+ tp , err := initTracing (conf .Tracing .OpenTelemetry )
240
+ if err != nil {
241
+ log .Panic ().Err (err ).Msg ("Unable to initialize tracing" )
242
+ }
243
+ defer func () {
244
+ if err := tp .Shutdown (context .Background ()); err != nil {
245
+ log .Error ().Err (err ).Msg ("Failed to shutdown tracing" )
246
+ }
247
+ }()
248
+ otel .SetTracerProvider (tp )
249
+ log .Info ().Msg (fmt .Sprintf ("Tracing enabled with service %q" , conf .Tracing .OpenTelemetry .Default ))
250
+ } else {
251
+ log .Info ().Msg ("Tracing disabled" )
252
+ }
253
+
136
254
conf .LogConfigWarnings ()
137
255
138
256
setRuntimeEnvironment (conf .Runtime )
@@ -157,7 +275,7 @@ func main() {
157
275
cancel ()
158
276
}()
159
277
160
- apiRouter := routers .NewDefaultAPIRouter (optlyCache , conf . API , agentMetricsRegistry )
278
+ apiRouter := routers .NewDefaultAPIRouter (optlyCache , * conf , agentMetricsRegistry )
161
279
adminRouter := routers .NewAdminRouter (* conf )
162
280
163
281
log .Info ().Str ("version" , conf .Version ).Msg ("Starting services." )
0 commit comments