lotus/lib/tracing/setup.go
hannahhoward f3b691d618 feat(tracing): switch to OpenTelemetry
Switch the underlying tracing library to OpenTelemetry, with a bridge to OpenCensus for
compatibility
2021-12-01 16:19:47 -08:00

91 lines
2.8 KiB
Go

package tracing
import (
"os"
"strings"
octrace "go.opencensus.io/trace"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/bridge/opencensus"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
logging "github.com/ipfs/go-log/v2"
)
var log = logging.Logger("tracing")
const (
// environment variable names
envCollectorEndpoint = "LOTUS_JAEGER_COLLECTOR_ENDPOINT"
envAgentHost = "LOTUS_JAEGER_AGENT_HOST"
envAgentPort = "LOTUS_JAEGER_AGENT_PORT"
envJaegerUser = "LOTUS_JAEGER_USERNAME"
envJaegerCred = "LOTUS_JAEGER_PASSWORD"
)
// When sending directly to the collector, agent options are ignored.
// The collector endpoint is an HTTP or HTTPs URL.
// The agent endpoint is a thrift/udp protocol and should be given
// as a string like "hostname:port". The agent can also be configured
// with separate host and port variables.
func jaegerOptsFromEnv() jaeger.EndpointOption {
var e string
var ok bool
if e, ok = os.LookupEnv(envCollectorEndpoint); ok {
options := []jaeger.CollectorEndpointOption{jaeger.WithEndpoint(e)}
if u, ok := os.LookupEnv(envJaegerUser); ok {
if p, ok := os.LookupEnv(envJaegerCred); ok {
options = append(options, jaeger.WithUsername(u))
options = append(options, jaeger.WithPassword(p))
} else {
log.Warn("jaeger username supplied with no password. authentication will not be used.")
}
}
log.Infof("jaeger tracess will send to collector %s", e)
return jaeger.WithCollectorEndpoint(options...)
}
if e, ok = os.LookupEnv(envAgentHost); ok {
options := []jaeger.AgentEndpointOption{jaeger.WithAgentHost(e)}
var ep string
if p, ok := os.LookupEnv(envAgentPort); ok {
options = append(options, jaeger.WithAgentPort(p))
ep = strings.Join([]string{e, p}, ":")
} else {
ep = strings.Join([]string{e, "6831"}, ":")
}
log.Infof("jaeger traces will be sent to agent %s", ep)
return jaeger.WithAgentEndpoint(options...)
}
return nil
}
func SetupJaegerTracing(serviceName string) *tracesdk.TracerProvider {
jaegerEndpoint := jaegerOptsFromEnv()
if jaegerEndpoint == nil {
return nil
}
je, err := jaeger.New(jaegerEndpoint)
if err != nil {
log.Errorw("failed to create the jaeger exporter", "error", err)
return nil
}
tp := tracesdk.NewTracerProvider(
// Always be sure to batch in production.
tracesdk.WithBatcher(je),
// Record information about this application in an Resource.
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName),
)),
)
otel.SetTracerProvider(tp)
tracer := tp.Tracer(serviceName)
octrace.DefaultTracer = opencensus.NewTracer(tracer)
return tp
}