utils.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package trace
  2. import (
  3. "context"
  4. "net"
  5. "strings"
  6. ztrace "github.com/wuntsong-org/go-zero-plus/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. // ParseFullMethod returns the method name and attributes.
  21. func ParseFullMethod(fullMethod string) (string, []attribute.KeyValue) {
  22. name := strings.TrimLeft(fullMethod, "/")
  23. parts := strings.SplitN(name, "/", 2)
  24. if len(parts) != 2 {
  25. // Invalid format, does not follow `/package.service/method`.
  26. return name, []attribute.KeyValue(nil)
  27. }
  28. var attrs []attribute.KeyValue
  29. if service := parts[0]; service != "" {
  30. attrs = append(attrs, semconv.RPCServiceKey.String(service))
  31. }
  32. if method := parts[1]; method != "" {
  33. attrs = append(attrs, semconv.RPCMethodKey.String(method))
  34. }
  35. return name, attrs
  36. }
  37. // PeerAttr returns the peer attributes.
  38. func PeerAttr(addr string) []attribute.KeyValue {
  39. host, port, err := net.SplitHostPort(addr)
  40. if err != nil {
  41. return nil
  42. }
  43. if len(host) == 0 {
  44. host = localhost
  45. }
  46. return []attribute.KeyValue{
  47. semconv.NetPeerIPKey.String(host),
  48. semconv.NetPeerPortKey.String(port),
  49. }
  50. }
  51. // PeerFromCtx returns the peer from ctx.
  52. func PeerFromCtx(ctx context.Context) string {
  53. p, ok := peer.FromContext(ctx)
  54. if !ok || p == nil {
  55. return ""
  56. }
  57. return p.Addr.String()
  58. }
  59. // SpanInfo returns the span info.
  60. func SpanInfo(fullMethod, peerAddress string) (string, []attribute.KeyValue) {
  61. attrs := []attribute.KeyValue{RPCSystemGRPC}
  62. name, mAttrs := ParseFullMethod(fullMethod)
  63. attrs = append(attrs, mAttrs...)
  64. attrs = append(attrs, PeerAttr(peerAddress)...)
  65. return name, attrs
  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. }