package tracing import ( "git.dev.m-and-m.ovh/mderasse/gocommon/tracing/exporter/jaeger" "git.dev.m-and-m.ovh/mderasse/gocommon/tracing/exporter/zipkin" "github.com/juju/errors" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.12.0" ) // Init will try to initialize tracing by trying to retrieve config from multiple source. func Init() (*sdktrace.TracerProvider, error) { // loading configuration c, err := loadConfig() if err != nil { return nil, errors.Trace(err) } return initFromSource(c) } // InitFromCustomVaultSecret will initialize tracing with a vault secret. func InitFromCustomVaultSecret(secret string) (*sdktrace.TracerProvider, error) { c, err := loadConfigFromVault(secret) if err != nil { return nil, errors.Trace(err) } return initFromSource(c) } // InitFromCustomFile will initialize tracing with a config file. func InitFromCustomFile(path string) (*sdktrace.TracerProvider, error) { c, err := loadConfigFromFile(path) if err != nil { return nil, errors.Trace(err) } return initFromSource(c) } func initFromSource(c *ConfigStruct) (*sdktrace.TracerProvider, error) { err := c.applyEnv() if err != nil { return nil, errors.Trace(err) } return InitFromCustomConfig(c) } // InitFromCustomConfig will initialize tracing from a gaven config. func InitFromCustomConfig(c *ConfigStruct) (*sdktrace.TracerProvider, error) { err := c.IsValid() if err != nil { return nil, errors.Trace(err) } // if disabled, never sample if !c.Enabled { return sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.NeverSample()), ), nil } attributes := []attribute.KeyValue{ semconv.ServiceNameKey.String(c.ServiceName), } if c.ServiceVersion != "" { attributes = append( attributes, semconv.ServiceVersionKey.String(c.ServiceVersion), ) } if c.ServiceInstanceID != "" { attributes = append( attributes, semconv.ServiceInstanceIDKey.String(c.ServiceInstanceID), ) } for k, v := range c.Attributes { attributes = append( attributes, attribute.String(k, v), ) } // Ensure default SDK resources and the required service name are set. r, err := resource.Merge( resource.Default(), resource.NewWithAttributes( semconv.SchemaURL, attributes..., ), ) if err != nil { return nil, errors.Trace(err) } // Get the exporter var exporter sdktrace.SpanExporter switch c.Exporter { case ExporterName_JAEGER: exporter, err = jaeger.NewExporter(c.JaegerConfig) if err != nil { return nil, errors.Trace(err) } case ExporterName_ZIPKIN: exporter, err = zipkin.NewExporter(c.ZipkinConfig) if err != nil { return nil, errors.Trace(err) } default: return nil, errors.BadRequestf("Exporter is not handled.") } return sdktrace.NewTracerProvider( sdktrace.WithResource(r), sdktrace.WithBatcher(exporter), ), nil }