diff options
-rw-r--r-- | plugin/trace/README.md | 15 | ||||
-rw-r--r-- | plugin/trace/setup.go | 15 | ||||
-rw-r--r-- | plugin/trace/setup_test.go | 2 | ||||
-rw-r--r-- | plugin/trace/trace.go | 51 | ||||
-rw-r--r-- | plugin/trace/trace_test.go | 5 |
5 files changed, 61 insertions, 27 deletions
diff --git a/plugin/trace/README.md b/plugin/trace/README.md index 3c36f0b86..85c6c64ba 100644 --- a/plugin/trace/README.md +++ b/plugin/trace/README.md @@ -28,9 +28,16 @@ Additional features can be enabled with this syntax: ~~~ trace [ENDPOINT-TYPE] [ENDPOINT] { - every AMOUNT - service NAME - client_server + every AMOUNT + service NAME + client_server +} +~~~ +~~~ +trace datadog { + every AMOUNT + service NAME + datadog_analytics_rate RATE } ~~~ @@ -39,6 +46,8 @@ trace [ENDPOINT-TYPE] [ENDPOINT] { * `service` **NAME** allows you to specify the service name reported to the tracing server. Default is `coredns`. * `client_server` will enable the `ClientServerSameSpan` OpenTracing feature. +* `datadog_analytics_rate` **RATE** will enable [trace analytics](https://docs.datadoghq.com/tracing/app_analytics) on the traces sent + from *0* to *1*, *1* being every trace sent will be analyzed. This is a datadog only feature. ## Zipkin You can run Zipkin on a Docker host like this: diff --git a/plugin/trace/setup.go b/plugin/trace/setup.go index 2ef73a0e4..93d11766f 100644 --- a/plugin/trace/setup.go +++ b/plugin/trace/setup.go @@ -83,6 +83,21 @@ func traceParse(c *caddy.Controller) (*trace, error) { if err != nil { return nil, err } + case "datadog_analytics_rate": + args := c.RemainingArgs() + if len(args) > 1 { + return nil, c.ArgErr() + } + tr.datadogAnalyticsRate = 0 + if len(args) == 1 { + tr.datadogAnalyticsRate,err = strconv.ParseFloat(args[0], 64) + } + if err != nil { + return nil, err + } + if tr.datadogAnalyticsRate > 1 || tr.datadogAnalyticsRate < 0 { + return nil,fmt.Errorf("datadog analytics rate must be between 0 and 1, '%f' is not supported", tr.datadogAnalyticsRate ) + } } } } diff --git a/plugin/trace/setup_test.go b/plugin/trace/setup_test.go index 34b0adb29..1e3baaf4b 100644 --- a/plugin/trace/setup_test.go +++ b/plugin/trace/setup_test.go @@ -22,6 +22,7 @@ func TestTraceParse(t *testing.T) { {`trace zipkin localhost:1234`, false, "http://localhost:1234/api/v1/spans", 1, `coredns`, false}, {`trace datadog localhost`, false, "localhost", 1, `coredns`, false}, {`trace datadog http://localhost:8127`, false, "http://localhost:8127", 1, `coredns`, false}, + {"trace datadog localhost {\n datadog_analytics_rate 0.1\n}", false, "localhost", 1, `coredns`, false}, {"trace {\n every 100\n}", false, "http://localhost:9411/api/v1/spans", 100, `coredns`, false}, {"trace {\n every 100\n service foobar\nclient_server\n}", false, "http://localhost:9411/api/v1/spans", 100, `foobar`, true}, {"trace {\n every 2\n client_server true\n}", false, "http://localhost:9411/api/v1/spans", 2, `coredns`, true}, @@ -29,6 +30,7 @@ func TestTraceParse(t *testing.T) { // fails {`trace footype localhost:4321`, true, "", 1, "", false}, {"trace {\n every 2\n client_server junk\n}", true, "", 1, "", false}, + {"trace datadog localhost {\n datadog_analytics_rate 2\n}", true, "", 1, "", false}, } for i, test := range tests { c := caddy.NewTestController("dns", test.input) diff --git a/plugin/trace/trace.go b/plugin/trace/trace.go index b74cc5b33..4e1d1b4de 100644 --- a/plugin/trace/trace.go +++ b/plugin/trace/trace.go @@ -8,7 +8,6 @@ import ( "sync/atomic" "github.com/coredns/coredns/plugin" - "github.com/coredns/coredns/plugin/metrics" "github.com/coredns/coredns/plugin/pkg/dnstest" "github.com/coredns/coredns/plugin/pkg/log" "github.com/coredns/coredns/plugin/pkg/rcode" @@ -20,30 +19,33 @@ import ( zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing" "github.com/openzipkin/zipkin-go" zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" ) const ( - tagName = "coredns.io/name" - tagType = "coredns.io/type" - tagRcode = "coredns.io/rcode" - tagProto = "coredns.io/proto" - tagRemote = "coredns.io/remote" + tagName = "coredns.io/name" + tagType = "coredns.io/type" + tagRcode = "coredns.io/rcode" + tagProto = "coredns.io/proto" + tagRemote = "coredns.io/remote" + defaultTopLevelSpanName = "servedns" ) type trace struct { count uint64 // as per Go spec, needs to be first element in a struct - Next plugin.Handler - Endpoint string - EndpointType string - tracer ot.Tracer - serviceEndpoint string - serviceName string - clientServer bool - every uint64 - Once sync.Once + Next plugin.Handler + Endpoint string + EndpointType string + tracer ot.Tracer + serviceEndpoint string + serviceName string + clientServer bool + every uint64 + datadogAnalyticsRate float64 + Once sync.Once } func (t *trace) Tracer() ot.Tracer { @@ -58,7 +60,13 @@ func (t *trace) OnStartup() error { case "zipkin": err = t.setupZipkin() case "datadog": - tracer := opentracer.New(tracer.WithAgentAddr(t.Endpoint), tracer.WithServiceName(t.serviceName), tracer.WithDebugMode(log.D.Value())) + tracer := opentracer.New( + tracer.WithAgentAddr(t.Endpoint), + tracer.WithDebugMode(log.D.Value()), + tracer.WithGlobalTag(ext.SpanTypeDNS, true), + tracer.WithServiceName(t.serviceName), + tracer.WithAnalyticsRate(t.datadogAnalyticsRate), + ) t.tracer = tracer default: err = fmt.Errorf("unknown endpoint type: %s", t.EndpointType) @@ -73,7 +81,10 @@ func (t *trace) setupZipkin() error { if err != nil { log.Warningf("build Zipkin endpoint found err: %v", err) } - tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(recorder)) + tracer, err := zipkin.NewTracer( + reporter, + zipkin.WithLocalEndpoint(recorder), + ) if err != nil { return err } @@ -100,7 +111,7 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) } req := request.Request{W: w, Req: r} - span = t.Tracer().StartSpan(spanName(ctx, req)) + span = t.Tracer().StartSpan(defaultTopLevelSpanName) defer span.Finish() rw := dnstest.NewRecorder(w) @@ -115,7 +126,3 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) return status, err } - -func spanName(ctx context.Context, req request.Request) string { - return "servedns:" + metrics.WithServer(ctx) + " " + req.Name() -}
\ No newline at end of file diff --git a/plugin/trace/trace_test.go b/plugin/trace/trace_test.go index e06e3e8ee..613f88b6d 100644 --- a/plugin/trace/trace_test.go +++ b/plugin/trace/trace_test.go @@ -79,9 +79,10 @@ func TestTrace(t *testing.T) { rootSpan := fs[1] req := request.Request{W: w, Req: tc.question} - if rootSpan.OperationName != spanName(ctx, req) { - t.Errorf("Unexpected span name: rootSpan.Name: want %v, got %v", spanName(ctx, req), rootSpan.OperationName) + if rootSpan.OperationName != defaultTopLevelSpanName { + t.Errorf("Unexpected span name: rootSpan.Name: want %v, got %v", defaultTopLevelSpanName, rootSpan.OperationName) } + if rootSpan.Tag(tagName) != req.Name() { t.Errorf("Unexpected span tag: rootSpan.Tag(%v): want %v, got %v", tagName, req.Name(), rootSpan.Tag(tagName)) } |