Extend semantic convetions for RPC (#900)
* Extend semantic convetions for RPC * Update changelog * make service attribute conform to spec * Update api/standard/trace.go Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
parent
918c6547c9
commit
1c9aab619d
|
|
@ -28,6 +28,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||||
- The B3 propagator now extracts from either HTTP encoding of B3 (Single Header or Multiple Header) based on what is contained in the header.
|
- The B3 propagator now extracts from either HTTP encoding of B3 (Single Header or Multiple Header) based on what is contained in the header.
|
||||||
Preference is given to Single Header encoding with Multiple Header being the fallback if Single Header is not found or is invalid.
|
Preference is given to Single Header encoding with Multiple Header being the fallback if Single Header is not found or is invalid.
|
||||||
This behavior change is made to dynamically support all correctly encoded traces received instead of having to guess the expected encoding prior to receiving. (#882)
|
This behavior change is made to dynamically support all correctly encoded traces received instead of having to guess the expected encoding prior to receiving. (#882)
|
||||||
|
- Extend semantic conventions for RPC. (#900)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,9 +188,15 @@ const (
|
||||||
|
|
||||||
// Standard attribute keys for RPC.
|
// Standard attribute keys for RPC.
|
||||||
const (
|
const (
|
||||||
// The RPC service name.
|
// A string identifying the remoting system.
|
||||||
|
RPCSystemKey = kv.Key("rpc.system")
|
||||||
|
|
||||||
|
// The full name of the service being called.
|
||||||
RPCServiceKey = kv.Key("rpc.service")
|
RPCServiceKey = kv.Key("rpc.service")
|
||||||
|
|
||||||
|
// The name of the method being called.
|
||||||
|
RPCMethodKey = kv.Key("rpc.method")
|
||||||
|
|
||||||
// Name of message transmitted or received.
|
// Name of message transmitted or received.
|
||||||
RPCNameKey = kv.Key("name")
|
RPCNameKey = kv.Key("name")
|
||||||
|
|
||||||
|
|
@ -209,6 +215,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
RPCSystemGRPC = RPCSystemKey.String("grpc")
|
||||||
|
|
||||||
RPCNameMessage = RPCNameKey.String("message")
|
RPCNameMessage = RPCNameKey.String("message")
|
||||||
|
|
||||||
RPCMessageTypeSent = RPCMessageTypeKey.String("SENT")
|
RPCMessageTypeSent = RPCMessageTypeKey.String("SENT")
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"strings"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/api/standard"
|
"go.opentelemetry.io/otel/api/standard"
|
||||||
|
|
||||||
|
|
@ -86,7 +86,8 @@ func UnaryClientInterceptor(tracer trace.Tracer) grpc.UnaryClientInterceptor {
|
||||||
ctx, method,
|
ctx, method,
|
||||||
trace.WithSpanKind(trace.SpanKindClient),
|
trace.WithSpanKind(trace.SpanKindClient),
|
||||||
trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
|
trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
|
||||||
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(method))),
|
trace.WithAttributes(standard.RPCSystemGRPC),
|
||||||
|
trace.WithAttributes(serviceAndMethodFromFullName(method)...),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
|
@ -264,7 +265,8 @@ func StreamClientInterceptor(tracer trace.Tracer) grpc.StreamClientInterceptor {
|
||||||
ctx, method,
|
ctx, method,
|
||||||
trace.WithSpanKind(trace.SpanKindClient),
|
trace.WithSpanKind(trace.SpanKindClient),
|
||||||
trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
|
trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
|
||||||
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(method))),
|
trace.WithAttributes(standard.RPCSystemGRPC),
|
||||||
|
trace.WithAttributes(serviceAndMethodFromFullName(method)...),
|
||||||
)
|
)
|
||||||
|
|
||||||
Inject(ctx, &metadataCopy)
|
Inject(ctx, &metadataCopy)
|
||||||
|
|
@ -318,7 +320,8 @@ func UnaryServerInterceptor(tracer trace.Tracer) grpc.UnaryServerInterceptor {
|
||||||
info.FullMethod,
|
info.FullMethod,
|
||||||
trace.WithSpanKind(trace.SpanKindServer),
|
trace.WithSpanKind(trace.SpanKindServer),
|
||||||
trace.WithAttributes(peerInfoFromContext(ctx)...),
|
trace.WithAttributes(peerInfoFromContext(ctx)...),
|
||||||
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(info.FullMethod))),
|
trace.WithAttributes(standard.RPCSystemGRPC),
|
||||||
|
trace.WithAttributes(serviceAndMethodFromFullName(info.FullMethod)...),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
|
@ -408,7 +411,8 @@ func StreamServerInterceptor(tracer trace.Tracer) grpc.StreamServerInterceptor {
|
||||||
info.FullMethod,
|
info.FullMethod,
|
||||||
trace.WithSpanKind(trace.SpanKindServer),
|
trace.WithSpanKind(trace.SpanKindServer),
|
||||||
trace.WithAttributes(peerInfoFromContext(ctx)...),
|
trace.WithAttributes(peerInfoFromContext(ctx)...),
|
||||||
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(info.FullMethod))),
|
trace.WithAttributes(standard.RPCSystemGRPC),
|
||||||
|
trace.WithAttributes(serviceAndMethodFromFullName(info.FullMethod)...),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
|
@ -450,13 +454,14 @@ func peerInfoFromContext(ctx context.Context) []kv.KeyValue {
|
||||||
return peerInfoFromTarget(p.Addr.String())
|
return peerInfoFromTarget(p.Addr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullMethodRegexp = regexp.MustCompile(`^\/?(?:\S+\.)?(\S+)\/\S+$`)
|
func serviceAndMethodFromFullName(method string) []kv.KeyValue {
|
||||||
|
l := strings.LastIndexByte(method, '/')
|
||||||
func serviceFromFullMethod(method string) string {
|
if l == -1 {
|
||||||
match := fullMethodRegexp.FindStringSubmatch(method)
|
return []kv.KeyValue{}
|
||||||
if len(match) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return match[1]
|
return []kv.KeyValue{
|
||||||
|
standard.RPCServiceKey.String(method[:l]),
|
||||||
|
standard.RPCMethodKey.String(method[l+1:]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "/github.com.serviceName/bar",
|
name: "/github.com.serviceName/bar",
|
||||||
expectedAttr: map[kv.Key]value.Value{
|
expectedAttr: map[kv.Key]value.Value{
|
||||||
standard.RPCServiceKey: value.String("serviceName"),
|
standard.RPCSystemKey: value.String("grpc"),
|
||||||
|
standard.RPCServiceKey: value.String("/github.com.serviceName"),
|
||||||
|
standard.RPCMethodKey: value.String("bar"),
|
||||||
standard.NetPeerIPKey: value.String("fake"),
|
standard.NetPeerIPKey: value.String("fake"),
|
||||||
standard.NetPeerPortKey: value.String("connection"),
|
standard.NetPeerPortKey: value.String("connection"),
|
||||||
},
|
},
|
||||||
|
|
@ -117,7 +119,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "/serviceName/bar",
|
name: "/serviceName/bar",
|
||||||
expectedAttr: map[kv.Key]value.Value{
|
expectedAttr: map[kv.Key]value.Value{
|
||||||
standard.RPCServiceKey: value.String("serviceName"),
|
standard.RPCSystemKey: value.String("grpc"),
|
||||||
|
standard.RPCServiceKey: value.String("/serviceName"),
|
||||||
|
standard.RPCMethodKey: value.String("bar"),
|
||||||
standard.NetPeerIPKey: value.String("fake"),
|
standard.NetPeerIPKey: value.String("fake"),
|
||||||
standard.NetPeerPortKey: value.String("connection"),
|
standard.NetPeerPortKey: value.String("connection"),
|
||||||
},
|
},
|
||||||
|
|
@ -137,7 +141,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "serviceName/bar",
|
name: "serviceName/bar",
|
||||||
expectedAttr: map[kv.Key]value.Value{
|
expectedAttr: map[kv.Key]value.Value{
|
||||||
|
standard.RPCSystemKey: value.String("grpc"),
|
||||||
standard.RPCServiceKey: value.String("serviceName"),
|
standard.RPCServiceKey: value.String("serviceName"),
|
||||||
|
standard.RPCMethodKey: value.String("bar"),
|
||||||
standard.NetPeerIPKey: value.String("fake"),
|
standard.NetPeerIPKey: value.String("fake"),
|
||||||
standard.NetPeerPortKey: value.String("connection"),
|
standard.NetPeerPortKey: value.String("connection"),
|
||||||
},
|
},
|
||||||
|
|
@ -157,7 +163,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "invalidName",
|
name: "invalidName",
|
||||||
expectedAttr: map[kv.Key]value.Value{
|
expectedAttr: map[kv.Key]value.Value{
|
||||||
standard.RPCServiceKey: value.String(""),
|
standard.RPCSystemKey: value.String("grpc"),
|
||||||
standard.NetPeerIPKey: value.String("fake"),
|
standard.NetPeerIPKey: value.String("fake"),
|
||||||
standard.NetPeerPortKey: value.String("connection"),
|
standard.NetPeerPortKey: value.String("connection"),
|
||||||
},
|
},
|
||||||
|
|
@ -177,7 +183,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "/github.com.foo.serviceName_123/method",
|
name: "/github.com.foo.serviceName_123/method",
|
||||||
expectedAttr: map[kv.Key]value.Value{
|
expectedAttr: map[kv.Key]value.Value{
|
||||||
standard.RPCServiceKey: value.String("serviceName_123"),
|
standard.RPCSystemKey: value.String("grpc"),
|
||||||
|
standard.RPCServiceKey: value.String("/github.com.foo.serviceName_123"),
|
||||||
|
standard.RPCMethodKey: value.String("method"),
|
||||||
standard.NetPeerIPKey: value.String("fake"),
|
standard.NetPeerIPKey: value.String("fake"),
|
||||||
standard.NetPeerPortKey: value.String("connection"),
|
standard.NetPeerPortKey: value.String("connection"),
|
||||||
},
|
},
|
||||||
|
|
@ -346,7 +354,9 @@ func TestStreamClientInterceptor(t *testing.T) {
|
||||||
|
|
||||||
attrs := spanData.Attributes
|
attrs := spanData.Attributes
|
||||||
expectedAttr := map[kv.Key]string{
|
expectedAttr := map[kv.Key]string{
|
||||||
standard.RPCServiceKey: "serviceName",
|
standard.RPCSystemKey: "grpc",
|
||||||
|
standard.RPCServiceKey: "/github.com.serviceName",
|
||||||
|
standard.RPCMethodKey: "bar",
|
||||||
standard.NetPeerIPKey: "fake",
|
standard.NetPeerIPKey: "fake",
|
||||||
standard.NetPeerPortKey: "connection",
|
standard.NetPeerPortKey: "connection",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue