@@ -7,9 +7,18 @@ import (
77 "strconv"
88 "time"
99
10+ "go.opentelemetry.io/otel"
11+ "go.opentelemetry.io/otel/attribute"
12+ "go.opentelemetry.io/otel/propagation"
13+ "go.opentelemetry.io/otel/sdk/resource"
14+ semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
15+
1016 "firebase.google.com/go/messaging"
17+ cloudtrace "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace"
1118 "github.com/hirosassa/zerodriver"
1219 "github.com/rs/zerolog"
20+ "go.opentelemetry.io/otel/exporters/jaeger"
21+ "go.opentelemetry.io/otel/sdk/trace"
1322
1423 firebase "firebase.google.com/go"
1524 "firebase.google.com/go/auth"
@@ -51,6 +60,8 @@ func NewContainer(projectID string) (container *Container) {
5160 logger : logger (3 ).WithService (fmt .Sprintf ("%T" , container )),
5261 }
5362
63+ container .InitializeTraceProvider ("0.0.1" , os .Getenv ("GCP_PROJECT_ID" ))
64+
5465 container .RegisterMessageListeners ()
5566 container .RegisterMessageRoutes ()
5667
@@ -86,6 +97,8 @@ func (container *Container) App() (app *fiber.App) {
8697 app .Use (fiberLogger .New ())
8798 }
8899
100+ app .Use (middlewares .OtelTraceContext (container .Tracer (), container .Logger (), "X-Cloud-Trace-Context" , os .Getenv ("GCP_PROJECT_ID" )))
101+
89102 // Default config
90103 app .Use (cors .New ())
91104
@@ -564,11 +577,73 @@ func (container *Container) UserRepository() repositories.UserRepository {
564577 )
565578}
566579
580+ // InitializeTraceProvider initializes the open telemetry trace provider
581+ func (container * Container ) InitializeTraceProvider (version string , namespace string ) func () {
582+ if isLocal () {
583+ return container .initializeJaegerTraceProvider (version , namespace )
584+ }
585+ return container .initializeGoogleTraceProvider (version , namespace )
586+ }
587+
588+ func (container * Container ) initializeGoogleTraceProvider (version string , namespace string ) func () {
589+ container .logger .Debug ("initializing google trace provider" )
590+
591+ exporter , err := cloudtrace .New (cloudtrace .WithProjectID (os .Getenv ("GCP_PROJECT_ID" )))
592+ if err != nil {
593+ container .logger .Fatal (stacktrace .Propagate (err , "cannot create cloud trace exporter" ))
594+ }
595+
596+ tp := trace .NewTracerProvider (
597+ trace .WithBatcher (exporter ),
598+ trace .WithSampler (trace .AlwaysSample ()),
599+ trace .WithResource (container .InitializeOtelResources (version , namespace )),
600+ )
601+
602+ otel .SetTracerProvider (tp )
603+
604+ return func () {
605+ _ = exporter .Shutdown (context .Background ())
606+ }
607+ }
608+
609+ func (container * Container ) initializeJaegerTraceProvider (version string , namespace string ) (flush func ()) {
610+ container .logger .Debug ("initializing jaeger trace provider" )
611+ exp , err := jaeger .New (jaeger .WithCollectorEndpoint (jaeger .WithEndpoint (os .Getenv ("JAEGER_COLLECTOR_ENDPOINT" ))))
612+ if err != nil {
613+ container .logger .Error (stacktrace .Propagate (err , "could not create jaeger exporter" ))
614+ }
615+ tp := trace .NewTracerProvider (
616+ // Always be sure to batch in production.
617+ trace .WithBatcher (exp ),
618+ trace .WithSampler (trace .AlwaysSample ()),
619+ // Record information about this application in a resource.
620+ trace .WithResource (container .InitializeOtelResources (version , namespace )),
621+ )
622+
623+ otel .SetTracerProvider (tp )
624+ otel .SetTextMapPropagator (propagation .NewCompositeTextMapPropagator (propagation.TraceContext {}, propagation.Baggage {}))
625+
626+ return func () {
627+ _ = exp .Shutdown (context .Background ())
628+ }
629+ }
630+
631+ // InitializeOtelResources initializes open telemetry resources
632+ func (container * Container ) InitializeOtelResources (version string , namespace string ) * resource.Resource {
633+ return resource .NewWithAttributes (
634+ semconv .SchemaURL ,
635+ semconv .ServiceNameKey .String (namespace ),
636+ semconv .ServiceNamespaceKey .String (namespace ),
637+ semconv .ServiceVersionKey .String (version ),
638+ semconv .ServiceInstanceIDKey .String (hostName ()),
639+ attribute .String ("service.environment" , os .Getenv ("ENV" )),
640+ )
641+ }
642+
567643func logger (skipFrameCount int ) telemetry.Logger {
568- hostname , _ := os .Hostname ()
569644 fields := map [string ]string {
570645 "pid" : strconv .Itoa (os .Getpid ()),
571- "hostname" : hostname ,
646+ "hostname" : hostName () ,
572647 }
573648
574649 return telemetry .NewZerologLogger (
@@ -612,6 +687,14 @@ func jsonLogger(skipFrameCount int) *zerodriver.Logger {
612687 return & zerodriver.Logger {Logger : & zl }
613688}
614689
690+ func hostName () string {
691+ h , err := os .Hostname ()
692+ if err != nil {
693+ h = strconv .Itoa (os .Getpid ())
694+ }
695+ return h
696+ }
697+
615698func consoleLogger (skipFrameCount int ) * zerodriver.Logger {
616699 l := zerolog .New (
617700 zerolog.ConsoleWriter {
0 commit comments