You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.4 KiB
Go
101 lines
2.4 KiB
Go
package trace
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/zeromicro/go-zero/core/lang"
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/exporters/jaeger"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
|
|
"go.opentelemetry.io/otel/exporters/zipkin"
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
const (
|
|
kindJaeger = "jaeger"
|
|
kindZipkin = "zipkin"
|
|
kindGrpc = "grpc"
|
|
)
|
|
|
|
var (
|
|
agents = make(map[string]lang.PlaceholderType)
|
|
lock sync.Mutex
|
|
tp *sdktrace.TracerProvider
|
|
)
|
|
|
|
// StartAgent starts an opentelemetry agent.
|
|
func StartAgent(c Config) {
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
|
|
_, ok := agents[c.Endpoint]
|
|
if ok {
|
|
return
|
|
}
|
|
|
|
// if error happens, let later calls run.
|
|
if err := startAgent(c); err != nil {
|
|
return
|
|
}
|
|
|
|
agents[c.Endpoint] = lang.Placeholder
|
|
}
|
|
|
|
// StopAgent shuts down the span processors in the order they were registered.
|
|
func StopAgent() {
|
|
_ = tp.Shutdown(context.Background())
|
|
}
|
|
|
|
func createExporter(c Config) (sdktrace.SpanExporter, error) {
|
|
// Just support jaeger and zipkin now, more for later
|
|
switch c.Batcher {
|
|
case kindJaeger:
|
|
return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(c.Endpoint)))
|
|
case kindZipkin:
|
|
return zipkin.New(c.Endpoint)
|
|
case kindGrpc:
|
|
return otlptracegrpc.New(
|
|
context.Background(),
|
|
otlptracegrpc.WithInsecure(),
|
|
otlptracegrpc.WithEndpoint(c.Endpoint),
|
|
otlptracegrpc.WithDialOption(grpc.WithBlock()),
|
|
)
|
|
default:
|
|
return nil, fmt.Errorf("unknown exporter: %s", c.Batcher)
|
|
}
|
|
}
|
|
|
|
func startAgent(c Config) error {
|
|
opts := []sdktrace.TracerProviderOption{
|
|
// Set the sampling rate based on the parent span to 100%
|
|
sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(c.Sampler))),
|
|
// Record information about this application in a Resource.
|
|
sdktrace.WithResource(resource.NewSchemaless(semconv.ServiceNameKey.String(c.Name))),
|
|
}
|
|
|
|
if len(c.Endpoint) > 0 {
|
|
exp, err := createExporter(c)
|
|
if err != nil {
|
|
logx.Error(err)
|
|
return err
|
|
}
|
|
|
|
// Always be sure to batch in production.
|
|
opts = append(opts, sdktrace.WithBatcher(exp))
|
|
}
|
|
|
|
tp = sdktrace.NewTracerProvider(opts...)
|
|
otel.SetTracerProvider(tp)
|
|
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) {
|
|
logx.Errorf("[otel] error: %v", err)
|
|
}))
|
|
|
|
return nil
|
|
}
|