Commit 0835f5bb authored by Bob's avatar Bob Committed by GitHub

[plugin][trace] - Have a consistent spanName (#4171)

Automatically submitted.
parent 5f5cc318
...@@ -28,9 +28,16 @@ Additional features can be enabled with this syntax: ...@@ -28,9 +28,16 @@ Additional features can be enabled with this syntax:
~~~ ~~~
trace [ENDPOINT-TYPE] [ENDPOINT] { trace [ENDPOINT-TYPE] [ENDPOINT] {
every AMOUNT every AMOUNT
service NAME service NAME
client_server client_server
}
~~~
~~~
trace datadog {
every AMOUNT
service NAME
datadog_analytics_rate RATE
} }
~~~ ~~~
...@@ -39,6 +46,8 @@ trace [ENDPOINT-TYPE] [ENDPOINT] { ...@@ -39,6 +46,8 @@ trace [ENDPOINT-TYPE] [ENDPOINT] {
* `service` **NAME** allows you to specify the service name reported to the tracing server. * `service` **NAME** allows you to specify the service name reported to the tracing server.
Default is `coredns`. Default is `coredns`.
* `client_server` will enable the `ClientServerSameSpan` OpenTracing feature. * `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 ## Zipkin
You can run Zipkin on a Docker host like this: You can run Zipkin on a Docker host like this:
......
...@@ -83,6 +83,21 @@ func traceParse(c *caddy.Controller) (*trace, error) { ...@@ -83,6 +83,21 @@ func traceParse(c *caddy.Controller) (*trace, error) {
if err != nil { if err != nil {
return nil, err 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 )
}
} }
} }
} }
......
...@@ -22,6 +22,7 @@ func TestTraceParse(t *testing.T) { ...@@ -22,6 +22,7 @@ func TestTraceParse(t *testing.T) {
{`trace zipkin localhost:1234`, false, "http://localhost:1234/api/v1/spans", 1, `coredns`, false}, {`trace zipkin localhost:1234`, false, "http://localhost:1234/api/v1/spans", 1, `coredns`, false},
{`trace datadog localhost`, false, "localhost", 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 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}", 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 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}, {"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) { ...@@ -29,6 +30,7 @@ func TestTraceParse(t *testing.T) {
// fails // fails
{`trace footype localhost:4321`, true, "", 1, "", false}, {`trace footype localhost:4321`, true, "", 1, "", false},
{"trace {\n every 2\n client_server junk\n}", 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 { for i, test := range tests {
c := caddy.NewTestController("dns", test.input) c := caddy.NewTestController("dns", test.input)
......
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
"sync/atomic" "sync/atomic"
"github.com/coredns/coredns/plugin" "github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/metrics"
"github.com/coredns/coredns/plugin/pkg/dnstest" "github.com/coredns/coredns/plugin/pkg/dnstest"
"github.com/coredns/coredns/plugin/pkg/log" "github.com/coredns/coredns/plugin/pkg/log"
"github.com/coredns/coredns/plugin/pkg/rcode" "github.com/coredns/coredns/plugin/pkg/rcode"
...@@ -20,30 +19,33 @@ import ( ...@@ -20,30 +19,33 @@ import (
zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing" zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing"
"github.com/openzipkin/zipkin-go" "github.com/openzipkin/zipkin-go"
zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http" 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/opentracer"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
) )
const ( const (
tagName = "coredns.io/name" tagName = "coredns.io/name"
tagType = "coredns.io/type" tagType = "coredns.io/type"
tagRcode = "coredns.io/rcode" tagRcode = "coredns.io/rcode"
tagProto = "coredns.io/proto" tagProto = "coredns.io/proto"
tagRemote = "coredns.io/remote" tagRemote = "coredns.io/remote"
defaultTopLevelSpanName = "servedns"
) )
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
Next plugin.Handler Next plugin.Handler
Endpoint string Endpoint string
EndpointType string EndpointType string
tracer ot.Tracer tracer ot.Tracer
serviceEndpoint string serviceEndpoint string
serviceName string serviceName string
clientServer bool clientServer bool
every uint64 every uint64
Once sync.Once datadogAnalyticsRate float64
Once sync.Once
} }
func (t *trace) Tracer() ot.Tracer { func (t *trace) Tracer() ot.Tracer {
...@@ -58,7 +60,13 @@ func (t *trace) OnStartup() error { ...@@ -58,7 +60,13 @@ func (t *trace) OnStartup() error {
case "zipkin": case "zipkin":
err = t.setupZipkin() err = t.setupZipkin()
case "datadog": 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 t.tracer = tracer
default: default:
err = fmt.Errorf("unknown endpoint type: %s", t.EndpointType) err = fmt.Errorf("unknown endpoint type: %s", t.EndpointType)
...@@ -73,7 +81,10 @@ func (t *trace) setupZipkin() error { ...@@ -73,7 +81,10 @@ func (t *trace) setupZipkin() error {
if err != nil { if err != nil {
log.Warningf("build Zipkin endpoint found err: %v", err) 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 { if err != nil {
return err return err
} }
...@@ -100,7 +111,7 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) ...@@ -100,7 +111,7 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
} }
req := request.Request{W: w, Req: r} req := request.Request{W: w, Req: r}
span = t.Tracer().StartSpan(spanName(ctx, req)) span = t.Tracer().StartSpan(defaultTopLevelSpanName)
defer span.Finish() defer span.Finish()
rw := dnstest.NewRecorder(w) rw := dnstest.NewRecorder(w)
...@@ -115,7 +126,3 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) ...@@ -115,7 +126,3 @@ func (t *trace) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
return status, err 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
...@@ -79,9 +79,10 @@ func TestTrace(t *testing.T) { ...@@ -79,9 +79,10 @@ func TestTrace(t *testing.T) {
rootSpan := fs[1] rootSpan := fs[1]
req := request.Request{W: w, Req: tc.question} req := request.Request{W: w, Req: tc.question}
if rootSpan.OperationName != spanName(ctx, req) { if rootSpan.OperationName != defaultTopLevelSpanName {
t.Errorf("Unexpected span name: rootSpan.Name: want %v, got %v", spanName(ctx, req), 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(tagName) != 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", tagName, req.Name(), rootSpan.Tag(tagName))
} }
......
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