Skip to content

Commit c6dbdd9

Browse files
anapsixclaude
andcommitted
feat(contrib/lovoo/goka): add goka integration with APM and DSM support
Add a new contrib package instrumenting github.com/lovoo/goka with both Datadog APM distributed tracing and Data Streams Monitoring in a single integration. goka builds its consumer group on top of IBM/sarama but owns the sarama.ConsumerGroupHandler internally, so the contrib/IBM/sarama integration cannot attach. This package instruments through goka's public extension points instead, requiring no changes to goka: - NewTracer + WrapContext (goka.WithContextWrapper) sets the inbound DSM checkpoint and returns a context whose Emit/Loopback propagate the active consume span and a DSM outbound checkpoint into the emitted headers. - WrapCallback runs each input message inside a kafka.consume span, finishing it around the callback (panics recovered and error-tagged) and recording the DSM commit offset on success, honoring ctx.DeferCommit. - No kafka.produce span is created: goka.Context.Emit is asynchronous with no completion handle, so trace continuity is preserved by propagating the consume span through the outbound headers instead. - EmitHeaders covers the standalone goka.Emitter path. - WithService, WithDataStreams, and WithLoopSuffix options; a single header carrier satisfies both the tracer and datastreams TextMap interfaces. Register PackageLovooGoka in instrumentation/packages.go and contribIntegrations in ddtrace/tracer/option.go. Includes unit tests (carrier round-trip, DSM no-op when disabled, span parent/child linkage, error tagging, emit/loopback injection, DeferCommit, context delegation) and an INTEGRATION-gated end-to-end test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5774a34 commit c6dbdd9

12 files changed

Lines changed: 1665 additions & 9 deletions

File tree

contrib/lovoo/goka/carrier.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed
2+
// under the Apache License Version 2.0.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
// Copyright 2016 Datadog, Inc.
5+
6+
package goka
7+
8+
import (
9+
"github.com/lovoo/goka"
10+
11+
"github.com/DataDog/dd-trace-go/v2/datastreams"
12+
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
13+
)
14+
15+
// gokaHeadersCarrier adapts goka.Headers (map[string][]byte) to the text-map
16+
// interfaces used by both APM trace propagation (tracer.Extract/Inject) and Data
17+
// Streams Monitoring (datastreams.ExtractFromBase64Carrier/InjectToBase64Carrier).
18+
// A single carrier serves both because the four interfaces share the same method
19+
// shapes. The carrier shares the underlying map, so Set mutates the goka.Headers
20+
// it wraps.
21+
type gokaHeadersCarrier goka.Headers
22+
23+
var (
24+
_ tracer.TextMapReader = gokaHeadersCarrier(nil)
25+
_ tracer.TextMapWriter = gokaHeadersCarrier(nil)
26+
_ datastreams.TextMapReader = gokaHeadersCarrier(nil)
27+
_ datastreams.TextMapWriter = gokaHeadersCarrier(nil)
28+
)
29+
30+
// ForeachKey implements tracer.TextMapReader and datastreams.TextMapReader.
31+
func (c gokaHeadersCarrier) ForeachKey(handler func(key, val string) error) error {
32+
for k, v := range c {
33+
if err := handler(k, string(v)); err != nil {
34+
return err
35+
}
36+
}
37+
return nil
38+
}
39+
40+
// Set implements tracer.TextMapWriter and datastreams.TextMapWriter.
41+
func (c gokaHeadersCarrier) Set(key, val string) {
42+
c[key] = []byte(val)
43+
}
44+
45+
// ExtractSpanContext extracts the span context propagated in a goka message's
46+
// headers, allowing callers to create manual child spans.
47+
func ExtractSpanContext(headers goka.Headers) (*tracer.SpanContext, error) {
48+
return tracer.Extract(gokaHeadersCarrier(headers))
49+
}

contrib/lovoo/goka/example_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed
2+
// under the Apache License Version 2.0.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
// Copyright 2016 Datadog, Inc.
5+
6+
package goka_test
7+
8+
import (
9+
"log"
10+
11+
gokatrace "github.com/DataDog/dd-trace-go/contrib/lovoo/goka/v2"
12+
13+
"github.com/lovoo/goka"
14+
"github.com/lovoo/goka/codec"
15+
)
16+
17+
func Example() {
18+
tr := gokatrace.NewTracer(
19+
gokatrace.WithService("orders-processor"),
20+
gokatrace.WithDataStreams(),
21+
)
22+
23+
// handle processes an input message. Because the callback is wrapped, it runs
24+
// inside a "kafka.consume" span, and ctx.Emit continues the trace downstream.
25+
handle := func(ctx goka.Context, msg any) {
26+
ctx.Emit("orders-enriched", ctx.Key(), msg)
27+
}
28+
29+
g := goka.DefineGroup(
30+
"orders",
31+
goka.Input("orders", new(codec.String), tr.WrapCallback(handle)),
32+
goka.Output("orders-enriched", new(codec.String)),
33+
)
34+
35+
p, err := goka.NewProcessor(
36+
[]string{"localhost:9092"},
37+
g,
38+
goka.WithContextWrapper(tr.WrapContext),
39+
)
40+
if err != nil {
41+
log.Fatal(err)
42+
}
43+
_ = p
44+
}

