Skip to content

Commit

Permalink
Extend semantic convetions for RPC (#900)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
matej-g and MrAlias authored Jul 8, 2020
1 parent 918c654 commit 1c9aab6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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)
- Extend semantic conventions for RPC. (#900)

### Removed

Expand Down
10 changes: 9 additions & 1 deletion api/standard/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,15 @@ const (

// Standard attribute keys for RPC.
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")

// The name of the method being called.
RPCMethodKey = kv.Key("rpc.method")

// Name of message transmitted or received.
RPCNameKey = kv.Key("name")

Expand All @@ -209,6 +215,8 @@ const (
)

var (
RPCSystemGRPC = RPCSystemKey.String("grpc")

RPCNameMessage = RPCNameKey.String("message")

RPCMessageTypeSent = RPCMessageTypeKey.String("SENT")
Expand Down
29 changes: 17 additions & 12 deletions instrumentation/grpctrace/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"context"
"io"
"net"
"regexp"
"strings"

"go.opentelemetry.io/otel/api/standard"

Expand Down Expand Up @@ -86,7 +86,8 @@ func UnaryClientInterceptor(tracer trace.Tracer) grpc.UnaryClientInterceptor {
ctx, method,
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(method))),
trace.WithAttributes(standard.RPCSystemGRPC),
trace.WithAttributes(serviceAndMethodFromFullName(method)...),
)
defer span.End()

Expand Down Expand Up @@ -264,7 +265,8 @@ func StreamClientInterceptor(tracer trace.Tracer) grpc.StreamClientInterceptor {
ctx, method,
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(method))),
trace.WithAttributes(standard.RPCSystemGRPC),
trace.WithAttributes(serviceAndMethodFromFullName(method)...),
)

Inject(ctx, &metadataCopy)
Expand Down Expand Up @@ -318,7 +320,8 @@ func UnaryServerInterceptor(tracer trace.Tracer) grpc.UnaryServerInterceptor {
info.FullMethod,
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(peerInfoFromContext(ctx)...),
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(info.FullMethod))),
trace.WithAttributes(standard.RPCSystemGRPC),
trace.WithAttributes(serviceAndMethodFromFullName(info.FullMethod)...),
)
defer span.End()

Expand Down Expand Up @@ -408,7 +411,8 @@ func StreamServerInterceptor(tracer trace.Tracer) grpc.StreamServerInterceptor {
info.FullMethod,
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(peerInfoFromContext(ctx)...),
trace.WithAttributes(standard.RPCServiceKey.String(serviceFromFullMethod(info.FullMethod))),
trace.WithAttributes(standard.RPCSystemGRPC),
trace.WithAttributes(serviceAndMethodFromFullName(info.FullMethod)...),
)
defer span.End()

Expand Down Expand Up @@ -450,13 +454,14 @@ func peerInfoFromContext(ctx context.Context) []kv.KeyValue {
return peerInfoFromTarget(p.Addr.String())
}

var fullMethodRegexp = regexp.MustCompile(`^\/?(?:\S+\.)?(\S+)\/\S+$`)

func serviceFromFullMethod(method string) string {
match := fullMethodRegexp.FindStringSubmatch(method)
if len(match) == 0 {
return ""
func serviceAndMethodFromFullName(method string) []kv.KeyValue {
l := strings.LastIndexByte(method, '/')
if l == -1 {
return []kv.KeyValue{}
}

return match[1]
return []kv.KeyValue{
standard.RPCServiceKey.String(method[:l]),
standard.RPCMethodKey.String(method[l+1:]),
}
}
20 changes: 15 additions & 5 deletions instrumentation/grpctrace/interceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
{
name: "/github.com.serviceName/bar",
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.NetPeerPortKey: value.String("connection"),
},
Expand All @@ -117,7 +119,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
{
name: "/serviceName/bar",
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.NetPeerPortKey: value.String("connection"),
},
Expand All @@ -137,7 +141,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
{
name: "serviceName/bar",
expectedAttr: map[kv.Key]value.Value{
standard.RPCSystemKey: value.String("grpc"),
standard.RPCServiceKey: value.String("serviceName"),
standard.RPCMethodKey: value.String("bar"),
standard.NetPeerIPKey: value.String("fake"),
standard.NetPeerPortKey: value.String("connection"),
},
Expand All @@ -157,7 +163,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
{
name: "invalidName",
expectedAttr: map[kv.Key]value.Value{
standard.RPCServiceKey: value.String(""),
standard.RPCSystemKey: value.String("grpc"),
standard.NetPeerIPKey: value.String("fake"),
standard.NetPeerPortKey: value.String("connection"),
},
Expand All @@ -177,7 +183,9 @@ func TestUnaryClientInterceptor(t *testing.T) {
{
name: "/github.com.foo.serviceName_123/method",
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.NetPeerPortKey: value.String("connection"),
},
Expand Down Expand Up @@ -346,7 +354,9 @@ func TestStreamClientInterceptor(t *testing.T) {

attrs := spanData.Attributes
expectedAttr := map[kv.Key]string{
standard.RPCServiceKey: "serviceName",
standard.RPCSystemKey: "grpc",
standard.RPCServiceKey: "/github.com.serviceName",
standard.RPCMethodKey: "bar",
standard.NetPeerIPKey: "fake",
standard.NetPeerPortKey: "connection",
}
Expand Down

0 comments on commit 1c9aab6

Please sign in to comment.