utils.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package opentelemetry
  2. import (
  3. "context"
  4. "net"
  5. "strings"
  6. "go.opentelemetry.io/otel/attribute"
  7. semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
  8. "google.golang.org/grpc/peer"
  9. )
  10. // PeerFromCtx returns the peer from ctx.
  11. func PeerFromCtx(ctx context.Context) string {
  12. p, ok := peer.FromContext(ctx)
  13. if !ok {
  14. return ""
  15. }
  16. return p.Addr.String()
  17. }
  18. // SpanInfo returns the span info.
  19. func SpanInfo(fullMethod, peerAddress string) (string, []attribute.KeyValue) {
  20. attrs := []attribute.KeyValue{RPCSystemGRPC}
  21. name, mAttrs := ParseFullMethod(fullMethod)
  22. attrs = append(attrs, mAttrs...)
  23. attrs = append(attrs, PeerAttr(peerAddress)...)
  24. return name, attrs
  25. }
  26. // ParseFullMethod returns the method name and attributes.
  27. func ParseFullMethod(fullMethod string) (string, []attribute.KeyValue) {
  28. name := strings.TrimLeft(fullMethod, "/")
  29. parts := strings.SplitN(name, "/", 2)
  30. if len(parts) != 2 {
  31. // Invalid format, does not follow `/package.service/method`.
  32. return name, []attribute.KeyValue(nil)
  33. }
  34. var attrs []attribute.KeyValue
  35. if service := parts[0]; service != "" {
  36. attrs = append(attrs, semconv.RPCServiceKey.String(service))
  37. }
  38. if method := parts[1]; method != "" {
  39. attrs = append(attrs, semconv.RPCMethodKey.String(method))
  40. }
  41. return name, attrs
  42. }
  43. // PeerAttr returns the peer attributes.
  44. func PeerAttr(addr string) []attribute.KeyValue {
  45. host, port, err := net.SplitHostPort(addr)
  46. if err != nil {
  47. return []attribute.KeyValue(nil)
  48. }
  49. if host == "" {
  50. host = "127.0.0.1"
  51. }
  52. return []attribute.KeyValue{
  53. semconv.NetPeerIPKey.String(host),
  54. semconv.NetPeerPortKey.String(port),
  55. }
  56. }