diff --git a/contrib/99designs/gqlgen/tracer.go b/contrib/99designs/gqlgen/tracer.go index 89062aed3d..f2a38c27df 100644 --- a/contrib/99designs/gqlgen/tracer.go +++ b/contrib/99designs/gqlgen/tracer.go @@ -90,6 +90,7 @@ func (t *gqlTracer) InterceptResponse(ctx context.Context, next graphql.Response opts := []ddtrace.StartSpanOption{ tracer.SpanType(ext.SpanTypeGraphQL), tracer.ServiceName(t.cfg.serviceName), + tracer.Tag(ext.Component, "99designs/gqlgen"), } if !math.IsNaN(t.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, t.cfg.analyticsRate)) @@ -136,6 +137,7 @@ func (t *gqlTracer) InterceptResponse(ctx context.Context, next graphql.Response var childOpts []ddtrace.StartSpanOption childOpts = append(childOpts, tracer.StartTime(start)) childOpts = append(childOpts, tracer.ResourceName(name)) + childOpts = append(childOpts, tracer.Tag(ext.Component, "99designs/gqlgen")) var childSpan ddtrace.Span childSpan, _ = tracer.StartSpanFromContext(ctx, name, childOpts...) childSpan.Finish(tracer.FinishTime(finish)) diff --git a/contrib/99designs/gqlgen/tracer_test.go b/contrib/99designs/gqlgen/tracer_test.go index 1375d15bd5..4b85ad2e40 100644 --- a/contrib/99designs/gqlgen/tracer_test.go +++ b/contrib/99designs/gqlgen/tracer_test.go @@ -30,6 +30,7 @@ func TestOptions(t *testing.T) { assert.Equal(query, root.Tag(ext.ResourceName)) assert.Equal(defaultServiceName, root.Tag(ext.ServiceName)) assert.Equal(ext.SpanTypeGraphQL, root.Tag(ext.SpanType)) + assert.Equal("99designs/gqlgen", root.Tag(ext.Component)) assert.Nil(root.Tag(ext.EventSampleRate)) }, }, @@ -143,6 +144,7 @@ func TestChildSpans(t *testing.T) { } resNames = append(resNames, span.Tag(ext.ResourceName).(string)) opNames = append(opNames, span.OperationName()) + assert.Equal("99designs/gqlgen", span.Tag(ext.Component)) } assert.ElementsMatch(resNames, []string{readOp, validationOp, parsingOp, query}) assert.ElementsMatch(opNames, []string{readOp, validationOp, parsingOp, "graphql.query"}) diff --git a/contrib/README.md b/contrib/README.md index 8030e9c6c3..c2178feda8 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -19,5 +19,10 @@ First, find the library which you'd like to integrate with. The naming conventio * All new integrations should be suffixed with `.vN` where `N` is the major version that is being covered. If the integration covers more than one major version, the minimum version supported should be chosen for the suffix. (ex. If the integration covers versions `2.x.x` - `4.x.x`, the suffix will be `.v2`) * The package itself should retain its un-versioned name. For example, the integration under `user/repo.v2` stays as `package repo`, and does not become `package repo.v2` +Second, there are a few tags that should be found in all integration spans: +* The `span.kind` tag should be set in root spans with either a `client`, `server`, `producer`, or `consumer` value according to the [definitions](../ddtrace/ext/span_kind.go) found in the repository. +If the value is determined to be `internal`, then omit the tag as that is the assumed default value. Otherwise, explicitly set it with a value from above. +* The `component` tag should be set in all spans with the value equivalent to full naming convention of the integration package explained in the previous step. + Each integration comes with thorough documentation and usage examples. A good overview can be seen on our [godoc](https://godoc.org/gopkg.in/DataDog/dd-trace-go.v1/contrib) page. diff --git a/contrib/Shopify/sarama/sarama.go b/contrib/Shopify/sarama/sarama.go index 09dd89a3c8..4913e085ef 100644 --- a/contrib/Shopify/sarama/sarama.go +++ b/contrib/Shopify/sarama/sarama.go @@ -52,6 +52,8 @@ func WrapPartitionConsumer(pc sarama.PartitionConsumer, opts ...Option) sarama.P tracer.SpanType(ext.SpanTypeMessageConsumer), tracer.Tag("partition", msg.Partition), tracer.Tag("offset", msg.Offset), + tracer.Tag(ext.Component, "Shopify/sarama"), + tracer.Tag(ext.SpanKind, ext.SpanKindConsumer), tracer.Measured(), } if !math.IsNaN(cfg.analyticsRate) { @@ -258,6 +260,8 @@ func startProducerSpan(cfg *config, version sarama.KafkaVersion, msg *sarama.Pro tracer.ServiceName(cfg.producerServiceName), tracer.ResourceName("Produce Topic " + msg.Topic), tracer.SpanType(ext.SpanTypeMessageProducer), + tracer.Tag(ext.Component, "Shopify/sarama"), + tracer.Tag(ext.SpanKind, ext.SpanKindProducer), } if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) diff --git a/contrib/Shopify/sarama/sarama_test.go b/contrib/Shopify/sarama/sarama_test.go index 21cba82621..21a046ed15 100644 --- a/contrib/Shopify/sarama/sarama_test.go +++ b/contrib/Shopify/sarama/sarama_test.go @@ -77,6 +77,8 @@ func TestConsumer(t *testing.T) { assert.Equal(t, "Consume Topic test-topic", s.Tag(ext.ResourceName)) assert.Equal(t, "queue", s.Tag(ext.SpanType)) assert.Equal(t, "kafka.consume", s.OperationName()) + assert.Equal(t, "Shopify/sarama", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindConsumer, s.Tag(ext.SpanKind)) } { s := spans[1] @@ -91,6 +93,8 @@ func TestConsumer(t *testing.T) { assert.Equal(t, "Consume Topic test-topic", s.Tag(ext.ResourceName)) assert.Equal(t, "queue", s.Tag(ext.SpanType)) assert.Equal(t, "kafka.consume", s.OperationName()) + assert.Equal(t, "Shopify/sarama", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindConsumer, s.Tag(ext.SpanKind)) } } @@ -140,6 +144,8 @@ func TestSyncProducer(t *testing.T) { assert.Equal(t, "kafka.produce", s.OperationName()) assert.Equal(t, int32(0), s.Tag("partition")) assert.Equal(t, int64(0), s.Tag("offset")) + assert.Equal(t, "Shopify/sarama", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s.Tag(ext.SpanKind)) } } @@ -191,6 +197,8 @@ func TestSyncProducerSendMessages(t *testing.T) { assert.Equal(t, "Produce Topic my_topic", s.Tag(ext.ResourceName)) assert.Equal(t, "kafka.produce", s.OperationName()) assert.Equal(t, int32(0), s.Tag("partition")) + assert.Equal(t, "Shopify/sarama", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s.Tag(ext.SpanKind)) } } @@ -231,6 +239,8 @@ func TestAsyncProducer(t *testing.T) { assert.Equal(t, "kafka.produce", s.OperationName()) assert.Equal(t, int32(0), s.Tag("partition")) assert.Equal(t, int64(0), s.Tag("offset")) + assert.Equal(t, "Shopify/sarama", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s.Tag(ext.SpanKind)) } }) @@ -269,6 +279,8 @@ func TestAsyncProducer(t *testing.T) { assert.Equal(t, "kafka.produce", s.OperationName()) assert.Equal(t, int32(0), s.Tag("partition")) assert.Equal(t, int64(0), s.Tag("offset")) + assert.Equal(t, "Shopify/sarama", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s.Tag(ext.SpanKind)) } }) } diff --git a/contrib/aws/aws-sdk-go-v2/aws/aws.go b/contrib/aws/aws-sdk-go-v2/aws/aws.go index c239253f8d..503311c15c 100644 --- a/contrib/aws/aws-sdk-go-v2/aws/aws.go +++ b/contrib/aws/aws-sdk-go-v2/aws/aws.go @@ -78,6 +78,8 @@ func (mw *traceMiddleware) startTraceMiddleware(stack *middleware.Stack) error { tracer.Tag(tagAWSOperation, operation), tracer.Tag(tagAWSService, serviceID), tracer.StartTime(ctx.Value(spanTimestampKey{}).(time.Time)), + tracer.Tag(ext.Component, "aws/aws-sdk-go-v2/aws"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(mw.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, mw.cfg.analyticsRate)) diff --git a/contrib/aws/aws-sdk-go-v2/aws/aws_test.go b/contrib/aws/aws-sdk-go-v2/aws/aws_test.go index f42a451d56..c654b94998 100644 --- a/contrib/aws/aws-sdk-go-v2/aws/aws_test.go +++ b/contrib/aws/aws-sdk-go-v2/aws/aws_test.go @@ -79,6 +79,8 @@ func TestAppendMiddleware(t *testing.T) { } assert.Equal(t, "POST", s.Tag(ext.HTTPMethod)) assert.Equal(t, server.URL+"/", s.Tag(ext.HTTPURL)) + assert.Equal(t, "aws/aws-sdk-go-v2/aws", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s.Tag(ext.SpanKind)) }) } } diff --git a/contrib/aws/aws-sdk-go/aws/aws.go b/contrib/aws/aws-sdk-go/aws/aws.go index 23a79a642a..d4c6bb4105 100644 --- a/contrib/aws/aws-sdk-go/aws/aws.go +++ b/contrib/aws/aws-sdk-go/aws/aws.go @@ -69,6 +69,8 @@ func (h *handlers) Send(req *request.Request) { tracer.Tag(tagAWSRegion, h.awsRegion(req)), tracer.Tag(ext.HTTPMethod, req.Operation.HTTPMethod), tracer.Tag(ext.HTTPURL, req.HTTPRequest.URL.String()), + tracer.Tag(ext.Component, "aws/aws-sdk-go/aws"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(h.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, h.cfg.analyticsRate)) diff --git a/contrib/aws/aws-sdk-go/aws/aws_test.go b/contrib/aws/aws-sdk-go/aws/aws_test.go index db4f0bfde6..2db340da9e 100644 --- a/contrib/aws/aws-sdk-go/aws/aws_test.go +++ b/contrib/aws/aws-sdk-go/aws/aws_test.go @@ -57,6 +57,8 @@ func TestAWS(t *testing.T) { assert.Equal(t, "403", s.Tag(ext.HTTPCode)) assert.Equal(t, "PUT", s.Tag(ext.HTTPMethod)) assert.Equal(t, "http://s3.us-west-2.amazonaws.com/BUCKET", s.Tag(ext.HTTPURL)) + assert.Equal(t, "aws/aws-sdk-go/aws", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s.Tag(ext.SpanKind)) assert.NotNil(t, s.Tag(tagAWSRequestID)) }) @@ -83,6 +85,8 @@ func TestAWS(t *testing.T) { assert.Equal(t, "400", s.Tag(ext.HTTPCode)) assert.Equal(t, "POST", s.Tag(ext.HTTPMethod)) assert.Equal(t, "http://ec2.us-west-2.amazonaws.com/", s.Tag(ext.HTTPURL)) + assert.Equal(t, "aws/aws-sdk-go/aws", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s.Tag(ext.SpanKind)) }) } diff --git a/contrib/bradfitz/gomemcache/memcache/memcache.go b/contrib/bradfitz/gomemcache/memcache/memcache.go index 1c13f8660e..da11bc3782 100644 --- a/contrib/bradfitz/gomemcache/memcache/memcache.go +++ b/contrib/bradfitz/gomemcache/memcache/memcache.go @@ -69,6 +69,8 @@ func (c *Client) startSpan(resourceName string) ddtrace.Span { tracer.SpanType(ext.SpanTypeMemcached), tracer.ServiceName(c.cfg.serviceName), tracer.ResourceName(resourceName), + tracer.Tag(ext.Component, "bradfitz/gomemcache/memcache"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(c.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, c.cfg.analyticsRate)) diff --git a/contrib/bradfitz/gomemcache/memcache/memcache_test.go b/contrib/bradfitz/gomemcache/memcache/memcache_test.go index 0e74821a96..183b30483f 100644 --- a/contrib/bradfitz/gomemcache/memcache/memcache_test.go +++ b/contrib/bradfitz/gomemcache/memcache/memcache_test.go @@ -49,6 +49,10 @@ func testMemcache(t *testing.T, addr string) { "operation name should be set to memcached.query") assert.Equal(t, resourceName, span.Tag(ext.ResourceName), "resource name should be set to the memcache command") + assert.Equal(t, "bradfitz/gomemcache/memcache", span.Tag(ext.Component), + "component should be set to gomemcache") + assert.Equal(t, ext.SpanKindClient, span.Tag(ext.SpanKind), + "span.kind should be set to client") } t.Run("default", func(t *testing.T) { diff --git a/contrib/cloud.google.com/go/pubsub.v1/pubsub.go b/contrib/cloud.google.com/go/pubsub.v1/pubsub.go index 6daf0f88b3..2ec2bfb61b 100644 --- a/contrib/cloud.google.com/go/pubsub.v1/pubsub.go +++ b/contrib/cloud.google.com/go/pubsub.v1/pubsub.go @@ -34,6 +34,8 @@ func Publish(ctx context.Context, t *pubsub.Topic, msg *pubsub.Message, opts ... tracer.SpanType(ext.SpanTypeMessageProducer), tracer.Tag("message_size", len(msg.Data)), tracer.Tag("ordering_key", msg.OrderingKey), + tracer.Tag(ext.Component, "cloud.google.com/go/pubsub.v1"), + tracer.Tag(ext.SpanKind, ext.SpanKindProducer), } if cfg.serviceName != "" { spanOpts = append(spanOpts, tracer.ServiceName(cfg.serviceName)) @@ -96,6 +98,8 @@ func WrapReceiveHandler(s *pubsub.Subscription, f func(context.Context, *pubsub. tracer.Tag("ordering_key", msg.OrderingKey), tracer.Tag("message_id", msg.ID), tracer.Tag("publish_time", msg.PublishTime.String()), + tracer.Tag(ext.Component, "cloud.google.com/go/pubsub.v1"), + tracer.Tag(ext.SpanKind, ext.SpanKindConsumer), tracer.ChildOf(parentSpanCtx), } if cfg.serviceName != "" { diff --git a/contrib/cloud.google.com/go/pubsub.v1/pubsub_test.go b/contrib/cloud.google.com/go/pubsub.v1/pubsub_test.go index ecb5748109..4566bdff1c 100644 --- a/contrib/cloud.google.com/go/pubsub.v1/pubsub_test.go +++ b/contrib/cloud.google.com/go/pubsub.v1/pubsub_test.go @@ -70,6 +70,8 @@ func TestPropagation(t *testing.T) { ext.SpanType: ext.SpanTypeMessageProducer, "server_id": srvID, ext.ServiceName: nil, + ext.Component: "cloud.google.com/go/pubsub.v1", + ext.SpanKind: ext.SpanKindProducer, }, spans[0].Tags()) assert.Equal(spans[0].SpanID(), spans[2].ParentID()) @@ -83,6 +85,8 @@ func TestPropagation(t *testing.T) { ext.SpanType: ext.SpanTypeMessageConsumer, "message_id": msgID, "publish_time": pubTime, + ext.Component: "cloud.google.com/go/pubsub.v1", + ext.SpanKind: ext.SpanKindConsumer, }, spans[2].Tags()) } @@ -155,6 +159,8 @@ func TestPropagationNoParentSpan(t *testing.T) { ext.ResourceName: "projects/project/topics/topic", ext.SpanType: ext.SpanTypeMessageProducer, "server_id": srvID, + ext.Component: "cloud.google.com/go/pubsub.v1", + ext.SpanKind: ext.SpanKindProducer, }, spans[0].Tags()) assert.Equal(spans[0].SpanID(), spans[1].ParentID()) @@ -168,6 +174,8 @@ func TestPropagationNoParentSpan(t *testing.T) { ext.SpanType: ext.SpanTypeMessageConsumer, "message_id": msgID, "publish_time": pubTime, + ext.Component: "cloud.google.com/go/pubsub.v1", + ext.SpanKind: ext.SpanKindConsumer, }, spans[1].Tags()) } @@ -218,6 +226,8 @@ func TestPropagationNoPubsliherSpan(t *testing.T) { ext.SpanType: ext.SpanTypeMessageConsumer, "message_id": msgID, "publish_time": pubTime, + ext.Component: "cloud.google.com/go/pubsub.v1", + ext.SpanKind: ext.SpanKindConsumer, }, spans[0].Tags()) } diff --git a/contrib/confluentinc/confluent-kafka-go/kafka/kafka.go b/contrib/confluentinc/confluent-kafka-go/kafka/kafka.go index 10bb7c3a80..96f15d7d9f 100644 --- a/contrib/confluentinc/confluent-kafka-go/kafka/kafka.go +++ b/contrib/confluentinc/confluent-kafka-go/kafka/kafka.go @@ -96,6 +96,8 @@ func (c *Consumer) startSpan(msg *kafka.Message) ddtrace.Span { tracer.SpanType(ext.SpanTypeMessageConsumer), tracer.Tag("partition", msg.TopicPartition.Partition), tracer.Tag("offset", msg.TopicPartition.Offset), + tracer.Tag(ext.Component, "confluentinc/confluent-kafka-go/kafka"), + tracer.Tag(ext.SpanKind, ext.SpanKindConsumer), tracer.Measured(), } if c.cfg.tagFns != nil { @@ -205,6 +207,8 @@ func (p *Producer) startSpan(msg *kafka.Message) ddtrace.Span { tracer.ServiceName(p.cfg.producerServiceName), tracer.ResourceName("Produce Topic " + *msg.TopicPartition.Topic), tracer.SpanType(ext.SpanTypeMessageProducer), + tracer.Tag(ext.Component, "confluentinc/confluent-kafka-go/kafka"), + tracer.Tag(ext.SpanKind, ext.SpanKindProducer), tracer.Tag("partition", msg.TopicPartition.Partition), } if !math.IsNaN(p.cfg.analyticsRate) { diff --git a/contrib/confluentinc/confluent-kafka-go/kafka/kafka_test.go b/contrib/confluentinc/confluent-kafka-go/kafka/kafka_test.go index 62379a7e07..52aa664cd1 100644 --- a/contrib/confluentinc/confluent-kafka-go/kafka/kafka_test.go +++ b/contrib/confluentinc/confluent-kafka-go/kafka/kafka_test.go @@ -85,6 +85,8 @@ func TestConsumerChannel(t *testing.T) { assert.Equal(t, int32(1), s.Tag("partition")) assert.Equal(t, 0.3, s.Tag(ext.EventSampleRate)) assert.Equal(t, kafka.Offset(i+1), s.Tag("offset")) + assert.Equal(t, "confluentinc/confluent-kafka-go/kafka", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindConsumer, s.Tag(ext.SpanKind)) } } @@ -198,6 +200,8 @@ func TestConsumerFunctional(t *testing.T) { assert.Equal(t, 0.1, s0.Tag(ext.EventSampleRate)) assert.Equal(t, "queue", s0.Tag(ext.SpanType)) assert.Equal(t, int32(0), s0.Tag("partition")) + assert.Equal(t, "confluentinc/confluent-kafka-go/kafka", s0.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s0.Tag(ext.SpanKind)) s1 := spans[1] // consume assert.Equal(t, "kafka.consume", s1.OperationName()) @@ -206,6 +210,8 @@ func TestConsumerFunctional(t *testing.T) { assert.Equal(t, nil, s1.Tag(ext.EventSampleRate)) assert.Equal(t, "queue", s1.Tag(ext.SpanType)) assert.Equal(t, int32(0), s1.Tag("partition")) + assert.Equal(t, "confluentinc/confluent-kafka-go/kafka", s1.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindConsumer, s1.Tag(ext.SpanKind)) }) } } diff --git a/contrib/database/sql/conn.go b/contrib/database/sql/conn.go index e221490ae6..73cf67d899 100644 --- a/contrib/database/sql/conn.go +++ b/contrib/database/sql/conn.go @@ -226,6 +226,8 @@ func (tp *traceParams) tryTrace(ctx context.Context, qtype queryType, query stri tracer.ServiceName(tp.cfg.serviceName), tracer.SpanType(ext.SpanTypeSQL), tracer.StartTime(startTime), + tracer.Tag(ext.Component, "database/sql"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), ) if tp.cfg.tags != nil { for key, tag := range tp.cfg.tags { diff --git a/contrib/database/sql/conn_test.go b/contrib/database/sql/conn_test.go index c1a0c27e5e..29452ff603 100644 --- a/contrib/database/sql/conn_test.go +++ b/contrib/database/sql/conn_test.go @@ -102,12 +102,16 @@ func TestWithSpanTags(t *testing.T) { for k, v := range tt.want.ctxTags { assert.Equal(t, v, connectSpan.Tag(k), "Value mismatch on tag %s", k) } + assert.Equal(t, ext.SpanKindClient, connectSpan.Tag(ext.SpanKind)) + assert.Equal(t, "database/sql", connectSpan.Tag(ext.Component)) span := spans[1] assert.Equal(t, tt.want.opName, span.OperationName()) for k, v := range tt.want.ctxTags { assert.Equal(t, v, span.Tag(k), "Value mismatch on tag %s", k) } + assert.Equal(t, ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal(t, "database/sql", span.Tag(ext.Component)) }) } } @@ -284,12 +288,16 @@ func TestWithCustomTag(t *testing.T) { for k, v := range tt.want.customTags { assert.Equal(t, v, connectSpan.Tag(k), "Value mismatch on tag %s", k) } + assert.Equal(t, ext.SpanKindClient, connectSpan.Tag(ext.SpanKind)) + assert.Equal(t, "database/sql", connectSpan.Tag(ext.Component)) span := spans[1] assert.Equal(t, tt.want.opName, span.OperationName()) for k, v := range tt.want.customTags { assert.Equal(t, v, span.Tag(k), "Value mismatch on tag %s", k) } + assert.Equal(t, ext.SpanKindClient, connectSpan.Tag(ext.SpanKind)) + assert.Equal(t, "database/sql", connectSpan.Tag(ext.Component)) }) } } diff --git a/contrib/elastic/go-elasticsearch.v6/elastictrace.go b/contrib/elastic/go-elasticsearch.v6/elastictrace.go index d85bb3a635..d42465354b 100644 --- a/contrib/elastic/go-elasticsearch.v6/elastictrace.go +++ b/contrib/elastic/go-elasticsearch.v6/elastictrace.go @@ -57,6 +57,8 @@ func (t *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { tracer.Tag("elasticsearch.method", method), tracer.Tag("elasticsearch.url", url), tracer.Tag("elasticsearch.params", req.URL.Query().Encode()), + tracer.Tag(ext.Component, "elastic/go-elasticsearch.v6"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(t.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, t.config.analyticsRate)) diff --git a/contrib/elastic/go-elasticsearch.v6/elastictrace_test.go b/contrib/elastic/go-elasticsearch.v6/elastictrace_test.go index d540155fb3..4b7ae6f0ee 100644 --- a/contrib/elastic/go-elasticsearch.v6/elastictrace_test.go +++ b/contrib/elastic/go-elasticsearch.v6/elastictrace_test.go @@ -42,6 +42,8 @@ func checkPUTTrace(assert *assert.Assertions, mt mocktracer.Tracer) { assert.Equal("/twitter/tweet/1", span.Tag("elasticsearch.url")) assert.Equal("PUT", span.Tag("elasticsearch.method")) assert.Equal(`{"user": "test", "message": "hello"}`, span.Tag("elasticsearch.body")) + assert.Equal("elastic/go-elasticsearch.v6", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func checkGETTrace(assert *assert.Assertions, mt mocktracer.Tracer) { @@ -50,6 +52,8 @@ func checkGETTrace(assert *assert.Assertions, mt mocktracer.Tracer) { assert.Equal("GET /twitter/tweet/?", span.Tag(ext.ResourceName)) assert.Equal("/twitter/tweet/1", span.Tag("elasticsearch.url")) assert.Equal("GET", span.Tag("elasticsearch.method")) + assert.Equal("elastic/go-elasticsearch.v6", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func checkErrTrace(assert *assert.Assertions, mt mocktracer.Tracer) { @@ -59,6 +63,8 @@ func checkErrTrace(assert *assert.Assertions, mt mocktracer.Tracer) { assert.Equal("/not-real-index/_doc/1", span.Tag("elasticsearch.url")) assert.NotEmpty(span.Tag(ext.Error)) assert.Equal("*errors.errorString", fmt.Sprintf("%T", span.Tag(ext.Error).(error))) + assert.Equal("elastic/go-elasticsearch.v6", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestQuantize(t *testing.T) { diff --git a/contrib/emicklei/go-restful/restful.go b/contrib/emicklei/go-restful/restful.go index c09ed863c2..4428340b34 100644 --- a/contrib/emicklei/go-restful/restful.go +++ b/contrib/emicklei/go-restful/restful.go @@ -28,6 +28,9 @@ func FilterFunc(configOpts ...Option) restful.FilterFunction { spanOpts := []ddtrace.StartSpanOption{tracer.ServiceName(cfg.serviceName)} return func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { spanOpts := append(spanOpts, tracer.ResourceName(req.SelectedRoutePath())) + spanOpts = append(spanOpts, tracer.Tag(ext.Component, "emicklei/go-restful")) + spanOpts = append(spanOpts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + if !math.IsNaN(cfg.analyticsRate) { spanOpts = append(spanOpts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } diff --git a/contrib/emicklei/go-restful/restful_test.go b/contrib/emicklei/go-restful/restful_test.go index a92b944dae..9dffed796d 100644 --- a/contrib/emicklei/go-restful/restful_test.go +++ b/contrib/emicklei/go-restful/restful_test.go @@ -55,6 +55,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("emicklei/go-restful", span.Tag(ext.Component)) } func TestError(t *testing.T) { @@ -86,6 +88,8 @@ func TestError(t *testing.T) { assert.Equal("http.request", span.OperationName()) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("emicklei/go-restful", span.Tag(ext.Component)) } func TestPropagation(t *testing.T) { diff --git a/contrib/garyburd/redigo/redigo.go b/contrib/garyburd/redigo/redigo.go index 92a7bf9690..4a680ef84c 100644 --- a/contrib/garyburd/redigo/redigo.go +++ b/contrib/garyburd/redigo/redigo.go @@ -103,6 +103,8 @@ func (tc Conn) newChildSpan(ctx context.Context) ddtrace.Span { opts := []ddtrace.StartSpanOption{ tracer.SpanType(ext.SpanTypeRedis), tracer.ServiceName(p.config.serviceName), + tracer.Tag(ext.Component, "garyburd/redigo"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) diff --git a/contrib/garyburd/redigo/redigo_test.go b/contrib/garyburd/redigo/redigo_test.go index 9d331751f1..f7a25fe560 100644 --- a/contrib/garyburd/redigo/redigo_test.go +++ b/contrib/garyburd/redigo/redigo_test.go @@ -48,8 +48,9 @@ func TestClient(t *testing.T) { assert.Equal("SET", span.Tag(ext.ResourceName)) assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) - assert.Equal("SET 1 truck", span.Tag("redis.raw_command")) assert.Equal("2", span.Tag("redis.args_length")) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal("garyburd/redigo", span.Tag(ext.Component)) } func TestCommandError(t *testing.T) { @@ -73,6 +74,8 @@ func TestCommandError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("NOT_A_COMMAND", span.Tag("redis.raw_command")) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal("garyburd/redigo", span.Tag(ext.Component)) } func TestConnectionError(t *testing.T) { @@ -115,6 +118,8 @@ func TestInheritance(t *testing.T) { assert.Equal(child.ParentID(), parent.SpanID()) assert.Equal(child.Tag(ext.TargetHost), "127.0.0.1") assert.Equal(child.Tag(ext.TargetPort), "6379") + assert.Equal(ext.SpanKindClient, child.Tag(ext.SpanKind)) + assert.Equal("garyburd/redigo", child.Tag(ext.Component)) } type stringifyTest struct{ A, B int } @@ -141,6 +146,8 @@ func TestCommandsToSring(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("SADD testSet a 0 1 2 [57, 8]", span.Tag("redis.raw_command")) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal("garyburd/redigo", span.Tag(ext.Component)) } func TestPool(t *testing.T) { diff --git a/contrib/gin-gonic/gin/gintrace.go b/contrib/gin-gonic/gin/gintrace.go index 33dc894d82..7c9a3aa9ed 100644 --- a/contrib/gin-gonic/gin/gintrace.go +++ b/contrib/gin-gonic/gin/gintrace.go @@ -40,6 +40,9 @@ func Middleware(service string, opts ...Option) gin.HandlerFunc { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } opts = append(opts, tracer.Tag(ext.HTTPRoute, c.FullPath())) + opts = append(opts, tracer.Tag(ext.Component, "gin-gonic/gin")) + opts = append(opts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + span, ctx := httptrace.StartRequestSpan(c.Request, opts...) defer func() { httptrace.FinishRequestSpan(span, c.Writer.Status()) @@ -67,6 +70,7 @@ func Middleware(service string, opts ...Option) gin.HandlerFunc { func HTML(c *gin.Context, code int, name string, obj interface{}) { span, _ := tracer.StartSpanFromContext(c.Request.Context(), "gin.render.html") span.SetTag("go.template", name) + span.SetTag(ext.Component, "gin-gonic/gin") defer func() { if r := recover(); r != nil { err := fmt.Errorf("error rendering tmpl:%s: %s", name, r) diff --git a/contrib/gin-gonic/gin/gintrace_test.go b/contrib/gin-gonic/gin/gintrace_test.go index 5e5740fe94..8e33046fb4 100644 --- a/contrib/gin-gonic/gin/gintrace_test.go +++ b/contrib/gin-gonic/gin/gintrace_test.go @@ -86,6 +86,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gin-gonic/gin", span.Tag(ext.Component)) } func TestTraceDefaultResponse(t *testing.T) { @@ -122,6 +124,8 @@ func TestTraceDefaultResponse(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gin-gonic/gin", span.Tag(ext.Component)) } func TestTraceMultipleResponses(t *testing.T) { @@ -161,6 +165,8 @@ func TestTraceMultipleResponses(t *testing.T) { assert.Equal("133", span.Tag(ext.HTTPCode)) // Will be fixed by https://github.com/gin-gonic/gin/pull/2627 once merged and released assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gin-gonic/gin", span.Tag(ext.Component)) } func TestError(t *testing.T) { @@ -199,6 +205,8 @@ func TestError(t *testing.T) { assert.Equal(fmt.Sprintf("Error #01: %s\n", responseErr), span.Tag("gin.errors")) // server errors set the ext.Error tag assert.Equal("500: Internal Server Error", span.Tag(ext.Error).(error).Error()) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gin-gonic/gin", span.Tag(ext.Component)) }) t.Run("client error", func(*testing.T) { @@ -227,6 +235,8 @@ func TestError(t *testing.T) { assert.Equal(fmt.Sprintf("Error #01: %s\n", responseErr), span.Tag("gin.errors")) // client errors do not set the ext.Error tag assert.Equal(nil, span.Tag(ext.Error)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gin-gonic/gin", span.Tag(ext.Component)) }) } @@ -259,6 +269,7 @@ func TestHTML(t *testing.T) { assert.Len(spans, 2) for _, s := range spans { assert.Equal("foobar", s.Tag(ext.ServiceName), s.String()) + assert.Equal("gin-gonic/gin", s.Tag(ext.Component)) } var tspan mocktracer.Span @@ -271,6 +282,9 @@ func TestHTML(t *testing.T) { } assert.NotNil(tspan) assert.Equal("hello", tspan.Tag("go.template")) + + _, ok := tspan.Tags()[ext.SpanKind] + assert.Equal(false, ok) } func TestGetSpanNotInstrumented(t *testing.T) { diff --git a/contrib/globalsign/mgo/collection.go b/contrib/globalsign/mgo/collection.go index be29e3d83e..cdf2561d69 100644 --- a/contrib/globalsign/mgo/collection.go +++ b/contrib/globalsign/mgo/collection.go @@ -201,7 +201,9 @@ func (c *Collection) RemoveAll(selector interface{}) (info *mgo.ChangeInfo, err // Repair invokes and traces Collection.Repair func (c *Collection) Repair() *Iter { + c.tags["createChild"] = "true" // flag to tell newChildSpanFromContext not to set span.kind span := newChildSpanFromContext(c.cfg, c.tags) + delete(c.tags, "createChild") // removes flag after creating span iter := c.Collection.Repair() span.Finish() return &Iter{ diff --git a/contrib/globalsign/mgo/mgo.go b/contrib/globalsign/mgo/mgo.go index 7fba385ab6..b2494d1848 100644 --- a/contrib/globalsign/mgo/mgo.go +++ b/contrib/globalsign/mgo/mgo.go @@ -56,7 +56,13 @@ func newChildSpanFromContext(cfg *mongoConfig, tags map[string]string) ddtrace.S tracer.SpanType(ext.SpanTypeMongoDB), tracer.ServiceName(cfg.serviceName), tracer.ResourceName("mongodb.query"), + tracer.Tag(ext.Component, "globalsign/mgo"), } + + if _, ok := tags["createChild"]; !ok { + opts = append(opts, tracer.Tag(ext.SpanKind, ext.SpanKindClient)) + } + if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } diff --git a/contrib/globalsign/mgo/mgo_test.go b/contrib/globalsign/mgo/mgo_test.go index f235e90805..ae647a5e88 100644 --- a/contrib/globalsign/mgo/mgo_test.go +++ b/contrib/globalsign/mgo/mgo_test.go @@ -55,9 +55,48 @@ func testMongoCollectionCommand(assert *assert.Assertions, command func(*Collect parentSpan.Finish() spans := mt.FinishedSpans() + + for _, val := range spans { + if val.OperationName() == "mongodb.query" { + assert.Equal("globalsign/mgo", val.Tag(ext.Component)) + } + } + return spans } +func TestIter_NoSpanKind(t *testing.T) { + assert := assert.New(t) + + entity := bson.D{ + bson.DocElem{ + Name: "entity", + Value: bson.DocElem{ + Name: "index", + Value: 0}}} + + insert := func(collection *Collection) { + collection.Insert(entity) + var r bson.D + collection.Find(entity).Iter().Next(&r) + collection.UpdateId(r.Map()["_id"], entity) + } + + spans := testMongoCollectionCommand(assert, insert) + assert.Equal(5, len(spans)) + + numSpanKindClient := 0 + for _, val := range spans { + if val.OperationName() != "mgo-unittest" { + if val, ok := val.Tags()[ext.SpanKind]; ok && val == ext.SpanKindClient { + numSpanKindClient++ + } + } + } + assert.Equal(3, numSpanKindClient, "Iter() should not get span.kind tag") + +} + func TestCollection_Insert(t *testing.T) { assert := assert.New(t) @@ -75,6 +114,7 @@ func TestCollection_Insert(t *testing.T) { spans := testMongoCollectionCommand(assert, insert) assert.Equal(2, len(spans)) assert.Equal("mongodb.query", spans[0].OperationName()) + assert.Equal(ext.SpanKindClient, spans[0].Tag(ext.SpanKind)) } func TestCollection_Update(t *testing.T) { @@ -95,6 +135,7 @@ func TestCollection_Update(t *testing.T) { spans := testMongoCollectionCommand(assert, insert) assert.Equal(3, len(spans)) assert.Equal("mongodb.query", spans[1].OperationName()) + assert.Equal(ext.SpanKindClient, spans[1].Tag(ext.SpanKind)) } func TestCollection_UpdateId(t *testing.T) { diff --git a/contrib/globalsign/mgo/query.go b/contrib/globalsign/mgo/query.go index 0a14eabf1d..60ac4e4c73 100644 --- a/contrib/globalsign/mgo/query.go +++ b/contrib/globalsign/mgo/query.go @@ -22,7 +22,9 @@ type Query struct { // Iter invokes and traces Query.Iter func (q *Query) Iter() *Iter { + q.tags["createChild"] = "true" //flag to tell newChildSpanFromContext not to set span.kind span := newChildSpanFromContext(q.cfg, q.tags) + delete(q.tags, "createChild") // removes flag after creating span iter := q.Query.Iter() span.Finish() return &Iter{ @@ -97,7 +99,9 @@ func (q *Query) One(result interface{}) error { // Tail invokes and traces Query.Tail func (q *Query) Tail(timeout time.Duration) *Iter { + q.tags["createChild"] = "true" //flag to tell newChildSpanFromContext not to set span.kind span := newChildSpanFromContext(q.cfg, q.tags) + delete(q.tags, "createChild") // removes flag after creating span iter := q.Query.Tail(timeout) span.Finish() return &Iter{ diff --git a/contrib/go-chi/chi.v5/chi.go b/contrib/go-chi/chi.v5/chi.go index 2c9aedd565..8488ea3902 100644 --- a/contrib/go-chi/chi.v5/chi.go +++ b/contrib/go-chi/chi.v5/chi.go @@ -37,6 +37,8 @@ func Middleware(opts ...Option) func(next http.Handler) http.Handler { return } opts := spanOpts + opts = append(opts, tracer.Tag(ext.Component, "go-chi/chi.v5")) + opts = append(opts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } diff --git a/contrib/go-chi/chi.v5/chi_test.go b/contrib/go-chi/chi.v5/chi_test.go index 2212ebbc80..d5f77be8d4 100644 --- a/contrib/go-chi/chi.v5/chi_test.go +++ b/contrib/go-chi/chi.v5/chi_test.go @@ -68,6 +68,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal("go-chi/chi.v5", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } t.Run("response written", func(t *testing.T) { diff --git a/contrib/go-chi/chi/chi.go b/contrib/go-chi/chi/chi.go index 5acfb09c7e..c4b31c8680 100644 --- a/contrib/go-chi/chi/chi.go +++ b/contrib/go-chi/chi/chi.go @@ -37,6 +37,8 @@ func Middleware(opts ...Option) func(next http.Handler) http.Handler { return } opts := spanOpts + opts = append(opts, tracer.Tag(ext.Component, "go-chi/chi")) + opts = append(opts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } diff --git a/contrib/go-chi/chi/chi_test.go b/contrib/go-chi/chi/chi_test.go index 261322bb67..2b1af422e1 100644 --- a/contrib/go-chi/chi/chi_test.go +++ b/contrib/go-chi/chi/chi_test.go @@ -68,6 +68,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal("go-chi/chi", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } t.Run("response written", func(t *testing.T) { diff --git a/contrib/go-pg/pg.v10/pg_go.go b/contrib/go-pg/pg.v10/pg_go.go index a34f98a015..3866eda653 100644 --- a/contrib/go-pg/pg.v10/pg_go.go +++ b/contrib/go-pg/pg.v10/pg_go.go @@ -43,6 +43,8 @@ func (h *queryHook) BeforeQuery(ctx context.Context, qe *pg.QueryEvent) (context tracer.SpanType(ext.SpanTypeSQL), tracer.ResourceName(string(query)), tracer.ServiceName(h.cfg.serviceName), + tracer.Tag(ext.Component, "go-pg/pg.v10"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(h.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, h.cfg.analyticsRate)) diff --git a/contrib/go-pg/pg.v10/pg_go_test.go b/contrib/go-pg/pg.v10/pg_go_test.go index 90020cc2ff..92eac241a1 100644 --- a/contrib/go-pg/pg.v10/pg_go_test.go +++ b/contrib/go-pg/pg.v10/pg_go_test.go @@ -67,6 +67,9 @@ func TestSelect(t *testing.T) { assert.Equal(1, n) assert.Equal("go-pg", spans[0].OperationName()) assert.Equal("http.request", spans[1].OperationName()) + assert.Equal("go-pg/pg.v10", spans[0].Tags()[ext.Component]) + assert.Equal(ext.SpanKindClient, spans[0].Tags()[ext.SpanKind]) + } func TestServiceName(t *testing.T) { @@ -105,6 +108,8 @@ func TestServiceName(t *testing.T) { assert.Equal("http.request", spans[1].OperationName()) assert.Equal("gopg.db", spans[0].Tag(ext.ServiceName)) assert.Equal("fake-http-server", spans[1].Tag(ext.ServiceName)) + assert.Equal("go-pg/pg.v10", spans[0].Tags()[ext.Component]) + assert.Equal(ext.SpanKindClient, spans[0].Tags()[ext.SpanKind]) }) t.Run("global", func(t *testing.T) { @@ -145,6 +150,8 @@ func TestServiceName(t *testing.T) { assert.Equal("http.request", spans[1].OperationName()) assert.Equal("global-service", spans[0].Tag(ext.ServiceName)) assert.Equal("fake-http-server", spans[1].Tag(ext.ServiceName)) + assert.Equal("go-pg/pg.v10", spans[0].Tags()[ext.Component]) + assert.Equal(ext.SpanKindClient, spans[0].Tags()[ext.SpanKind]) }) t.Run("custom", func(t *testing.T) { @@ -182,6 +189,8 @@ func TestServiceName(t *testing.T) { assert.Equal("http.request", spans[1].OperationName()) assert.Equal("my-service-name", spans[0].Tag(ext.ServiceName)) assert.Equal("fake-http-server", spans[1].Tag(ext.ServiceName)) + assert.Equal("go-pg/pg.v10", spans[0].Tags()[ext.Component]) + assert.Equal(ext.SpanKindClient, spans[0].Tags()[ext.SpanKind]) }) } diff --git a/contrib/go-redis/redis.v7/redis.go b/contrib/go-redis/redis.v7/redis.go index 1f24572226..ab8bd72b78 100644 --- a/contrib/go-redis/redis.v7/redis.go +++ b/contrib/go-redis/redis.v7/redis.go @@ -108,6 +108,8 @@ func (ddh *datadogHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (con tracer.ResourceName(parts[0]), tracer.Tag("redis.raw_command", raw), tracer.Tag("redis.args_length", strconv.Itoa(length)), + tracer.Tag(ext.Component, "go-redis/redis.v7"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } opts = append(opts, ddh.additionalTags...) if !math.IsNaN(p.config.analyticsRate) { @@ -142,6 +144,8 @@ func (ddh *datadogHook) BeforeProcessPipeline(ctx context.Context, cmds []redis. tracer.Tag("redis.args_length", strconv.Itoa(length)), tracer.Tag(ext.ResourceName, raw), tracer.Tag("redis.pipeline_length", strconv.Itoa(len(cmds))), + tracer.Tag(ext.Component, "go-redis/redis.v7"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } opts = append(opts, ddh.additionalTags...) if !math.IsNaN(p.config.analyticsRate) { diff --git a/contrib/go-redis/redis.v7/redis_test.go b/contrib/go-redis/redis.v7/redis_test.go index 909d15ee78..a577f508bc 100644 --- a/contrib/go-redis/redis.v7/redis_test.go +++ b/contrib/go-redis/redis.v7/redis_test.go @@ -59,6 +59,8 @@ func TestClientEvalSha(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("evalsha", span.Tag(ext.ResourceName)) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestClient(t *testing.T) { @@ -81,6 +83,8 @@ func TestClient(t *testing.T) { assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("set test_key test_value: ", span.Tag("redis.raw_command")) assert.Equal("3", span.Tag("redis.args_length")) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestWrapClient(t *testing.T) { @@ -138,6 +142,8 @@ func TestWrapClient(t *testing.T) { assert.Equal("my-redis", span.Tag(ext.ServiceName)) assert.Equal("set test_key test_value: ", span.Tag("redis.raw_command")) assert.Equal("3", span.Tag("redis.args_length")) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } } @@ -225,6 +231,8 @@ func TestPipeline(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("1", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) mt.Reset() pipeline.Expire("pipeline_counter", time.Hour) @@ -242,6 +250,8 @@ func TestPipeline(t *testing.T) { assert.Equal("my-redis", span.Tag(ext.ServiceName)) assert.Equal("expire pipeline_counter 3600: false\nexpire pipeline_counter_1 60: false\n", span.Tag(ext.ResourceName)) assert.Equal("2", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestChildSpan(t *testing.T) { @@ -323,6 +333,8 @@ func TestError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6378", span.Tag(ext.TargetPort)) assert.Equal("get key: ", span.Tag("redis.raw_command")) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("nil", func(t *testing.T) { @@ -344,6 +356,8 @@ func TestError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("get non_existent_key: ", span.Tag("redis.raw_command")) + assert.Equal("go-redis/redis.v7", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/go-redis/redis.v8/redis.go b/contrib/go-redis/redis.v8/redis.go index e03f5ad799..3c7d2ce56d 100644 --- a/contrib/go-redis/redis.v8/redis.go +++ b/contrib/go-redis/redis.v8/redis.go @@ -108,6 +108,8 @@ func (ddh *datadogHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (con tracer.ServiceName(p.config.serviceName), tracer.ResourceName(raw[:strings.IndexByte(raw, ' ')]), tracer.Tag("redis.args_length", strconv.Itoa(length)), + tracer.Tag(ext.Component, "go-redis/redis.v8"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), ) if !p.config.skipRaw { opts = append(opts, tracer.Tag("redis.raw_command", raw)) @@ -143,6 +145,8 @@ func (ddh *datadogHook) BeforeProcessPipeline(ctx context.Context, cmds []redis. tracer.ResourceName(raw[:strings.IndexByte(raw, ' ')]), tracer.Tag("redis.args_length", strconv.Itoa(length)), tracer.Tag("redis.pipeline_length", strconv.Itoa(len(cmds))), + tracer.Tag(ext.Component, "go-redis/redis.v8"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), ) if !p.config.skipRaw { opts = append(opts, tracer.Tag("redis.raw_command", raw)) diff --git a/contrib/go-redis/redis.v8/redis_test.go b/contrib/go-redis/redis.v8/redis_test.go index 270a30334f..127c2f0911 100644 --- a/contrib/go-redis/redis.v8/redis_test.go +++ b/contrib/go-redis/redis.v8/redis_test.go @@ -105,6 +105,8 @@ func TestClientEvalSha(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("evalsha", span.Tag(ext.ResourceName)) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestClient(t *testing.T) { @@ -128,6 +130,8 @@ func TestClient(t *testing.T) { assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("set test_key test_value: ", span.Tag("redis.raw_command")) assert.Equal("3", span.Tag("redis.args_length")) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestWrapClient(t *testing.T) { @@ -186,6 +190,8 @@ func TestWrapClient(t *testing.T) { assert.Equal("my-redis", span.Tag(ext.ServiceName)) assert.Equal("set test_key test_value: ", span.Tag("redis.raw_command")) assert.Equal("3", span.Tag("redis.args_length")) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } } @@ -274,6 +280,8 @@ func TestPipeline(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("1", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) mt.Reset() pipeline.Expire(ctx, "pipeline_counter", time.Hour) @@ -291,6 +299,8 @@ func TestPipeline(t *testing.T) { assert.Equal("my-redis", span.Tag(ext.ServiceName)) assert.Equal("expire", span.Tag(ext.ResourceName)) assert.Equal("2", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestChildSpan(t *testing.T) { @@ -376,6 +386,8 @@ func TestError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6378", span.Tag(ext.TargetPort)) assert.Equal("get key: ", span.Tag("redis.raw_command")) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("nil", func(t *testing.T) { @@ -398,6 +410,8 @@ func TestError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("get non_existent_key: ", span.Tag("redis.raw_command")) + assert.Equal("go-redis/redis.v8", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/go-redis/redis/redis.go b/contrib/go-redis/redis/redis.go index ea8d8c50ee..54ee76661f 100644 --- a/contrib/go-redis/redis/redis.go +++ b/contrib/go-redis/redis/redis.go @@ -123,6 +123,8 @@ func (c *Pipeliner) execWithContext(ctx context.Context) ([]redis.Cmder, error) tracer.Tag(ext.TargetHost, p.host), tracer.Tag(ext.TargetPort, p.port), tracer.Tag("out.db", p.db), + tracer.Tag(ext.Component, "go-redis/redis"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) @@ -193,6 +195,8 @@ func createWrapperFromClient(tc *Client) func(oldProcess func(cmd redis.Cmder) e tracer.Tag("out.db", p.db), tracer.Tag("redis.raw_command", raw), tracer.Tag("redis.args_length", strconv.Itoa(length)), + tracer.Tag(ext.Component, "go-redis/redis"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) diff --git a/contrib/go-redis/redis/redis_test.go b/contrib/go-redis/redis/redis_test.go index f1073fd634..c8c30841b3 100644 --- a/contrib/go-redis/redis/redis_test.go +++ b/contrib/go-redis/redis/redis_test.go @@ -56,6 +56,8 @@ func TestClientEvalSha(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("evalsha", span.Tag(ext.ResourceName)) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } // https://github.com/DataDog/dd-trace-go/issues/387 @@ -99,6 +101,8 @@ func TestClient(t *testing.T) { assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("set test_key test_value: ", span.Tag("redis.raw_command")) assert.Equal("3", span.Tag("redis.args_length")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestPipeline(t *testing.T) { @@ -125,6 +129,8 @@ func TestPipeline(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("1", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) mt.Reset() pipeline.Expire("pipeline_counter", time.Hour) @@ -142,6 +148,8 @@ func TestPipeline(t *testing.T) { assert.Equal("my-redis", span.Tag(ext.ServiceName)) assert.Equal("expire pipeline_counter 3600: false\nexpire pipeline_counter_1 60: false\n", span.Tag(ext.ResourceName)) assert.Equal("2", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestPipelined(t *testing.T) { @@ -168,6 +176,8 @@ func TestPipelined(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("1", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) mt.Reset() _, err = client.Pipelined(func(p redis.Pipeliner) error { @@ -186,6 +196,8 @@ func TestPipelined(t *testing.T) { assert.Equal("my-redis", span.Tag(ext.ServiceName)) assert.Equal("expire pipeline_counter 3600: false\nexpire pipeline_counter_1 60: false\n", span.Tag(ext.ResourceName)) assert.Equal("2", span.Tag("redis.pipeline_length")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestChildSpan(t *testing.T) { @@ -268,6 +280,8 @@ func TestError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6378", span.Tag(ext.TargetPort)) assert.Equal("get key: ", span.Tag("redis.raw_command")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("nil", func(t *testing.T) { @@ -289,6 +303,8 @@ func TestError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("get non_existent_key: ", span.Tag("redis.raw_command")) + assert.Equal("go-redis/redis", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/go.mongodb.org/mongo-driver/mongo/mongo.go b/contrib/go.mongodb.org/mongo-driver/mongo/mongo.go index d1f3a67904..51583d260f 100644 --- a/contrib/go.mongodb.org/mongo-driver/mongo/mongo.go +++ b/contrib/go.mongodb.org/mongo-driver/mongo/mongo.go @@ -48,6 +48,8 @@ func (m *monitor) Started(ctx context.Context, evt *event.CommandStartedEvent) { tracer.Tag(ext.DBType, "mongo"), tracer.Tag(ext.PeerHostname, hostname), tracer.Tag(ext.PeerPort, port), + tracer.Tag(ext.Component, "go.mongodb.org/mongo-driver/mongo"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(m.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, m.cfg.analyticsRate)) diff --git a/contrib/go.mongodb.org/mongo-driver/mongo/mongo_test.go b/contrib/go.mongodb.org/mongo-driver/mongo/mongo_test.go index 779e64199a..d9eaa70066 100644 --- a/contrib/go.mongodb.org/mongo-driver/mongo/mongo_test.go +++ b/contrib/go.mongodb.org/mongo-driver/mongo/mongo_test.go @@ -76,6 +76,8 @@ func Test(t *testing.T) { assert.Contains(t, s.Tag("mongodb.query"), `"test-item":"test-value"`) assert.Equal(t, "test-database", s.Tag(ext.DBInstance)) assert.Equal(t, "mongo", s.Tag(ext.DBType)) + assert.Equal(t, "go.mongodb.org/mongo-driver/mongo", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s.Tag(ext.SpanKind)) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/gocql/gocql/gocql.go b/contrib/gocql/gocql/gocql.go index 11706dedaf..fd8d115dc8 100644 --- a/contrib/gocql/gocql/gocql.go +++ b/contrib/gocql/gocql/gocql.go @@ -102,6 +102,8 @@ func (tq *Query) newChildSpan(ctx context.Context) ddtrace.Span { tracer.ResourceName(p.config.resourceName), tracer.Tag(ext.CassandraPaginated, fmt.Sprintf("%t", p.paginated)), tracer.Tag(ext.CassandraKeyspace, p.keyspace), + tracer.Tag(ext.Component, "gocql/gocql"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) @@ -253,6 +255,8 @@ func (tb *Batch) newChildSpan(ctx context.Context) ddtrace.Span { tracer.ResourceName(p.config.resourceName), tracer.Tag(ext.CassandraConsistencyLevel, tb.Cons.String()), tracer.Tag(ext.CassandraKeyspace, tb.Keyspace()), + tracer.Tag(ext.Component, "gocql/gocql"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) diff --git a/contrib/gocql/gocql/gocql_test.go b/contrib/gocql/gocql/gocql_test.go index f8435d77af..cf41c03174 100644 --- a/contrib/gocql/gocql/gocql_test.go +++ b/contrib/gocql/gocql/gocql_test.go @@ -85,6 +85,8 @@ func TestErrorWrapper(t *testing.T) { assert.Equal(span.Tag(ext.ServiceName), "ServiceName") assert.Equal(span.Tag(ext.CassandraConsistencyLevel), "QUORUM") assert.Equal(span.Tag(ext.CassandraPaginated), "false") + assert.Equal(span.Tag(ext.Component), "gocql/gocql") + assert.Equal(span.Tag(ext.SpanKind), ext.SpanKindClient) if iter.Host() != nil { assert.Equal(span.Tag(ext.TargetPort), "9042") @@ -128,6 +130,8 @@ func TestChildWrapperSpan(t *testing.T) { assert.Equal(childSpan.OperationName(), ext.CassandraQuery) assert.Equal(childSpan.Tag(ext.ResourceName), "SELECT * FROM trace.person") assert.Equal(childSpan.Tag(ext.CassandraKeyspace), "trace") + assert.Equal(childSpan.Tag(ext.Component), "gocql/gocql") + assert.Equal(childSpan.Tag(ext.SpanKind), ext.SpanKindClient) if iter.Host() != nil { assert.Equal(childSpan.Tag(ext.TargetPort), "9042") assert.Equal(childSpan.Tag(ext.TargetHost), iter.Host().HostID()) @@ -305,6 +309,9 @@ func TestIterScanner(t *testing.T) { assert.Equal(childSpan.OperationName(), ext.CassandraQuery) assert.Equal(childSpan.Tag(ext.ResourceName), "SELECT * from trace.person") assert.Equal(childSpan.Tag(ext.CassandraKeyspace), "trace") + assert.Equal(childSpan.Tag(ext.Component), "gocql/gocql") + assert.Equal(childSpan.Tag(ext.SpanKind), ext.SpanKindClient) + } func TestBatch(t *testing.T) { @@ -347,4 +354,6 @@ func TestBatch(t *testing.T) { assert.Equal(childSpan.OperationName(), ext.CassandraBatch) assert.Equal(childSpan.Tag(ext.ResourceName), "BatchInsert") assert.Equal(childSpan.Tag(ext.CassandraKeyspace), "trace") + assert.Equal(childSpan.Tag(ext.Component), "gocql/gocql") + assert.Equal(childSpan.Tag(ext.SpanKind), ext.SpanKindClient) } diff --git a/contrib/gofiber/fiber.v2/fiber.go b/contrib/gofiber/fiber.v2/fiber.go index 1efed3dc1d..a836e18a94 100644 --- a/contrib/gofiber/fiber.v2/fiber.go +++ b/contrib/gofiber/fiber.v2/fiber.go @@ -48,6 +48,8 @@ func Middleware(opts ...Option) func(c *fiber.Ctx) error { opts = append(opts, tracer.ChildOf(spanctx)) } opts = append(opts, cfg.spanOpts...) + opts = append(opts, tracer.Tag(ext.Component, "gofiber/fiber.v2")) + opts = append(opts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) span, ctx := tracer.StartSpanFromContext(c.Context(), "http.request", opts...) defer span.Finish() diff --git a/contrib/gofiber/fiber.v2/fiber_test.go b/contrib/gofiber/fiber.v2/fiber_test.go index 13a1e61e32..6ec999d5ed 100644 --- a/contrib/gofiber/fiber.v2/fiber_test.go +++ b/contrib/gofiber/fiber.v2/fiber_test.go @@ -64,6 +64,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("/user/123", span.Tag(ext.HTTPURL)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gofiber/fiber.v2", span.Tag(ext.Component)) } t.Run("response", func(t *testing.T) { @@ -156,6 +158,8 @@ func TestCustomError(t *testing.T) { assert.Equal("foobar", span.Tag(ext.ServiceName)) assert.Equal("400", span.Tag(ext.HTTPCode)) assert.Equal(fiber.ErrBadRequest, span.Tag(ext.Error).(*fiber.Error)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) + assert.Equal("gofiber/fiber.v2", span.Tag(ext.Component)) } func TestUserContext(t *testing.T) { diff --git a/contrib/gomodule/redigo/redigo.go b/contrib/gomodule/redigo/redigo.go index f409fddef4..beb7f0e63e 100644 --- a/contrib/gomodule/redigo/redigo.go +++ b/contrib/gomodule/redigo/redigo.go @@ -149,6 +149,8 @@ func newChildSpan(ctx context.Context, p *params) ddtrace.Span { opts := []ddtrace.StartSpanOption{ tracer.SpanType(ext.SpanTypeRedis), tracer.ServiceName(p.config.serviceName), + tracer.Tag(ext.Component, "gomodule/redigo"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) diff --git a/contrib/gomodule/redigo/redigo_test.go b/contrib/gomodule/redigo/redigo_test.go index 7ba9423e08..230a180dc0 100644 --- a/contrib/gomodule/redigo/redigo_test.go +++ b/contrib/gomodule/redigo/redigo_test.go @@ -51,6 +51,8 @@ func TestClient(t *testing.T) { assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("SET 1 truck", span.Tag("redis.raw_command")) assert.Equal("2", span.Tag("redis.args_length")) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal("gomodule/redigo", span.Tag(ext.Component)) } func TestCommandError(t *testing.T) { @@ -74,6 +76,8 @@ func TestCommandError(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("NOT_A_COMMAND", span.Tag("redis.raw_command")) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal("gomodule/redigo", span.Tag(ext.Component)) } func TestConnectionError(t *testing.T) { @@ -116,6 +120,8 @@ func TestInheritance(t *testing.T) { assert.Equal(child.ParentID(), parent.SpanID()) assert.Equal(child.Tag(ext.TargetHost), "127.0.0.1") assert.Equal(child.Tag(ext.TargetPort), "6379") + assert.Equal(ext.SpanKindClient, child.Tag(ext.SpanKind)) + assert.Equal("gomodule/redigo", child.Tag(ext.Component)) } type stringifyTest struct{ A, B int } @@ -142,6 +148,8 @@ func TestCommandsToSring(t *testing.T) { assert.Equal("127.0.0.1", span.Tag(ext.TargetHost)) assert.Equal("6379", span.Tag(ext.TargetPort)) assert.Equal("SADD testSet a 0 1 2 [57, 8]", span.Tag("redis.raw_command")) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) + assert.Equal("gomodule/redigo", span.Tag(ext.Component)) } func TestPool(t *testing.T) { diff --git a/contrib/google.golang.org/api/api.go b/contrib/google.golang.org/api/api.go index 5eeea24396..b9b29a955f 100644 --- a/contrib/google.golang.org/api/api.go +++ b/contrib/google.golang.org/api/api.go @@ -56,6 +56,9 @@ func WrapRoundTripper(transport http.RoundTripper, options ...Option) http.Round if cfg.serviceName != "" { span.SetTag(ext.ServiceName, cfg.serviceName) } + span.SetTag(ext.Component, "google.golang.org/api") + span.SetTag(ext.SpanKind, ext.SpanKindClient) + }), } if !math.IsNaN(cfg.analyticsRate) { diff --git a/contrib/google.golang.org/api/api_test.go b/contrib/google.golang.org/api/api_test.go index c7b8192bb0..fdd1cb2a5e 100644 --- a/contrib/google.golang.org/api/api_test.go +++ b/contrib/google.golang.org/api/api_test.go @@ -60,6 +60,8 @@ func TestBooks(t *testing.T) { assert.Equal(t, "400", s0.Tag(ext.HTTPCode)) assert.Equal(t, "GET", s0.Tag(ext.HTTPMethod)) assert.Equal(t, svc.BasePath+"books/v1/users/montana.banana/bookshelves?alt=json&prettyPrint=false", s0.Tag(ext.HTTPURL)) + assert.Equal(t, "google.golang.org/api", s0.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s0.Tag(ext.SpanKind)) } func TestCivicInfo(t *testing.T) { @@ -83,6 +85,8 @@ func TestCivicInfo(t *testing.T) { assert.Equal(t, "400", s0.Tag(ext.HTTPCode)) assert.Equal(t, "GET", s0.Tag(ext.HTTPMethod)) assert.Equal(t, svc.BasePath+"civicinfo/v2/representatives?alt=json&prettyPrint=false", s0.Tag(ext.HTTPURL)) + assert.Equal(t, "google.golang.org/api", s0.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s0.Tag(ext.SpanKind)) } func TestURLShortener(t *testing.T) { @@ -108,6 +112,8 @@ func TestURLShortener(t *testing.T) { assert.Equal(t, "400", s0.Tag(ext.HTTPCode)) assert.Equal(t, "GET", s0.Tag(ext.HTTPMethod)) assert.Equal(t, "https://www.googleapis.com/urlshortener/v1/url/history?alt=json&prettyPrint=false", s0.Tag(ext.HTTPURL)) + assert.Equal(t, "google.golang.org/api", s0.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s0.Tag(ext.SpanKind)) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/google.golang.org/grpc.v12/grpc.go b/contrib/google.golang.org/grpc.v12/grpc.go index 5fb9e2c83b..db87dd40fa 100644 --- a/contrib/google.golang.org/grpc.v12/grpc.go +++ b/contrib/google.golang.org/grpc.v12/grpc.go @@ -38,6 +38,7 @@ func UnaryServerInterceptor(opts ...InterceptorOption) grpc.UnaryServerIntercept cfg.serviceName = svc } } + log.Debug("contrib/google.golang.org/grpc.v12: Configuring UnaryServerInterceptor: %#v", cfg) return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { span, ctx := startSpanFromContext(ctx, info.FullMethod, cfg.serviceName, cfg.analyticsRate) @@ -54,6 +55,8 @@ func startSpanFromContext(ctx context.Context, method, service string, rate floa tracer.Tag(tagMethod, method), tracer.SpanType(ext.AppTypeRPC), tracer.Measured(), + tracer.Tag(ext.Component, "google.golang.org/grpc.v12"), + tracer.Tag(ext.SpanKind, ext.SpanKindServer), } if !math.IsNaN(rate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, rate)) @@ -88,7 +91,10 @@ func UnaryClientInterceptor(opts ...InterceptorOption) grpc.UnaryClientIntercept if !math.IsNaN(cfg.analyticsRate) { spanopts = append(spanopts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } + spanopts = append(spanopts, tracer.Tag(ext.Component, "google.golang.org/grpc.v12")) + spanopts = append(spanopts, tracer.Tag(ext.SpanKind, ext.SpanKindClient)) span, ctx = tracer.StartSpanFromContext(ctx, "grpc.client", spanopts...) + md, ok := metadata.FromContext(ctx) if !ok { md = metadata.MD{} diff --git a/contrib/google.golang.org/grpc.v12/grpc_test.go b/contrib/google.golang.org/grpc.v12/grpc_test.go index cab3a4a386..7d06c24fe4 100644 --- a/contrib/google.golang.org/grpc.v12/grpc_test.go +++ b/contrib/google.golang.org/grpc.v12/grpc_test.go @@ -64,9 +64,13 @@ func TestClient(t *testing.T) { assert.Equal(clientSpan.Tag(ext.TargetPort), rig.port) assert.Equal(clientSpan.Tag(tagCode), codes.OK.String()) assert.Equal(clientSpan.TraceID(), rootSpan.TraceID()) + assert.Equal(clientSpan.Tag(ext.Component), "google.golang.org/grpc.v12") + assert.Equal(clientSpan.Tag(ext.SpanKind), ext.SpanKindClient) assert.Equal(serverSpan.Tag(ext.ServiceName), "grpc") assert.Equal(serverSpan.Tag(ext.ResourceName), "/grpc.Fixture/Ping") assert.Equal(serverSpan.TraceID(), rootSpan.TraceID()) + assert.Equal(serverSpan.Tag(ext.Component), "google.golang.org/grpc.v12") + assert.Equal(serverSpan.Tag(ext.SpanKind), ext.SpanKindServer) } func TestChild(t *testing.T) { @@ -111,6 +115,8 @@ func TestChild(t *testing.T) { assert.Equal(serverSpan.Tag(ext.ServiceName), "grpc") assert.Equal(serverSpan.Tag(ext.ResourceName), "/grpc.Fixture/Ping") assert.True(serverSpan.FinishTime().Sub(serverSpan.StartTime()) > 0) + assert.Equal(serverSpan.Tag(ext.Component), "google.golang.org/grpc.v12") + assert.Equal(serverSpan.Tag(ext.SpanKind), ext.SpanKindServer) } func TestPass(t *testing.T) { @@ -139,6 +145,8 @@ func TestPass(t *testing.T) { assert.Equal(s.Tag(ext.ResourceName), "/grpc.Fixture/Ping") assert.Equal(s.Tag(ext.SpanType), ext.AppTypeRPC) assert.True(s.FinishTime().Sub(s.StartTime()) > 0) + assert.Equal(s.Tag(ext.Component), "google.golang.org/grpc.v12") + assert.Equal(s.Tag(ext.SpanKind), ext.SpanKindServer) } // fixtureServer a dummy implemenation of our grpc fixtureServer. diff --git a/contrib/google.golang.org/grpc/client.go b/contrib/google.golang.org/grpc/client.go index 44e1af519a..949d0acda1 100644 --- a/contrib/google.golang.org/grpc/client.go +++ b/contrib/google.golang.org/grpc/client.go @@ -41,6 +41,7 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { cs.cfg.clientServiceName(), cs.cfg.startSpanOptions()..., ) + span.SetTag(ext.Component, "google.golang.org/grpc") if p, ok := peer.FromContext(cs.Context()); ok { setSpanTargetFromPeer(span, *p) } @@ -59,6 +60,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { cs.cfg.clientServiceName(), cs.cfg.startSpanOptions()..., ) + span.SetTag(ext.Component, "google.golang.org/grpc") if p, ok := peer.FromContext(cs.Context()); ok { setSpanTargetFromPeer(span, *p) } @@ -173,7 +175,9 @@ func doClientRequest( method, "grpc.client", cfg.clientServiceName(), - cfg.startSpanOptions()..., + cfg.startSpanOptions( + tracer.Tag(ext.Component, "google.golang.org/grpc"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient))..., ) if methodKind != "" { span.SetTag(tagMethodKind, methodKind) diff --git a/contrib/google.golang.org/grpc/grpc_test.go b/contrib/google.golang.org/grpc/grpc_test.go index e145e9ee1b..e6a3f9c4a3 100644 --- a/contrib/google.golang.org/grpc/grpc_test.go +++ b/contrib/google.golang.org/grpc/grpc_test.go @@ -102,12 +102,17 @@ func TestUnary(t *testing.T) { assert.Equal(clientSpan.Tag(tagCode), tt.wantCode.String()) assert.Equal(clientSpan.TraceID(), rootSpan.TraceID()) assert.Equal(clientSpan.Tag(tagMethodKind), methodKindUnary) + assert.Equal(clientSpan.Tag(ext.Component), "google.golang.org/grpc") + assert.Equal(clientSpan.Tag(ext.SpanKind), ext.SpanKindClient) assert.Equal(serverSpan.Tag(ext.ServiceName), "grpc") assert.Equal(serverSpan.Tag(ext.ResourceName), "/grpc.Fixture/Ping") assert.Equal(serverSpan.Tag(tagCode), tt.wantCode.String()) assert.Equal(serverSpan.TraceID(), rootSpan.TraceID()) assert.Equal(serverSpan.Tag(tagMethodKind), methodKindUnary) assert.Equal(serverSpan.Tag(tagRequest), tt.wantReqTag) + assert.Equal(serverSpan.Tag(ext.Component), "google.golang.org/grpc") + assert.Equal(serverSpan.Tag(ext.SpanKind), ext.SpanKindServer) + }) } } @@ -151,7 +156,6 @@ func TestStreaming(t *testing.T) { "expected service name to be grpc in span: %v", span) } - switch span.OperationName() { case "grpc.client": assert.Equal(t, "127.0.0.1", span.Tag(ext.TargetHost), @@ -178,6 +182,25 @@ func TestStreaming(t *testing.T) { assert.Equal(t, "/grpc.Fixture/StreamPing", span.Tag(tagMethodName), "expected grpc method name to be set in span: %v", span) } + + switch span.OperationName() { //checks spankind and component without fallthrough + case "grpc.client": + assert.Equal(t, "google.golang.org/grpc", span.Tag(ext.Component), + " expected component to be grpc-go in span %v", span) + assert.Equal(t, ext.SpanKindClient, span.Tag(ext.SpanKind), + " expected spankind to be client in span %v", span) + case "grpc.server": + assert.Equal(t, "google.golang.org/grpc", span.Tag(ext.Component), + " expected component to be grpc-go in span %v", span) + assert.Equal(t, ext.SpanKindServer, span.Tag(ext.SpanKind), + " expected spankind to be server in span %v, %v", span, span.OperationName()) + case "grpc.message": + assert.Equal(t, "google.golang.org/grpc", span.Tag(ext.Component), + " expected component to be grpc-go in span %v", span) + assert.NotContains(t, span.Tags(), ext.SpanKind, + " expected no spankind tag to be in span %v", span) + } + } } diff --git a/contrib/google.golang.org/grpc/server.go b/contrib/google.golang.org/grpc/server.go index 4bd255ed69..6c597cde8f 100644 --- a/contrib/google.golang.org/grpc/server.go +++ b/contrib/google.golang.org/grpc/server.go @@ -7,6 +7,7 @@ package grpc import ( "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" "gopkg.in/DataDog/dd-trace-go.v1/internal/appsec" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" @@ -48,6 +49,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { ss.cfg.serverServiceName(), ss.cfg.startSpanOptions(tracer.Measured())..., ) + span.SetTag(ext.Component, "google.golang.org/grpc") defer func() { finishWithError(span, err, ss.cfg) }() } err = ss.ServerStream.RecvMsg(m) @@ -65,6 +67,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { ss.cfg.serverServiceName(), ss.cfg.startSpanOptions(tracer.Measured())..., ) + span.SetTag(ext.Component, "google.golang.org/grpc") defer func() { finishWithError(span, err, ss.cfg) }() } err = ss.ServerStream.SendMsg(m) @@ -91,7 +94,9 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { info.FullMethod, "grpc.server", cfg.serverServiceName(), - cfg.startSpanOptions(tracer.Measured())..., + cfg.startSpanOptions(tracer.Measured(), + tracer.Tag(ext.Component, "google.golang.org/grpc"), + tracer.Tag(ext.SpanKind, ext.SpanKindServer))..., ) switch { case info.IsServerStream && info.IsClientStream: @@ -137,10 +142,11 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { info.FullMethod, "grpc.server", cfg.serverServiceName(), - cfg.startSpanOptions(tracer.Measured())..., + cfg.startSpanOptions(tracer.Measured(), + tracer.Tag(ext.Component, "google.golang.org/grpc"), + tracer.Tag(ext.SpanKind, ext.SpanKindServer))..., ) span.SetTag(tagMethodKind, methodKindUnary) - if cfg.withMetadataTags { md, _ := metadata.FromIncomingContext(ctx) // nil is ok for k, v := range md { diff --git a/contrib/gopkg.in/jinzhu/gorm.v1/gorm.go b/contrib/gopkg.in/jinzhu/gorm.v1/gorm.go index da700682ac..73f6a90597 100644 --- a/contrib/gopkg.in/jinzhu/gorm.v1/gorm.go +++ b/contrib/gopkg.in/jinzhu/gorm.v1/gorm.go @@ -122,6 +122,7 @@ func after(scope *gorm.Scope, operationName string) { tracer.ServiceName(cfg.serviceName), tracer.SpanType(ext.SpanTypeSQL), tracer.ResourceName(scope.SQL), + tracer.Tag(ext.Component, "gopkg.in/jinzhu/gorm.v1"), } if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) diff --git a/contrib/gopkg.in/jinzhu/gorm.v1/gorm_test.go b/contrib/gopkg.in/jinzhu/gorm.v1/gorm_test.go index 168013b74f..cd0350f78c 100644 --- a/contrib/gopkg.in/jinzhu/gorm.v1/gorm_test.go +++ b/contrib/gopkg.in/jinzhu/gorm.v1/gorm_test.go @@ -154,6 +154,7 @@ func TestCallbacks(t *testing.T) { assert.Equal( `INSERT INTO "products" ("created_at","updated_at","deleted_at","code","price") VALUES ($1,$2,$3,$4,$5) RETURNING "products"."id"`, span.Tag(ext.ResourceName)) + assert.Equal("gopkg.in/jinzhu/gorm.v1", span.Tag(ext.Component)) }) t.Run("query", func(t *testing.T) { @@ -177,6 +178,7 @@ func TestCallbacks(t *testing.T) { assert.Equal( `SELECT * FROM "products" WHERE "products"."deleted_at" IS NULL AND ((code = $1)) ORDER BY "products"."id" ASC LIMIT 1`, span.Tag(ext.ResourceName)) + assert.Equal("gopkg.in/jinzhu/gorm.v1", span.Tag(ext.Component)) }) t.Run("update", func(t *testing.T) { @@ -201,6 +203,7 @@ func TestCallbacks(t *testing.T) { assert.Equal( `UPDATE "products" SET "price" = $1, "updated_at" = $2 WHERE "products"."deleted_at" IS NULL AND "products"."id" = $3`, span.Tag(ext.ResourceName)) + assert.Equal("gopkg.in/jinzhu/gorm.v1", span.Tag(ext.Component)) }) t.Run("delete", func(t *testing.T) { @@ -225,6 +228,7 @@ func TestCallbacks(t *testing.T) { assert.Equal( `UPDATE "products" SET "deleted_at"=$1 WHERE "products"."deleted_at" IS NULL AND "products"."id" = $2`, span.Tag(ext.ResourceName)) + assert.Equal("gopkg.in/jinzhu/gorm.v1", span.Tag(ext.Component)) }) } @@ -370,6 +374,7 @@ func TestCustomTags(t *testing.T) { assert.Equal( `INSERT INTO "products" ("created_at","updated_at","deleted_at","code","price") VALUES ($1,$2,$3,$4,$5) RETURNING "products"."id"`, span.Tag(ext.ResourceName)) + assert.Equal("gopkg.in/jinzhu/gorm.v1", span.Tag(ext.Component)) } func TestError(t *testing.T) { diff --git a/contrib/gorilla/mux/mux.go b/contrib/gorilla/mux/mux.go index c1653dc7c0..fc5f90a427 100644 --- a/contrib/gorilla/mux/mux.go +++ b/contrib/gorilla/mux/mux.go @@ -10,12 +10,13 @@ import ( "net/http" "strings" + "github.com/gorilla/mux" + httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" - - "github.com/gorilla/mux" ) // Router registers routes to be matched and dispatches a handler. @@ -99,6 +100,9 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { route, _ = match.Route.GetPathTemplate() } spanopts = append(spanopts, r.config.spanOpts...) + spanopts = append(spanopts, tracer.Tag(ext.Component, "gorilla/mux")) + spanopts = append(spanopts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + if r.config.headerTags { spanopts = append(spanopts, headerTagsFromRequest(req)) } diff --git a/contrib/gorilla/mux/mux_test.go b/contrib/gorilla/mux/mux_test.go index e032ae696f..48016c72de 100644 --- a/contrib/gorilla/mux/mux_test.go +++ b/contrib/gorilla/mux/mux_test.go @@ -82,6 +82,9 @@ func TestHttpTracer(t *testing.T) { assert.Equal(ht.method, s.Tag(ext.HTTPMethod)) assert.Equal("http://example.com"+ht.url, s.Tag(ext.HTTPURL)) assert.Equal(ht.resourceName, s.Tag(ext.ResourceName)) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) + assert.Equal("gorilla/mux", s.Tag(ext.Component)) + if ht.errorStr != "" { assert.Equal(ht.errorStr, s.Tag(ext.Error).(error).Error()) } diff --git a/contrib/gorm.io/gorm.v1/gorm.go b/contrib/gorm.io/gorm.v1/gorm.go index d6d3c07f83..5800d21451 100644 --- a/contrib/gorm.io/gorm.v1/gorm.go +++ b/contrib/gorm.io/gorm.v1/gorm.go @@ -115,6 +115,7 @@ func after(db *gorm.DB, operationName string, cfg *config) { tracer.ServiceName(cfg.serviceName), tracer.SpanType(ext.SpanTypeSQL), tracer.ResourceName(db.Statement.SQL.String()), + tracer.Tag(ext.Component, "gorm.io/gorm.v1"), } if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) diff --git a/contrib/gorm.io/gorm.v1/gorm_test.go b/contrib/gorm.io/gorm.v1/gorm_test.go index c2d7aa12c3..361882c29f 100644 --- a/contrib/gorm.io/gorm.v1/gorm_test.go +++ b/contrib/gorm.io/gorm.v1/gorm_test.go @@ -199,6 +199,7 @@ func TestCallbacks(t *testing.T) { a.Equal("gorm.create", span.OperationName()) a.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) a.Equal(queryText, span.Tag(ext.ResourceName)) + a.Equal("gorm.io/gorm.v1", span.Tag(ext.Component)) }) t.Run("query", func(t *testing.T) { @@ -224,6 +225,7 @@ func TestCallbacks(t *testing.T) { a.Equal("gorm.query", span.OperationName()) a.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) a.Equal(queryText, span.Tag(ext.ResourceName)) + a.Equal("gorm.io/gorm.v1", span.Tag(ext.Component)) }) t.Run("update", func(t *testing.T) { @@ -250,6 +252,7 @@ func TestCallbacks(t *testing.T) { a.Equal("gorm.update", span.OperationName()) a.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) a.Equal(queryText, span.Tag(ext.ResourceName)) + a.Equal("gorm.io/gorm.v1", span.Tag(ext.Component)) }) t.Run("delete", func(t *testing.T) { @@ -276,6 +279,7 @@ func TestCallbacks(t *testing.T) { a.Equal("gorm.delete", span.OperationName()) a.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) a.Equal(queryText, span.Tag(ext.ResourceName)) + a.Equal("gorm.io/gorm.v1", span.Tag(ext.Component)) }) } diff --git a/contrib/graph-gophers/graphql-go/graphql.go b/contrib/graph-gophers/graphql-go/graphql.go index 76dd55240b..35ed484b25 100644 --- a/contrib/graph-gophers/graphql-go/graphql.go +++ b/contrib/graph-gophers/graphql-go/graphql.go @@ -47,6 +47,7 @@ func (t *Tracer) TraceQuery(ctx context.Context, queryString string, operationNa tracer.ServiceName(t.cfg.serviceName), tracer.Tag(tagGraphqlQuery, queryString), tracer.Tag(tagGraphqlOperationName, operationName), + tracer.Tag(ext.Component, "graph-gophers/graphql-go"), tracer.Measured(), } if !math.IsNaN(t.cfg.analyticsRate) { @@ -77,6 +78,7 @@ func (t *Tracer) TraceField(ctx context.Context, label string, typeName string, tracer.ServiceName(t.cfg.serviceName), tracer.Tag(tagGraphqlField, fieldName), tracer.Tag(tagGraphqlType, typeName), + tracer.Tag(ext.Component, "graph-gophers/graphql-go"), tracer.Measured(), } if !math.IsNaN(t.cfg.analyticsRate) { diff --git a/contrib/graph-gophers/graphql-go/graphql_test.go b/contrib/graph-gophers/graphql-go/graphql_test.go index 6b3d5b4676..98ef627dba 100644 --- a/contrib/graph-gophers/graphql-go/graphql_test.go +++ b/contrib/graph-gophers/graphql-go/graphql_test.go @@ -76,6 +76,7 @@ func Test(t *testing.T) { assert.Equal(t, "Query", s.Tag(tagGraphqlType)) assert.Equal(t, "graphql.field", s.OperationName()) assert.Equal(t, "graphql.field", s.Tag(ext.ResourceName)) + assert.Equal(t, "graph-gophers/graphql-go", s.Tag(ext.Component)) } { @@ -86,6 +87,8 @@ func Test(t *testing.T) { assert.Equal(t, "Query", s.Tag(tagGraphqlType)) assert.Equal(t, "graphql.field", s.OperationName()) assert.Equal(t, "graphql.field", s.Tag(ext.ResourceName)) + assert.Equal(t, "graph-gophers/graphql-go", s.Tag(ext.Component)) + } { @@ -96,6 +99,8 @@ func Test(t *testing.T) { assert.Equal(t, "test-graphql-service", s.Tag(ext.ServiceName)) assert.Equal(t, "graphql.request", s.OperationName()) assert.Equal(t, "graphql.request", s.Tag(ext.ResourceName)) + assert.Equal(t, "graph-gophers/graphql-go", s.Tag(ext.Component)) + } }) @@ -117,6 +122,8 @@ func Test(t *testing.T) { assert.Equal(t, "Query", s.Tag(tagGraphqlType)) assert.Equal(t, "graphql.field", s.OperationName()) assert.Equal(t, "graphql.field", s.Tag(ext.ResourceName)) + assert.Equal(t, "graph-gophers/graphql-go", s.Tag(ext.Component)) + } { @@ -127,6 +134,8 @@ func Test(t *testing.T) { assert.Equal(t, "test-graphql-service", s.Tag(ext.ServiceName)) assert.Equal(t, "graphql.request", s.OperationName()) assert.Equal(t, "graphql.request", s.Tag(ext.ResourceName)) + assert.Equal(t, "graph-gophers/graphql-go", s.Tag(ext.Component)) + } }) } diff --git a/contrib/hashicorp/consul/consul.go b/contrib/hashicorp/consul/consul.go index e1ff72d33d..d94b7ad8e4 100644 --- a/contrib/hashicorp/consul/consul.go +++ b/contrib/hashicorp/consul/consul.go @@ -70,6 +70,8 @@ func (k *KV) startSpan(resourceName string, key string) ddtrace.Span { tracer.ServiceName(k.config.serviceName), tracer.SpanType(ext.SpanTypeConsul), tracer.Tag("consul.key", key), + tracer.Tag(ext.Component, "hashicorp/consul"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(k.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, k.config.analyticsRate)) diff --git a/contrib/hashicorp/consul/consul_test.go b/contrib/hashicorp/consul/consul_test.go index b14f20a921..56cb505f70 100644 --- a/contrib/hashicorp/consul/consul_test.go +++ b/contrib/hashicorp/consul/consul_test.go @@ -98,6 +98,8 @@ func TestKV(t *testing.T) { assert.Equal(ext.SpanTypeConsul, span.Tag(ext.SpanType)) assert.Equal("consul", span.Tag(ext.ServiceName)) assert.Equal(key, span.Tag("consul.key")) + assert.Equal("hashicorp/consul", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } } diff --git a/contrib/hashicorp/vault/vault.go b/contrib/hashicorp/vault/vault.go index 0e78d9131b..16d370df52 100644 --- a/contrib/hashicorp/vault/vault.go +++ b/contrib/hashicorp/vault/vault.go @@ -56,6 +56,8 @@ func WrapHTTPClient(c *http.Client, opts ...Option) *http.Client { s.SetTag(ext.HTTPMethod, r.Method) s.SetTag(ext.ResourceName, r.Method+" "+r.URL.Path) s.SetTag(ext.SpanType, ext.SpanTypeHTTP) + s.SetTag(ext.Component, "hashicorp/vault") + s.SetTag(ext.SpanKind, ext.SpanKindClient) if ns := r.Header.Get(consts.NamespaceHeaderName); ns != "" { s.SetTag("vault.namespace", ns) } diff --git a/contrib/hashicorp/vault/vault_test.go b/contrib/hashicorp/vault/vault_test.go index 731364a013..66e0ea2043 100644 --- a/contrib/hashicorp/vault/vault_test.go +++ b/contrib/hashicorp/vault/vault_test.go @@ -134,6 +134,8 @@ func testMountReadWrite(c *api.Client, t *testing.T) { assert.Nil(span.Tag(ext.Error)) assert.Nil(span.Tag(ext.ErrorMsg)) assert.Nil(span.Tag("vault.namespace")) + assert.Equal("hashicorp/vault", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("write", func(t *testing.T) { @@ -160,6 +162,8 @@ func testMountReadWrite(c *api.Client, t *testing.T) { assert.Nil(span.Tag(ext.Error)) assert.Nil(span.Tag(ext.ErrorMsg)) assert.Nil(span.Tag("vault.namespace")) + assert.Equal("hashicorp/vault", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("read", func(t *testing.T) { @@ -193,6 +197,8 @@ func testMountReadWrite(c *api.Client, t *testing.T) { assert.Nil(span.Tag(ext.Error)) assert.Nil(span.Tag(ext.ErrorMsg)) assert.Nil(span.Tag("vault.namespace")) + assert.Equal("hashicorp/vault", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } @@ -229,6 +235,8 @@ func TestReadError(t *testing.T) { assert.Equal(true, span.Tag(ext.Error)) assert.NotNil(span.Tag(ext.ErrorMsg)) assert.Nil(span.Tag("vault.namespace")) + assert.Equal("hashicorp/vault", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestNamespace(t *testing.T) { @@ -269,6 +277,8 @@ func TestNamespace(t *testing.T) { assert.Nil(span.Tag(ext.Error)) assert.Nil(span.Tag(ext.ErrorMsg)) assert.Equal(namespace, span.Tag("vault.namespace")) + assert.Equal("hashicorp/vault", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("read", func(t *testing.T) { @@ -300,6 +310,8 @@ func TestNamespace(t *testing.T) { assert.Nil(span.Tag(ext.Error)) assert.Nil(span.Tag(ext.ErrorMsg)) assert.Equal(namespace, span.Tag("vault.namespace")) + assert.Equal("hashicorp/vault", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } diff --git a/contrib/jinzhu/gorm/gorm.go b/contrib/jinzhu/gorm/gorm.go index 90043dcd8b..3f4f98d9a9 100644 --- a/contrib/jinzhu/gorm/gorm.go +++ b/contrib/jinzhu/gorm/gorm.go @@ -125,6 +125,7 @@ func after(scope *gorm.Scope, operationName string) { tracer.ServiceName(cfg.serviceName), tracer.SpanType(ext.SpanTypeSQL), tracer.ResourceName(scope.SQL), + tracer.Tag(ext.Component, "jinzhu/gorm"), } if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) diff --git a/contrib/jinzhu/gorm/gorm_test.go b/contrib/jinzhu/gorm/gorm_test.go index 2caad8861f..2c7b07f812 100644 --- a/contrib/jinzhu/gorm/gorm_test.go +++ b/contrib/jinzhu/gorm/gorm_test.go @@ -156,6 +156,7 @@ func TestCallbacks(t *testing.T) { assert.Equal("gorm.create", span.OperationName()) assert.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) assert.Equal(queryText, span.Tag(ext.ResourceName)) + assert.Equal("jinzhu/gorm", span.Tag(ext.Component)) }) t.Run("query", func(t *testing.T) { @@ -181,6 +182,7 @@ func TestCallbacks(t *testing.T) { assert.Equal("gorm.query", span.OperationName()) assert.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) assert.Equal(queryText, span.Tag(ext.ResourceName)) + assert.Equal("jinzhu/gorm", span.Tag(ext.Component)) }) t.Run("update", func(t *testing.T) { @@ -207,6 +209,7 @@ func TestCallbacks(t *testing.T) { assert.Equal("gorm.update", span.OperationName()) assert.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) assert.Equal(queryText, span.Tag(ext.ResourceName)) + assert.Equal("jinzhu/gorm", span.Tag(ext.Component)) }) t.Run("delete", func(t *testing.T) { @@ -233,6 +236,7 @@ func TestCallbacks(t *testing.T) { assert.Equal("gorm.delete", span.OperationName()) assert.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) assert.Equal(queryText, span.Tag(ext.ResourceName)) + assert.Equal("jinzhu/gorm", span.Tag(ext.Component)) }) } @@ -380,6 +384,7 @@ func TestCustomTags(t *testing.T) { assert.Equal(ext.SpanTypeSQL, span.Tag(ext.SpanType)) assert.Equal("L1212", span.Tag("custom_tag")) assert.Equal(queryText, span.Tag(ext.ResourceName)) + assert.Equal("jinzhu/gorm", span.Tag(ext.Component)) } func TestError(t *testing.T) { diff --git a/contrib/julienschmidt/httprouter/httprouter.go b/contrib/julienschmidt/httprouter/httprouter.go index e4b5e493cc..f45382ad0d 100644 --- a/contrib/julienschmidt/httprouter/httprouter.go +++ b/contrib/julienschmidt/httprouter/httprouter.go @@ -48,6 +48,10 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { route = strings.Replace(route, param.Value, ":"+param.Key, 1) } resource := req.Method + " " + route + + r.config.spanOpts = append(r.config.spanOpts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + r.config.spanOpts = append(r.config.spanOpts, tracer.Tag(ext.Component, "julienschmidt/httprouter")) + httptrace.TraceAndServe(r.Router, w, req, &httptrace.ServeConfig{ Service: r.config.serviceName, Resource: resource, diff --git a/contrib/julienschmidt/httprouter/httprouter_test.go b/contrib/julienschmidt/httprouter/httprouter_test.go index 17cf3a4b41..760642b971 100644 --- a/contrib/julienschmidt/httprouter/httprouter_test.go +++ b/contrib/julienschmidt/httprouter/httprouter_test.go @@ -44,6 +44,8 @@ func TestHttpTracer200(t *testing.T) { assert.Equal("http://example.com"+url, s.Tag(ext.HTTPURL)) assert.Equal("testvalue", s.Tag("testkey")) assert.Equal(nil, s.Tag(ext.Error)) + assert.Equal("julienschmidt/httprouter", s.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) } func TestHttpTracer500(t *testing.T) { @@ -71,6 +73,8 @@ func TestHttpTracer500(t *testing.T) { assert.Equal("http://example.com"+url, s.Tag(ext.HTTPURL)) assert.Equal("testvalue", s.Tag("testkey")) assert.Equal("500: Internal Server Error", s.Tag(ext.Error).(error).Error()) + assert.Equal("julienschmidt/httprouter", s.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/k8s.io/client-go/kubernetes/kubernetes.go b/contrib/k8s.io/client-go/kubernetes/kubernetes.go index 055a654f0f..85f2194d6e 100644 --- a/contrib/k8s.io/client-go/kubernetes/kubernetes.go +++ b/contrib/k8s.io/client-go/kubernetes/kubernetes.go @@ -41,6 +41,8 @@ func WrapRoundTripper(rt http.RoundTripper) http.RoundTripper { func wrapRoundTripperWithOptions(rt http.RoundTripper, opts ...httptrace.RoundTripperOption) http.RoundTripper { opts = append(opts, httptrace.WithBefore(func(req *http.Request, span ddtrace.Span) { span.SetTag(ext.ResourceName, RequestToResource(req.Method, req.URL.Path)) + span.SetTag(ext.Component, "k8s.io/client-go/kubernetes") + span.SetTag(ext.SpanKind, ext.SpanKindClient) traceID := span.Context().TraceID() if traceID == 0 { // tracer is not running diff --git a/contrib/k8s.io/client-go/kubernetes/kubernetes_test.go b/contrib/k8s.io/client-go/kubernetes/kubernetes_test.go index be8dfa1dfb..41211fa45e 100644 --- a/contrib/k8s.io/client-go/kubernetes/kubernetes_test.go +++ b/contrib/k8s.io/client-go/kubernetes/kubernetes_test.go @@ -87,6 +87,8 @@ func TestKubernetes(t *testing.T) { auditID, ok := span.Tag("kubernetes.audit_id").(string) assert.True(t, ok) assert.True(t, len(auditID) > 0) + assert.Equal(t, "k8s.io/client-go/kubernetes", span.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, span.Tag(ext.SpanKind)) } } diff --git a/contrib/labstack/echo.v4/echotrace.go b/contrib/labstack/echo.v4/echotrace.go index aa27fde991..6afa2562bc 100644 --- a/contrib/labstack/echo.v4/echotrace.go +++ b/contrib/labstack/echo.v4/echotrace.go @@ -30,6 +30,8 @@ func Middleware(opts ...Option) echo.MiddlewareFunc { log.Debug("contrib/labstack/echo.v4: Configuring Middleware: %#v", cfg) spanOpts := []ddtrace.StartSpanOption{ tracer.ServiceName(cfg.serviceName), + tracer.Tag(ext.Component, "labstack/echo.v4"), + tracer.Tag(ext.SpanKind, ext.SpanKindServer), } return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { diff --git a/contrib/labstack/echo.v4/echotrace_test.go b/contrib/labstack/echo.v4/echotrace_test.go index dce358d4b8..52b2345d4f 100644 --- a/contrib/labstack/echo.v4/echotrace_test.go +++ b/contrib/labstack/echo.v4/echotrace_test.go @@ -89,6 +89,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal(root.Context().SpanID(), span.ParentID()) + assert.Equal("labstack/echo.v4", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) } @@ -136,6 +138,8 @@ func TestTraceAnalytics(t *testing.T) { assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal(1.0, span.Tag(ext.EventSampleRate)) assert.Equal(root.Context().SpanID(), span.ParentID()) + assert.Equal("labstack/echo.v4", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) } @@ -176,6 +180,8 @@ func TestError(t *testing.T) { assert.Equal("foobar", span.Tag(ext.ServiceName)) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) + assert.Equal("labstack/echo.v4", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestErrorHandling(t *testing.T) { @@ -214,6 +220,8 @@ func TestErrorHandling(t *testing.T) { assert.Equal("foobar", span.Tag(ext.ServiceName)) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) + assert.Equal("labstack/echo.v4", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestGetSpanNotInstrumented(t *testing.T) { @@ -270,6 +278,8 @@ func TestNoDebugStack(t *testing.T) { span := spans[0] assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) assert.Equal("", span.Tag(ext.ErrorStack)) + assert.Equal("labstack/echo.v4", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestIgnoreRequestFunc(t *testing.T) { diff --git a/contrib/labstack/echo/echotrace.go b/contrib/labstack/echo/echotrace.go index 3d56d7ccc3..5a827a437a 100644 --- a/contrib/labstack/echo/echotrace.go +++ b/contrib/labstack/echo/echotrace.go @@ -28,6 +28,8 @@ func Middleware(opts ...Option) echo.MiddlewareFunc { log.Debug("contrib/labstack/echo: Configuring Middleware: %#v", cfg) spanOpts := []ddtrace.StartSpanOption{ tracer.ServiceName(cfg.serviceName), + tracer.Tag(ext.Component, "labstack/echo"), + tracer.Tag(ext.SpanKind, ext.SpanKindServer), } return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { diff --git a/contrib/labstack/echo/echotrace_test.go b/contrib/labstack/echo/echotrace_test.go index c23fe45170..6f9b098798 100644 --- a/contrib/labstack/echo/echotrace_test.go +++ b/contrib/labstack/echo/echotrace_test.go @@ -84,6 +84,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal(root.Context().SpanID(), span.ParentID()) + assert.Equal("labstack/echo", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) } @@ -131,6 +133,8 @@ func TestTraceAnalytics(t *testing.T) { assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal(1.0, span.Tag(ext.EventSampleRate)) assert.Equal(root.Context().SpanID(), span.ParentID()) + assert.Equal("labstack/echo", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) } @@ -171,6 +175,8 @@ func TestError(t *testing.T) { assert.Equal("foobar", span.Tag(ext.ServiceName)) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) + assert.Equal("labstack/echo", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestErrorHandling(t *testing.T) { @@ -209,6 +215,8 @@ func TestErrorHandling(t *testing.T) { assert.Equal("foobar", span.Tag(ext.ServiceName)) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) + assert.Equal("labstack/echo", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestGetSpanNotInstrumented(t *testing.T) { @@ -265,4 +273,6 @@ func TestNoDebugStack(t *testing.T) { span := spans[0] assert.Equal(wantErr.Error(), span.Tag(ext.Error).(error).Error()) assert.Equal("", span.Tag(ext.ErrorStack)) + assert.Equal("labstack/echo", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } diff --git a/contrib/miekg/dns/dns.go b/contrib/miekg/dns/dns.go index a1b7ea3ce5..f055b61233 100644 --- a/contrib/miekg/dns/dns.go +++ b/contrib/miekg/dns/dns.go @@ -114,5 +114,7 @@ func startSpan(ctx context.Context, opcode int) (ddtrace.Span, context.Context) return tracer.StartSpanFromContext(ctx, "dns.request", tracer.ServiceName("dns"), tracer.ResourceName(dns.OpcodeToString[opcode]), - tracer.SpanType(ext.SpanTypeDNS)) + tracer.SpanType(ext.SpanTypeDNS), + tracer.Tag(ext.Component, "miekg/dns"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient)) } diff --git a/contrib/miekg/dns/dns_test.go b/contrib/miekg/dns/dns_test.go index 26a521ebf0..96d308049f 100644 --- a/contrib/miekg/dns/dns_test.go +++ b/contrib/miekg/dns/dns_test.go @@ -61,6 +61,8 @@ func TestDNS(t *testing.T) { assert.Equal(t, "dns", s.Tag(ext.SpanType)) assert.Equal(t, "dns", s.Tag(ext.ServiceName)) assert.Equal(t, "QUERY", s.Tag(ext.ResourceName)) + assert.Equal(t, "miekg/dns", s.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, s.Tag(ext.SpanKind)) } } diff --git a/contrib/net/http/http.go b/contrib/net/http/http.go index be24bfa57e..b4f339a8bf 100644 --- a/contrib/net/http/http.go +++ b/contrib/net/http/http.go @@ -9,6 +9,9 @@ package http // import "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http" import ( "net/http" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" + + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" ) @@ -48,6 +51,10 @@ func (mux *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { if resource == "" { resource = r.Method + " " + route } + + mux.cfg.spanOpts = append(mux.cfg.spanOpts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + mux.cfg.spanOpts = append(mux.cfg.spanOpts, tracer.Tag(ext.Component, "net/http")) + TraceAndServe(mux.ServeMux, w, r, &ServeConfig{ Service: mux.cfg.serviceName, Resource: resource, @@ -73,6 +80,10 @@ func WrapHandler(h http.Handler, service, resource string, opts ...Option) http. if r := cfg.resourceNamer(req); r != "" { resource = r } + + cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.Component, "net/http")) + TraceAndServe(h, w, req, &ServeConfig{ Service: service, Resource: resource, diff --git a/contrib/net/http/http_test.go b/contrib/net/http/http_test.go index 71934da485..4ca448b5ff 100644 --- a/contrib/net/http/http_test.go +++ b/contrib/net/http/http_test.go @@ -43,6 +43,8 @@ func TestHttpTracer200(t *testing.T) { assert.Equal("http://example.com"+url, s.Tag(ext.HTTPURL)) assert.Equal(nil, s.Tag(ext.Error)) assert.Equal("bar", s.Tag("foo")) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) + assert.Equal("net/http", s.Tag(ext.Component)) } func TestHttpTracer500(t *testing.T) { @@ -71,6 +73,8 @@ func TestHttpTracer500(t *testing.T) { assert.Equal("http://example.com"+url, s.Tag(ext.HTTPURL)) assert.Equal("500: Internal Server Error", s.Tag(ext.Error).(error).Error()) assert.Equal("bar", s.Tag("foo")) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) + assert.Equal("net/http", s.Tag(ext.Component)) } func TestWrapHandler200(t *testing.T) { @@ -101,6 +105,8 @@ func TestWrapHandler200(t *testing.T) { assert.Equal("http://example.com"+url, s.Tag(ext.HTTPURL)) assert.Equal(nil, s.Tag(ext.Error)) assert.Equal("bar", s.Tag("foo")) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) + assert.Equal("net/http", s.Tag(ext.Component)) } func TestNoStack(t *testing.T) { @@ -122,6 +128,8 @@ func TestNoStack(t *testing.T) { s := spans[0] assert.EqualError(spans[0].Tags()[ext.Error].(error), "500: Internal Server Error") assert.Equal("", s.Tags()[ext.ErrorStack]) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) + assert.Equal("net/http", s.Tag(ext.Component)) } func TestServeMuxUsesResourceNamer(t *testing.T) { @@ -154,6 +162,8 @@ func TestServeMuxUsesResourceNamer(t *testing.T) { assert.Equal("http://example.com"+url, s.Tag(ext.HTTPURL)) assert.Equal(nil, s.Tag(ext.Error)) assert.Equal("bar", s.Tag("foo")) + assert.Equal(ext.SpanKindServer, s.Tag(ext.SpanKind)) + assert.Equal("net/http", s.Tag(ext.Component)) } func TestAnalyticsSettings(t *testing.T) { diff --git a/contrib/net/http/roundtripper.go b/contrib/net/http/roundtripper.go index 40a6c761f0..13bff8c5dd 100644 --- a/contrib/net/http/roundtripper.go +++ b/contrib/net/http/roundtripper.go @@ -32,6 +32,8 @@ func (rt *roundTripper) RoundTrip(req *http.Request) (res *http.Response, err er tracer.ResourceName(resourceName), tracer.Tag(ext.HTTPMethod, req.Method), tracer.Tag(ext.HTTPURL, req.URL.String()), + tracer.Tag(ext.Component, "net/http"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(rt.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, rt.cfg.analyticsRate)) diff --git a/contrib/net/http/roundtripper_test.go b/contrib/net/http/roundtripper_test.go index 0ec1401527..1043aa0d3f 100644 --- a/contrib/net/http/roundtripper_test.go +++ b/contrib/net/http/roundtripper_test.go @@ -79,6 +79,8 @@ func TestRoundTripper(t *testing.T) { assert.Equal(t, s.URL+"/hello/world", s1.Tag(ext.HTTPURL)) assert.Equal(t, true, s1.Tag("CalledBefore")) assert.Equal(t, true, s1.Tag("CalledAfter")) + assert.Equal(t, ext.SpanKindClient, s1.Tag(ext.SpanKind)) + assert.Equal(t, "net/http", s1.Tag(ext.Component)) } func TestRoundTripperServerError(t *testing.T) { @@ -129,6 +131,8 @@ func TestRoundTripperServerError(t *testing.T) { assert.Equal(t, fmt.Errorf("500: Internal Server Error"), s1.Tag(ext.Error)) assert.Equal(t, true, s1.Tag("CalledBefore")) assert.Equal(t, true, s1.Tag("CalledAfter")) + assert.Equal(t, ext.SpanKindClient, s1.Tag(ext.SpanKind)) + assert.Equal(t, "net/http", s1.Tag(ext.Component)) } func TestRoundTripperNetworkError(t *testing.T) { @@ -171,6 +175,8 @@ func TestRoundTripperNetworkError(t *testing.T) { assert.NotNil(t, s0.Tag(ext.Error)) assert.Equal(t, true, s0.Tag("CalledBefore")) assert.Equal(t, true, s0.Tag("CalledAfter")) + assert.Equal(t, ext.SpanKindClient, s0.Tag(ext.SpanKind)) + assert.Equal(t, "net/http", s0.Tag(ext.Component)) } func TestWrapClient(t *testing.T) { diff --git a/contrib/olivere/elastic/elastictrace.go b/contrib/olivere/elastic/elastictrace.go index a89d5f571c..90e31e7cb4 100644 --- a/contrib/olivere/elastic/elastictrace.go +++ b/contrib/olivere/elastic/elastictrace.go @@ -55,6 +55,8 @@ func (t *httpTransport) RoundTrip(req *http.Request) (*http.Response, error) { tracer.Tag("elasticsearch.method", method), tracer.Tag("elasticsearch.url", url), tracer.Tag("elasticsearch.params", req.URL.Query().Encode()), + tracer.Tag(ext.Component, "olivere/elastic"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(t.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, t.config.analyticsRate)) diff --git a/contrib/olivere/elastic/elastictrace_test.go b/contrib/olivere/elastic/elastictrace_test.go index 6d4276f4a8..68e68f4cbc 100644 --- a/contrib/olivere/elastic/elastictrace_test.go +++ b/contrib/olivere/elastic/elastictrace_test.go @@ -263,6 +263,8 @@ func checkPUTTrace(assert *assert.Assertions, mt mocktracer.Tracer) { assert.Equal("/twitter/tweet/1", span.Tag("elasticsearch.url")) assert.Equal("PUT", span.Tag("elasticsearch.method")) assert.Equal(`{"user": "test", "message": "hello"}`, span.Tag("elasticsearch.body")) + assert.Equal("olivere/elastic", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func checkGETTrace(assert *assert.Assertions, mt mocktracer.Tracer) { @@ -271,6 +273,8 @@ func checkGETTrace(assert *assert.Assertions, mt mocktracer.Tracer) { assert.Equal("GET /twitter/tweet/?", span.Tag(ext.ResourceName)) assert.Equal("/twitter/tweet/1", span.Tag("elasticsearch.url")) assert.Equal("GET", span.Tag("elasticsearch.method")) + assert.Equal("olivere/elastic", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func checkErrTrace(assert *assert.Assertions, mt mocktracer.Tracer) { @@ -280,6 +284,8 @@ func checkErrTrace(assert *assert.Assertions, mt mocktracer.Tracer) { assert.Equal("/not-real-index/_all/1", span.Tag("elasticsearch.url")) assert.NotEmpty(span.Tag(ext.Error)) assert.Equal("*errors.errorString", fmt.Sprintf("%T", span.Tag(ext.Error).(error))) + assert.Equal("olivere/elastic", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) } func TestQuantize(t *testing.T) { diff --git a/contrib/segmentio/kafka.go.v0/kafka.go b/contrib/segmentio/kafka.go.v0/kafka.go index 458bb40675..ea2f9befdd 100644 --- a/contrib/segmentio/kafka.go.v0/kafka.go +++ b/contrib/segmentio/kafka.go.v0/kafka.go @@ -51,6 +51,8 @@ func (r *Reader) startSpan(ctx context.Context, msg *kafka.Message) ddtrace.Span tracer.SpanType(ext.SpanTypeMessageConsumer), tracer.Tag("partition", msg.Partition), tracer.Tag("offset", msg.Offset), + tracer.Tag(ext.Component, "segmentio/kafka.go.v0"), + tracer.Tag(ext.SpanKind, ext.SpanKindConsumer), tracer.Measured(), } if !math.IsNaN(r.cfg.analyticsRate) { @@ -128,6 +130,8 @@ func (w *Writer) startSpan(ctx context.Context, msg *kafka.Message) ddtrace.Span opts := []tracer.StartSpanOption{ tracer.ServiceName(w.cfg.producerServiceName), tracer.SpanType(ext.SpanTypeMessageProducer), + tracer.Tag(ext.Component, "segmentio/kafka.go.v0"), + tracer.Tag(ext.SpanKind, ext.SpanKindProducer), } if w.Writer.Topic != "" { opts = append(opts, tracer.ResourceName("Produce Topic "+w.Writer.Topic)) diff --git a/contrib/segmentio/kafka.go.v0/kafka_test.go b/contrib/segmentio/kafka.go.v0/kafka_test.go index c401e43a81..8802d9f175 100644 --- a/contrib/segmentio/kafka.go.v0/kafka_test.go +++ b/contrib/segmentio/kafka.go.v0/kafka_test.go @@ -82,6 +82,8 @@ func TestReadMessageFunctional(t *testing.T) { assert.Equal(t, 0.1, s0.Tag(ext.EventSampleRate)) assert.Equal(t, "queue", s0.Tag(ext.SpanType)) assert.Equal(t, 0, s0.Tag("partition")) + assert.Equal(t, "segmentio/kafka.go.v0", s0.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s0.Tag(ext.SpanKind)) s1 := spans[1] // consume assert.Equal(t, "kafka.consume", s1.OperationName()) @@ -90,6 +92,8 @@ func TestReadMessageFunctional(t *testing.T) { assert.Equal(t, nil, s1.Tag(ext.EventSampleRate)) assert.Equal(t, "queue", s1.Tag(ext.SpanType)) assert.Equal(t, 0, s1.Tag("partition")) + assert.Equal(t, "segmentio/kafka.go.v0", s1.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindConsumer, s1.Tag(ext.SpanKind)) } func TestFetchMessageFunctional(t *testing.T) { @@ -144,6 +148,8 @@ func TestFetchMessageFunctional(t *testing.T) { assert.Equal(t, 0.1, s0.Tag(ext.EventSampleRate)) assert.Equal(t, "queue", s0.Tag(ext.SpanType)) assert.Equal(t, 0, s0.Tag("partition")) + assert.Equal(t, "segmentio/kafka.go.v0", s0.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindProducer, s0.Tag(ext.SpanKind)) s1 := spans[1] // consume assert.Equal(t, "kafka.consume", s1.OperationName()) @@ -152,4 +158,6 @@ func TestFetchMessageFunctional(t *testing.T) { assert.Equal(t, nil, s1.Tag(ext.EventSampleRate)) assert.Equal(t, "queue", s1.Tag(ext.SpanType)) assert.Equal(t, 0, s1.Tag("partition")) + assert.Equal(t, "segmentio/kafka.go.v0", s1.Tag(ext.Component)) + assert.Equal(t, ext.SpanKindConsumer, s1.Tag(ext.SpanKind)) } diff --git a/contrib/syndtr/goleveldb/leveldb/leveldb.go b/contrib/syndtr/goleveldb/leveldb/leveldb.go index c781bf0ff9..d644d134bc 100644 --- a/contrib/syndtr/goleveldb/leveldb/leveldb.go +++ b/contrib/syndtr/goleveldb/leveldb/leveldb.go @@ -271,6 +271,8 @@ func startSpan(cfg *config, name string) ddtrace.Span { tracer.SpanType(ext.SpanTypeLevelDB), tracer.ServiceName(cfg.serviceName), tracer.ResourceName(name), + tracer.Tag(ext.Component, "syndtr/goleveldb/leveldb"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) diff --git a/contrib/syndtr/goleveldb/leveldb/leveldb_test.go b/contrib/syndtr/goleveldb/leveldb/leveldb_test.go index 9af824b25f..874bb917a8 100644 --- a/contrib/syndtr/goleveldb/leveldb/leveldb_test.go +++ b/contrib/syndtr/goleveldb/leveldb/leveldb_test.go @@ -148,6 +148,8 @@ func testAction(t *testing.T, name string, f func(mt mocktracer.Tracer, db *DB)) assert.Equal(t, ext.SpanTypeLevelDB, spans[0].Tag(ext.SpanType)) assert.Equal(t, "my-database", spans[0].Tag(ext.ServiceName)) assert.Equal(t, name, spans[0].Tag(ext.ResourceName)) + assert.Equal(t, "syndtr/goleveldb/leveldb", spans[0].Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, spans[0].Tag(ext.SpanKind)) }) } diff --git a/contrib/tidwall/buntdb/buntdb.go b/contrib/tidwall/buntdb/buntdb.go index 0fceeb9354..5938a7f0a1 100644 --- a/contrib/tidwall/buntdb/buntdb.go +++ b/contrib/tidwall/buntdb/buntdb.go @@ -98,6 +98,8 @@ func (tx *Tx) startSpan(name string) ddtrace.Span { tracer.SpanType(ext.AppTypeDB), tracer.ServiceName(tx.cfg.serviceName), tracer.ResourceName(name), + tracer.Tag(ext.Component, "tidwall/buntdb"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } if !math.IsNaN(tx.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, tx.cfg.analyticsRate)) diff --git a/contrib/tidwall/buntdb/buntdb_test.go b/contrib/tidwall/buntdb/buntdb_test.go index 940ac08ca4..e97830211f 100644 --- a/contrib/tidwall/buntdb/buntdb_test.go +++ b/contrib/tidwall/buntdb/buntdb_test.go @@ -435,6 +435,8 @@ func testUpdate(t *testing.T, name string, f func(tx *Tx) error) { assert.Equal(t, name, spans[0].Tag(ext.ResourceName)) assert.Equal(t, "buntdb", spans[0].Tag(ext.ServiceName)) assert.Equal(t, "buntdb.query", spans[0].OperationName()) + assert.Equal(t, "tidwall/buntdb", spans[0].Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, spans[0].Tag(ext.SpanKind)) } func testView(t *testing.T, name string, f func(tx *Tx) error) { @@ -453,6 +455,8 @@ func testView(t *testing.T, name string, f func(tx *Tx) error) { assert.Equal(t, name, spans[0].Tag(ext.ResourceName)) assert.Equal(t, "buntdb", spans[0].Tag(ext.ServiceName)) assert.Equal(t, "buntdb.query", spans[0].OperationName()) + assert.Equal(t, "tidwall/buntdb", spans[0].Tag(ext.Component)) + assert.Equal(t, ext.SpanKindClient, spans[0].Tag(ext.SpanKind)) } func getDatabase(t *testing.T, opts ...Option) *DB { diff --git a/contrib/twitchtv/twirp/twirp.go b/contrib/twitchtv/twirp/twirp.go index 8b3d7cfc3d..bce0670ad3 100644 --- a/contrib/twitchtv/twirp/twirp.go +++ b/contrib/twitchtv/twirp/twirp.go @@ -55,6 +55,8 @@ func (wc *wrappedClient) Do(req *http.Request) (*http.Response, error) { tracer.ServiceName(wc.cfg.clientServiceName()), tracer.Tag(ext.HTTPMethod, req.Method), tracer.Tag(ext.HTTPURL, req.URL.Path), + tracer.Tag(ext.Component, "twitchtv/twirp"), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), } ctx := req.Context() if pkg, ok := twirp.PackageName(ctx); ok { @@ -110,6 +112,8 @@ func WrapServer(h http.Handler, opts ...Option) http.Handler { tracer.ServiceName(cfg.serverServiceName()), tracer.Tag(ext.HTTPMethod, r.Method), tracer.Tag(ext.HTTPURL, r.URL.Path), + tracer.Tag(ext.Component, "twitchtv/twirp"), + tracer.Tag(ext.SpanKind, ext.SpanKindServer), tracer.Measured(), } if !math.IsNaN(cfg.analyticsRate) { @@ -159,6 +163,7 @@ func requestReceivedHook(cfg *config) func(context.Context) (context.Context, er tracer.SpanType(ext.SpanTypeWeb), tracer.ServiceName(cfg.serverServiceName()), tracer.Measured(), + tracer.Tag(ext.Component, "twitchtv/twirp"), } if pkg, ok := twirp.PackageName(ctx); ok { opts = append(opts, tracer.Tag("twirp.package", pkg)) diff --git a/contrib/twitchtv/twirp/twirp_test.go b/contrib/twitchtv/twirp/twirp_test.go index 0f90e51de8..8817371ae5 100644 --- a/contrib/twitchtv/twirp/twirp_test.go +++ b/contrib/twitchtv/twirp/twirp_test.go @@ -80,6 +80,8 @@ func TestClient(t *testing.T) { assert.Equal("Example", span.Tag("twirp.service")) assert.Equal("Method", span.Tag("twirp.method")) assert.Equal("200", span.Tag(ext.HTTPCode)) + assert.Equal("twitchtv/twirp", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("server-error", func(t *testing.T) { @@ -107,6 +109,8 @@ func TestClient(t *testing.T) { assert.Equal("Method", span.Tag("twirp.method")) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(true, span.Tag(ext.Error).(bool)) + assert.Equal("twitchtv/twirp", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) t.Run("timeout", func(t *testing.T) { @@ -133,6 +137,8 @@ func TestClient(t *testing.T) { assert.Equal("Example", span.Tag("twirp.service")) assert.Equal("Method", span.Tag("twirp.method")) assert.Equal(context.DeadlineExceeded, span.Tag(ext.Error)) + assert.Equal("twitchtv/twirp", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindClient, span.Tag(ext.SpanKind)) }) } @@ -179,6 +185,7 @@ func TestServerHooks(t *testing.T) { assert.Equal("Example", span.Tag("twirp.service")) assert.Equal("Method", span.Tag("twirp.method")) assert.Equal("200", span.Tag(ext.HTTPCode)) + assert.Equal("twitchtv/twirp", span.Tag(ext.Component)) }) t.Run("error", func(t *testing.T) { @@ -198,6 +205,7 @@ func TestServerHooks(t *testing.T) { assert.Equal("Method", span.Tag("twirp.method")) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal("twirp error internal: something bad or unexpected happened", span.Tag(ext.Error).(error).Error()) + assert.Equal("twitchtv/twirp", span.Tag(ext.Component)) }) t.Run("chained", func(t *testing.T) { @@ -230,6 +238,7 @@ func TestServerHooks(t *testing.T) { assert.Equal("Method", span.Tag("twirp.method")) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal("twirp error internal: something bad or unexpected happened", span.Tag(ext.Error).(error).Error()) + assert.Equal("twitchtv/twirp", span.Tag(ext.Component)) span = spans[1] assert.Equal("other.span.name", span.OperationName()) diff --git a/contrib/urfave/negroni/negroni.go b/contrib/urfave/negroni/negroni.go index 05168c28b6..22ff8ca618 100644 --- a/contrib/urfave/negroni/negroni.go +++ b/contrib/urfave/negroni/negroni.go @@ -29,6 +29,9 @@ func (m *DatadogMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, ne if !math.IsNaN(m.cfg.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, m.cfg.analyticsRate)) } + opts = append(opts, tracer.Tag(ext.Component, "urfave/negroni")) + opts = append(opts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + span, ctx := httptrace.StartRequestSpan(r, opts...) defer func() { // check if the responseWriter is of type negroni.ResponseWriter diff --git a/contrib/urfave/negroni/negroni_test.go b/contrib/urfave/negroni/negroni_test.go index 7373ff6ee7..d8ba0ac17e 100644 --- a/contrib/urfave/negroni/negroni_test.go +++ b/contrib/urfave/negroni/negroni_test.go @@ -63,6 +63,8 @@ func TestTrace200(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user", span.Tag(ext.HTTPURL)) + assert.Equal("urfave/negroni", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } t.Run("response", func(t *testing.T) { diff --git a/contrib/zenazn/goji.v1/web/goji.go b/contrib/zenazn/goji.v1/web/goji.go index 232f4c9e84..a0ea0cfdbb 100644 --- a/contrib/zenazn/goji.v1/web/goji.go +++ b/contrib/zenazn/goji.v1/web/goji.go @@ -36,6 +36,9 @@ func Middleware(opts ...Option) func(*web.C, http.Handler) http.Handler { if !math.IsNaN(cfg.analyticsRate) { cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) } + cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.Component, "zenazn/goji.v1/web")) + cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.SpanKind, ext.SpanKindServer)) + log.Debug("contrib/zenazn/goji.v1/web: Configuring Middleware: %#v", cfg) return func(c *web.C, h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/contrib/zenazn/goji.v1/web/goji_test.go b/contrib/zenazn/goji.v1/web/goji_test.go index 34b7e6edab..f30b4ad7da 100644 --- a/contrib/zenazn/goji.v1/web/goji_test.go +++ b/contrib/zenazn/goji.v1/web/goji_test.go @@ -47,6 +47,8 @@ func TestNoRouter(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal("zenazn/goji.v1/web", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestTraceWithRouter(t *testing.T) { @@ -83,6 +85,8 @@ func TestTraceWithRouter(t *testing.T) { assert.Equal("200", span.Tag(ext.HTTPCode)) assert.Equal("GET", span.Tag(ext.HTTPMethod)) assert.Equal("http://example.com/user/123", span.Tag(ext.HTTPURL)) + assert.Equal("zenazn/goji.v1/web", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestError(t *testing.T) { @@ -113,6 +117,8 @@ func TestError(t *testing.T) { assert.Equal("my-router", span.Tag(ext.ServiceName)) assert.Equal("500", span.Tag(ext.HTTPCode)) assert.Equal(wantErr, span.Tag(ext.Error).(error).Error()) + assert.Equal("zenazn/goji.v1/web", span.Tag(ext.Component)) + assert.Equal(ext.SpanKindServer, span.Tag(ext.SpanKind)) } func TestPropagation(t *testing.T) { @@ -218,4 +224,6 @@ func TestNoDebugStack(t *testing.T) { s := spans[0] assert.EqualError(t, s.Tags()[ext.Error].(error), "500: Internal Server Error") assert.Equal(t, "", spans[0].Tags()[ext.ErrorStack]) + assert.Equal(t, "zenazn/goji.v1/web", spans[0].Tag(ext.Component)) + assert.Equal(t, ext.SpanKindServer, spans[0].Tag(ext.SpanKind)) } diff --git a/ddtrace/ext/span_kind.go b/ddtrace/ext/span_kind.go new file mode 100644 index 0000000000..71a3ce50b8 --- /dev/null +++ b/ddtrace/ext/span_kind.go @@ -0,0 +1,32 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016 Datadog, Inc. + +package ext + +// span_kind values are set per span following the opentelemetry standard +// falls under the values of client, server, producer, consumer, and internal +const ( + + // SpanKindServer indicates that the span covers server-side handling of a synchronous RPC or other remote request + // This span should not have any local parents but can have other distributed parents + SpanKindServer = "server" + + // SpanKindClient indicates that the span describes a request to some remote service. + // This span should not have any local children but can have other distributed children + SpanKindClient = "client" + + // SpanKindConsumer indicates that the span describes the initiators of an asynchronous request. + // This span should not have any local parents but can have other distributed parents + SpanKindConsumer = "consumer" + + // SpanKindProducer indicates that the span describes a child of an asynchronous producer request. + // This span should not have any local children but can have other distributed children + SpanKindProducer = "producer" + + // SpanKindInternal indicates that the span represents an internal operation within an application, + // as opposed to an operations with remote parents or children. + // This is the default value and not explicitly set to save memory + SpanKindInternal = "internal" +) diff --git a/ddtrace/ext/system.go b/ddtrace/ext/system.go index de0579a2d2..163720a4f5 100644 --- a/ddtrace/ext/system.go +++ b/ddtrace/ext/system.go @@ -8,5 +8,5 @@ package ext // Standard system metadata names const ( // The pid of the traced process - Pid = "system.pid" + Pid = "process_id" ) diff --git a/ddtrace/ext/tags.go b/ddtrace/ext/tags.go index 54d16ca576..7a2e83cf3f 100644 --- a/ddtrace/ext/tags.go +++ b/ddtrace/ext/tags.go @@ -100,4 +100,10 @@ const ( // RuntimeID is a tag that contains a unique id for this process. RuntimeID = "runtime-id" + + // Component defines library integration the span originated from. + Component = "component" + + // SpanKind defines the kind of span based on Otel requirements (client, server, producer, consumer). + SpanKind = "span.kind" ) diff --git a/ddtrace/tracer/span_test.go b/ddtrace/tracer/span_test.go index 29edfdef6f..70b341277e 100644 --- a/ddtrace/tracer/span_test.go +++ b/ddtrace/tracer/span_test.go @@ -420,7 +420,7 @@ const ( func TestSpanSetMetric(t *testing.T) { for name, tt := range map[string]func(assert *assert.Assertions, span *span){ "init": func(assert *assert.Assertions, span *span) { - assert.Equal(3, len(span.Metrics)) + assert.Equal(4, len(span.Metrics)) _, ok := span.Metrics[keySamplingPriority] assert.True(ok) _, ok = span.Metrics[keySamplingPriorityRate] @@ -455,7 +455,7 @@ func TestSpanSetMetric(t *testing.T) { "finished": func(assert *assert.Assertions, span *span) { span.Finish() span.SetTag("finished.test", 1337) - assert.Equal(3, len(span.Metrics)) + assert.Equal(4, len(span.Metrics)) _, ok := span.Metrics["finished.test"] assert.False(ok) }, diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index 12f8786c15..7126ee5007 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -67,7 +67,7 @@ type tracer struct { prioritySampling *prioritySampler // pid of the process - pid string + pid int // These integers track metrics about spans and traces as they are started, // finished, and dropped @@ -216,7 +216,7 @@ func newUnstartedTracer(opts ...StartOption) *tracer { flush: make(chan chan<- struct{}), rulesSampling: newRulesSampler(c.traceRules, c.spanRules), prioritySampling: sampler, - pid: strconv.Itoa(os.Getpid()), + pid: os.Getpid(), stats: newConcentrator(c, defaultStatsBucketSize), obfuscator: obfuscate.NewObfuscator(obfuscate.Config{ SQL: obfuscate.SQLConfig{ @@ -453,15 +453,9 @@ func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOpt } } span.context = newSpanContext(span, context) - if context == nil || context.span == nil { - // this is either a root span or it has a remote parent, we should add the PID. - span.setMeta(ext.Pid, t.pid) - if _, ok := opts.Tags[ext.ServiceName]; !ok && t.config.runtimeMetrics { - // this is a root span in the global service; runtime metrics should - // be linked to it: - span.setMeta("language", "go") - } - } + span.setMetric(ext.Pid, float64(t.pid)) + span.setMeta("language", "go") + // add tags from options for k, v := range opts.Tags { span.SetTag(k, v) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index f2dba52419..5d64a3ef41 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -633,28 +633,6 @@ func TestTracerRuntimeMetrics(t *testing.T) { defer tracer.Stop() assert.Contains(t, tp.Lines()[0], "DEBUG: Runtime metrics enabled") }) - - t.Run("off", func(t *testing.T) { - tp := new(testLogger) - tracer := newTracer(WithLogger(tp), WithDebugMode(true)) - defer tracer.Stop() - assert.Len(t, removeAppSec(tp.Lines()), 0) - s := tracer.StartSpan("op").(*span) - _, ok := s.Meta["language"] - assert.False(t, ok) - }) - - t.Run("spans", func(t *testing.T) { - tracer := newTracer(WithRuntimeMetrics(), WithServiceName("main")) - defer tracer.Stop() - - s := tracer.StartSpan("op").(*span) - assert.Equal(t, s.Meta["language"], "go") - - s = tracer.StartSpan("op", ServiceName("secondary")).(*span) - _, ok := s.Meta["language"] - assert.False(t, ok) - }) } func TestTracerStartSpanOptions(t *testing.T) { @@ -987,7 +965,7 @@ func TestNewRootSpanHasPid(t *testing.T) { defer tracer.Stop() root := tracer.newRootSpan("pylons.request", "pylons", "/") - assert.Equal(strconv.Itoa(os.Getpid()), root.Meta[ext.Pid]) + assert.Equal(float64(os.Getpid()), root.Metrics[ext.Pid]) } func TestNewChildHasNoPid(t *testing.T) {