contrib/lovoo/goka/go.mod

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
module github.com/DataDog/dd-trace-go/contrib/lovoo/goka/v2
2+
3+
go 1.25.0
4+
5+
require (
6+
github.com/DataDog/dd-trace-go/v2 v2.11.0-dev
7+
github.com/lovoo/goka v1.1.8
8+
github.com/stretchr/testify v1.11.1
9+
)
10+
11+
require (
12+
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.79.0 // indirect
13+
github.com/DataDog/datadog-agent/pkg/obfuscate v0.79.0 // indirect
14+
github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.79.0 // indirect
15+
github.com/DataDog/datadog-agent/pkg/proto v0.79.0 // indirect
16+
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.79.0 // indirect
17+
github.com/DataDog/datadog-agent/pkg/trace v0.79.0 // indirect
18+
github.com/DataDog/datadog-agent/pkg/trace/log v0.79.0 // indirect
19+
github.com/DataDog/datadog-agent/pkg/trace/stats v0.79.0 // indirect
20+
github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.79.0 // indirect
21+
github.com/DataDog/datadog-go/v5 v5.8.3 // indirect
22+
github.com/DataDog/go-libddwaf/v5 v5.0.0 // indirect
23+
github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d // indirect
24+
github.com/DataDog/go-sqllexer v0.2.1 // indirect
25+
github.com/DataDog/go-tuf v1.1.1-0.5.2 // indirect
26+
github.com/DataDog/sketches-go v1.4.8 // indirect
27+
github.com/Microsoft/go-winio v0.6.2 // indirect
28+
github.com/Shopify/sarama v1.37.2 // indirect
29+
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
30+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
31+
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
32+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
33+
github.com/dustin/go-humanize v1.0.1 // indirect
34+
github.com/eapache/go-resiliency v1.3.0 // indirect
35+
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
36+
github.com/eapache/queue v1.1.0 // indirect
37+
github.com/ebitengine/purego v0.10.0 // indirect
38+
github.com/go-ole/go-ole v1.3.0 // indirect
39+
github.com/go-stack/stack v1.8.1 // indirect
40+
github.com/golang/mock v1.7.0-rc.1 // indirect
41+
github.com/golang/snappy v0.0.4 // indirect
42+
github.com/google/uuid v1.6.0 // indirect
43+
github.com/hashicorp/errwrap v1.1.0 // indirect
44+
github.com/hashicorp/go-multierror v1.1.1 // indirect
45+
github.com/hashicorp/go-uuid v1.0.3 // indirect
46+
github.com/hashicorp/go-version v1.9.0 // indirect
47+
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
48+
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
49+
github.com/jcmturner/gofork v1.7.6 // indirect
50+
github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect
51+
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
52+
github.com/json-iterator/go v1.1.12 // indirect
53+
github.com/klauspost/compress v1.18.6 // indirect
54+
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
55+
github.com/linkdata/deadlock v0.5.5 // indirect
56+
github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 // indirect
57+
github.com/minio/simdjson-go v0.4.5 // indirect
58+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
59+
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
60+
github.com/outcaste-io/ristretto v0.2.3 // indirect
61+
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
62+
github.com/philhofer/fwd v1.2.0 // indirect
63+
github.com/pierrec/lz4/v4 v4.1.17 // indirect
64+
github.com/pkg/errors v0.9.1 // indirect
65+
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
66+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
67+
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
68+
github.com/puzpuzpuz/xsync/v4 v4.5.0 // indirect
69+
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
70+
github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect
71+
github.com/shirou/gopsutil/v4 v4.26.3 // indirect
72+
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
73+
github.com/tinylib/msgp v1.6.3 // indirect
74+
github.com/tklauser/go-sysconf v0.3.16 // indirect
75+
github.com/tklauser/numcpus v0.11.0 // indirect
76+
github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561 // indirect
77+
github.com/yusufpapurcu/wmi v1.2.4 // indirect
78+
go.opentelemetry.io/collector/component v1.56.0 // indirect
79+
go.opentelemetry.io/collector/featuregate v1.56.0 // indirect
80+
go.opentelemetry.io/collector/pdata v1.56.0 // indirect
81+
go.opentelemetry.io/collector/pdata/pprofile v0.150.0 // indirect
82+
go.opentelemetry.io/otel v1.43.0 // indirect
83+
go.opentelemetry.io/otel/metric v1.43.0 // indirect
84+
go.opentelemetry.io/otel/trace v1.43.0 // indirect
85+
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
86+
go.uber.org/atomic v1.11.0 // indirect
87+
go.uber.org/multierr v1.11.0 // indirect
88+
go.uber.org/zap v1.27.1 // indirect
89+
go.yaml.in/yaml/v3 v3.0.4 // indirect
90+
golang.org/x/crypto v0.52.0 // indirect
91+
golang.org/x/exp v0.0.0-20260209203927-2842357ff358 // indirect
92+
golang.org/x/mod v0.35.0 // indirect
93+
golang.org/x/net v0.55.0 // indirect
94+
golang.org/x/sync v0.20.0 // indirect
95+
golang.org/x/sys v0.45.0 // indirect
96+
golang.org/x/time v0.15.0 // indirect
97+
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
98+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
99+
google.golang.org/protobuf v1.36.11 // indirect
100+
gopkg.in/yaml.v3 v3.0.1 // indirect
101+
)
102+
103+
replace github.com/DataDog/dd-trace-go/v2 => ../../..

0 commit comments

Comments
 (0)