utils.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package trace
  2. import (
  3. "context"
  4. "net"
  5. "strings"
  6. ztrace "github.com/zeromicro/go-zero/internal/trace"
  7. "go.opentelemetry.io/otel"
  8. "go.opentelemetry.io/otel/attribute"
  9. semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
  10. "go.opentelemetry.io/otel/trace"
  11. "google.golang.org/grpc/peer"
  12. )
  13. const localhost = "127.0.0.1"
  14. var (
  15. // SpanIDFromContext returns the span id from ctx.
  16. SpanIDFromContext = ztrace.SpanIDFromContext
  17. // TraceIDFromContext returns the trace id from ctx.
  18. TraceIDFromContext = ztrace.TraceIDFromContext
  19. )
  20. // PeerFromCtx returns the peer from ctx.
  21. func PeerFromCtx(ctx context.Context) string {
  22. p, ok := peer.FromContext(ctx)
  23. if !ok || p == nil {
  24. return ""
  25. }
  26. return p.Addr.String()
  27. }
  28. // SpanInfo returns the span info.
  29. func SpanInfo(fullMethod, peerAddress string) (string, []attribute.KeyValue) {
  30. attrs := []attribute.KeyValue{RPCSystemGRPC}
  31. name, mAttrs := ParseFullMethod(fullMethod)
  32. attrs = append(attrs, mAttrs...)
  33. attrs = append(attrs, PeerAttr(peerAddress)...)
  34. return name, attrs
  35. }
  36. // ParseFullMethod returns the method name and attributes.
  37. func ParseFullMethod(fullMethod string) (string, []attribute.KeyValue) {
  38. name := strings.TrimLeft(fullMethod, "/")
  39. parts := strings.SplitN(name, "/", 2)
  40. if len(parts) != 2 {
  41. // Invalid format, does not follow `/package.service/method`.
  42. return name, []attribute.KeyValue(nil)
  43. }
  44. var attrs []attribute.KeyValue
  45. if service := parts[0]; service != "" {
  46. attrs = append(attrs, semconv.RPCServiceKey.String(service))
  47. }
  48. if method := parts[1]; method != "" {
  49. attrs = append(attrs, semconv.RPCMethodKey.String(method))
  50. }
  51. return name, attrs
  52. }
  53. // PeerAttr returns the peer attributes.
  54. func PeerAttr(addr string) []attribute.KeyValue {
  55. host, port, err := net.SplitHostPort(addr)
  56. if err != nil {
  57. return nil
  58. }
  59. if len(host) == 0 {
  60. host = localhost
  61. }
  62. return []attribute.KeyValue{
  63. semconv.NetPeerIPKey.String(host),
  64. semconv.NetPeerPortKey.String(port),
  65. }
  66. }
  67. // TracerFromContext returns a tracer in ctx, otherwise returns a global tracer.
  68. func TracerFromContext(ctx context.Context) (tracer trace.Tracer) {
  69. if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
  70. tracer = span.TracerProvider().Tracer(TraceName)
  71. } else {
  72. tracer = otel.Tracer(TraceName)
  73. }
  74. return
  75. }