mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	plugin/trace - Use compatible tag name for datadog (#4408)
Traces are currently working properly with datadog with the exception of having the ability to facet the tags  In order to get valuable graph in dashboard the tag on the metrics need to be faceted by datadog. This PR update the tags with facetable path. While keeping backward compatibility with existing path for zipkin. Graph like:      Signed-off-by: bob <bob.bouteillier@datadoghq.com>
This commit is contained in:
		| @@ -25,14 +25,34 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	tagName                 = "coredns.io/name" |  | ||||||
| 	tagType                 = "coredns.io/type" |  | ||||||
| 	tagRcode                = "coredns.io/rcode" |  | ||||||
| 	tagProto                = "coredns.io/proto" |  | ||||||
| 	tagRemote               = "coredns.io/remote" |  | ||||||
| 	defaultTopLevelSpanName = "servedns" | 	defaultTopLevelSpanName = "servedns" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | type traceTags struct { | ||||||
|  | 	Name   string | ||||||
|  | 	Type   string | ||||||
|  | 	Rcode  string | ||||||
|  | 	Proto  string | ||||||
|  | 	Remote string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var tagByProvider = map[string]traceTags{ | ||||||
|  | 	"default": { | ||||||
|  | 		Name:   "coredns.io/name", | ||||||
|  | 		Type:   "coredns.io/type", | ||||||
|  | 		Rcode:  "coredns.io/rcode", | ||||||
|  | 		Proto:  "coredns.io/proto", | ||||||
|  | 		Remote: "coredns.io/remote", | ||||||
|  | 	}, | ||||||
|  | 	"datadog": { | ||||||
|  | 		Name:   "coredns.io@name", | ||||||
|  | 		Type:   "coredns.io@type", | ||||||
|  | 		Rcode:  "coredns.io@rcode", | ||||||
|  | 		Proto:  "coredns.io@proto", | ||||||
|  | 		Remote: "coredns.io@remote", | ||||||
|  | 	}, | ||||||
|  | } | ||||||
|  |  | ||||||
| type trace struct { | type trace struct { | ||||||
| 	count uint64 // as per Go spec, needs to be first element in a struct | 	count uint64 // as per Go spec, needs to be first element in a struct | ||||||
|  |  | ||||||
| @@ -46,6 +66,7 @@ type trace struct { | |||||||
| 	every                uint64 | 	every                uint64 | ||||||
| 	datadogAnalyticsRate float64 | 	datadogAnalyticsRate float64 | ||||||
| 	Once                 sync.Once | 	Once                 sync.Once | ||||||
|  | 	tagSet               traceTags | ||||||
| } | } | ||||||
|  |  | ||||||
| func (t *trace) Tracer() ot.Tracer { | func (t *trace) Tracer() ot.Tracer { | ||||||
| @@ -68,6 +89,7 @@ func (t *trace) OnStartup() error { | |||||||
| 				tracer.WithAnalyticsRate(t.datadogAnalyticsRate), | 				tracer.WithAnalyticsRate(t.datadogAnalyticsRate), | ||||||
| 			) | 			) | ||||||
| 			t.tracer = tracer | 			t.tracer = tracer | ||||||
|  | 			t.tagSet = tagByProvider["datadog"] | ||||||
| 		default: | 		default: | ||||||
| 			err = fmt.Errorf("unknown endpoint type: %s", t.EndpointType) | 			err = fmt.Errorf("unknown endpoint type: %s", t.EndpointType) | ||||||
| 		} | 		} | ||||||
| @@ -90,6 +112,8 @@ func (t *trace) setupZipkin() error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	t.tracer = zipkinot.Wrap(tracer) | 	t.tracer = zipkinot.Wrap(tracer) | ||||||
|  |  | ||||||
|  | 	t.tagSet = tagByProvider["default"] | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -119,11 +143,11 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) | |||||||
| 	ctx = ot.ContextWithSpan(ctx, span) | 	ctx = ot.ContextWithSpan(ctx, span) | ||||||
| 	status, err := plugin.NextOrFailure(t.Name(), t.Next, ctx, rw, r) | 	status, err := plugin.NextOrFailure(t.Name(), t.Next, ctx, rw, r) | ||||||
|  |  | ||||||
| 	span.SetTag(tagName, req.Name()) | 	span.SetTag(t.tagSet.Name, req.Name()) | ||||||
| 	span.SetTag(tagType, req.Type()) | 	span.SetTag(t.tagSet.Type, req.Type()) | ||||||
| 	span.SetTag(tagProto, req.Proto()) | 	span.SetTag(t.tagSet.Proto, req.Proto()) | ||||||
| 	span.SetTag(tagRemote, req.IP()) | 	span.SetTag(t.tagSet.Remote, req.IP()) | ||||||
| 	span.SetTag(tagRcode, rcode.ToString(rw.Rcode)) | 	span.SetTag(t.tagSet.Rcode, rcode.ToString(rw.Rcode)) | ||||||
|  |  | ||||||
| 	return status, err | 	return status, err | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,6 +28,11 @@ func TestStartup(t *testing.T) { | |||||||
| 		t.Errorf("Error starting tracing plugin: %s", err) | 		t.Errorf("Error starting tracing plugin: %s", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if m.tagSet != tagByProvider["default"] { | ||||||
|  | 		t.Errorf("TagSet by proviser hasn't been corectly initialized") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if m.Tracer() == nil { | 	if m.Tracer() == nil { | ||||||
| 		t.Errorf("Error, no tracer created") | 		t.Errorf("Error, no tracer created") | ||||||
| 	} | 	} | ||||||
| @@ -51,7 +56,7 @@ func TestTrace(t *testing.T) { | |||||||
| 			question: new(dns.Msg).SetQuestion("example.net.", dns.TypeCNAME), | 			question: new(dns.Msg).SetQuestion("example.net.", dns.TypeCNAME), | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  | 	defaultTagSet := tagByProvider["default"] | ||||||
| 	for _, tc := range cases { | 	for _, tc := range cases { | ||||||
| 		t.Run(tc.name, func(t *testing.T) { | 		t.Run(tc.name, func(t *testing.T) { | ||||||
| 			w := dnstest.NewRecorder(&test.ResponseWriter{}) | 			w := dnstest.NewRecorder(&test.ResponseWriter{}) | ||||||
| @@ -65,6 +70,7 @@ func TestTrace(t *testing.T) { | |||||||
| 				}), | 				}), | ||||||
| 				every:  1, | 				every:  1, | ||||||
| 				tracer: m, | 				tracer: m, | ||||||
|  | 				tagSet: defaultTagSet, | ||||||
| 			} | 			} | ||||||
| 			ctx := context.TODO() | 			ctx := context.TODO() | ||||||
| 			if _, err := tr.ServeDNS(ctx, w, tc.question); err != nil { | 			if _, err := tr.ServeDNS(ctx, w, tc.question); err != nil { | ||||||
| @@ -83,20 +89,20 @@ func TestTrace(t *testing.T) { | |||||||
| 				t.Errorf("Unexpected span name: rootSpan.Name: want %v, got %v", defaultTopLevelSpanName, rootSpan.OperationName) | 				t.Errorf("Unexpected span name: rootSpan.Name: want %v, got %v", defaultTopLevelSpanName, rootSpan.OperationName) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if rootSpan.Tag(tagName) != req.Name() { | 			if rootSpan.Tag(defaultTagSet.Name) != req.Name() { | ||||||
| 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", tagName, req.Name(), rootSpan.Tag(tagName)) | 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", defaultTagSet.Name, req.Name(), rootSpan.Tag(defaultTagSet.Name)) | ||||||
| 			} | 			} | ||||||
| 			if rootSpan.Tag(tagType) != req.Type() { | 			if rootSpan.Tag(defaultTagSet.Type) != req.Type() { | ||||||
| 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", tagType, req.Type(), rootSpan.Tag(tagType)) | 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", defaultTagSet.Type, req.Type(), rootSpan.Tag(defaultTagSet.Type)) | ||||||
| 			} | 			} | ||||||
| 			if rootSpan.Tag(tagProto) != req.Proto() { | 			if rootSpan.Tag(defaultTagSet.Proto) != req.Proto() { | ||||||
| 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", tagProto, req.Proto(), rootSpan.Tag(tagProto)) | 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", defaultTagSet.Proto, req.Proto(), rootSpan.Tag(defaultTagSet.Proto)) | ||||||
| 			} | 			} | ||||||
| 			if rootSpan.Tag(tagRemote) != req.IP() { | 			if rootSpan.Tag(defaultTagSet.Remote) != req.IP() { | ||||||
| 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", tagRemote, req.IP(), rootSpan.Tag(tagRemote)) | 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", defaultTagSet.Remote, req.IP(), rootSpan.Tag(defaultTagSet.Remote)) | ||||||
| 			} | 			} | ||||||
| 			if rootSpan.Tag(tagRcode) != rcode.ToString(tc.rcode) { | 			if rootSpan.Tag(defaultTagSet.Rcode) != rcode.ToString(tc.rcode) { | ||||||
| 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", tagRcode, rcode.ToString(tc.rcode), rootSpan.Tag(tagRcode)) | 				t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", defaultTagSet.Rcode, rcode.ToString(tc.rcode), rootSpan.Tag(defaultTagSet.Rcode)) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user