You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-25 22:41:46 +02:00
* Update License header for all source files - Add Apache 2.0 header to source files that did not have one. - Update all existing headers dated to 2019 to be 2020 - Remove comma from License header to comply with the Apache 2.0 guidelines. * Update Copyright notice Use the standard Copyright notices outlined by the [CNCF](https://github.com/cncf/foundation/blob/master/copyright-notices.md#copyright-notices)
86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package tracing
|
|
|
|
// gRPC tracing middleware
|
|
// https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-rpc.md
|
|
import (
|
|
"context"
|
|
|
|
"go.opentelemetry.io/otel/plugin/grpctrace"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/metadata"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"go.opentelemetry.io/otel/api/core"
|
|
"go.opentelemetry.io/otel/api/correlation"
|
|
"go.opentelemetry.io/otel/api/global"
|
|
"go.opentelemetry.io/otel/api/key"
|
|
"go.opentelemetry.io/otel/api/trace"
|
|
)
|
|
|
|
// UnaryServerInterceptor intercepts and extracts incoming trace data
|
|
func UnaryServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
|
|
requestMetadata, _ := metadata.FromIncomingContext(ctx)
|
|
metadataCopy := requestMetadata.Copy()
|
|
|
|
entries, spanCtx := grpctrace.Extract(ctx, &metadataCopy)
|
|
ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{
|
|
MultiKV: entries,
|
|
}))
|
|
|
|
grpcServerKey := key.New("grpc.server")
|
|
serverSpanAttrs := []core.KeyValue{
|
|
grpcServerKey.String("hello-world-server"),
|
|
}
|
|
|
|
tr := global.Tracer("example/grpc")
|
|
ctx, span := tr.Start(
|
|
trace.ContextWithRemoteSpanContext(ctx, spanCtx),
|
|
"hello-api-op",
|
|
trace.WithAttributes(serverSpanAttrs...),
|
|
trace.WithSpanKind(trace.SpanKindServer),
|
|
)
|
|
defer span.End()
|
|
|
|
return handler(ctx, req)
|
|
}
|
|
|
|
// UnaryClientInterceptor intercepts and injects outgoing trace
|
|
func UnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
|
requestMetadata, _ := metadata.FromOutgoingContext(ctx)
|
|
metadataCopy := requestMetadata.Copy()
|
|
|
|
tr := global.Tracer("example/grpc")
|
|
err := tr.WithSpan(ctx, "hello-api-op",
|
|
func(ctx context.Context) error {
|
|
grpctrace.Inject(ctx, &metadataCopy)
|
|
ctx = metadata.NewOutgoingContext(ctx, metadataCopy)
|
|
|
|
err := invoker(ctx, method, req, reply, cc, opts...)
|
|
setTraceStatus(ctx, err)
|
|
return err
|
|
})
|
|
return err
|
|
}
|
|
|
|
func setTraceStatus(ctx context.Context, err error) {
|
|
if err != nil {
|
|
s, _ := status.FromError(err)
|
|
trace.SpanFromContext(ctx).SetStatus(s.Code(), s.Message())
|
|
}
|
|
}
|