agent.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package trace
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "github.com/zeromicro/go-zero/core/lang"
  7. "github.com/zeromicro/go-zero/core/logx"
  8. "go.opentelemetry.io/otel"
  9. "go.opentelemetry.io/otel/exporters/jaeger"
  10. "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
  11. "go.opentelemetry.io/otel/exporters/zipkin"
  12. "go.opentelemetry.io/otel/sdk/resource"
  13. sdktrace "go.opentelemetry.io/otel/sdk/trace"
  14. semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
  15. "google.golang.org/grpc"
  16. )
  17. const (
  18. kindJaeger = "jaeger"
  19. kindZipkin = "zipkin"
  20. kindGrpc = "grpc"
  21. )
  22. var (
  23. agents = make(map[string]lang.PlaceholderType)
  24. lock sync.Mutex
  25. tp *sdktrace.TracerProvider
  26. )
  27. // StartAgent starts an opentelemetry agent.
  28. func StartAgent(c Config) {
  29. lock.Lock()
  30. defer lock.Unlock()
  31. _, ok := agents[c.Endpoint]
  32. if ok {
  33. return
  34. }
  35. // if error happens, let later calls run.
  36. if err := startAgent(c); err != nil {
  37. return
  38. }
  39. agents[c.Endpoint] = lang.Placeholder
  40. }
  41. // StopAgent shuts down the span processors in the order they were registered.
  42. func StopAgent() {
  43. _ = tp.Shutdown(context.Background())
  44. }
  45. func createExporter(c Config) (sdktrace.SpanExporter, error) {
  46. // Just support jaeger and zipkin now, more for later
  47. switch c.Batcher {
  48. case kindJaeger:
  49. return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(c.Endpoint)))
  50. case kindZipkin:
  51. return zipkin.New(c.Endpoint)
  52. case kindGrpc:
  53. return otlptracegrpc.New(
  54. context.Background(),
  55. otlptracegrpc.WithInsecure(),
  56. otlptracegrpc.WithEndpoint(c.Endpoint),
  57. otlptracegrpc.WithDialOption(grpc.WithBlock()),
  58. )
  59. default:
  60. return nil, fmt.Errorf("unknown exporter: %s", c.Batcher)
  61. }
  62. }
  63. func startAgent(c Config) error {
  64. opts := []sdktrace.TracerProviderOption{
  65. // Set the sampling rate based on the parent span to 100%
  66. sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(c.Sampler))),
  67. // Record information about this application in a Resource.
  68. sdktrace.WithResource(resource.NewSchemaless(semconv.ServiceNameKey.String(c.Name))),
  69. }
  70. if len(c.Endpoint) > 0 {
  71. exp, err := createExporter(c)
  72. if err != nil {
  73. logx.Error(err)
  74. return err
  75. }
  76. // Always be sure to batch in production.
  77. opts = append(opts, sdktrace.WithBatcher(exp))
  78. }
  79. tp = sdktrace.NewTracerProvider(opts...)
  80. otel.SetTracerProvider(tp)
  81. otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) {
  82. logx.Errorf("[otel] error: %v", err)
  83. }))
  84. return nil
  85. }