Commit d8d2c169 authored by Bob's avatar Bob Committed by GitHub

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

![image](https://user-images.githubusercontent.com/5513509/105051238-dddbbd00-5a6e-11eb-8fb2-071b3b1fa8cc.png)

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:
![image](https://user-images.githubusercontent.com/5513509/93375960-339e1f80-f859-11ea-81f0-a1074c375630.png)
![image](https://user-images.githubusercontent.com/5513509/93375997-4153a500-f859-11ea-9f8d-63d45217c681.png)
![image](https://user-images.githubusercontent.com/5513509/93376064-5597a200-f859-11ea-823a-6768f59e3497.png)
![image](https://user-images.githubusercontent.com/5513509/93376405-d6ef3480-f859-11ea-8d6f-58dda247cc86.png)
![image](https://user-images.githubusercontent.com/5513509/93376518-069e3c80-f85a-11ea-9a7e-0426a3817439.png)
Signed-off-by: default avatarbob <bob.bouteillier@datadoghq.com>
parent fc5c1721
...@@ -25,14 +25,34 @@ import ( ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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))
} }
}) })
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment