agent.go 2.1 KB

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