Skip to content

Commit 753a8aa

Browse files
Added disable trace propagation option at writer instantiation (#24)
Add disable trace propagation option at writer instantiation --------- Co-authored-by: stewartboyd119 <[email protected]>
1 parent d91bef4 commit 753a8aa

File tree

3 files changed

+68
-9
lines changed

3 files changed

+68
-9
lines changed

Diff for: changelog.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
44

55
This project adheres to Semantic Versioning.
66

7-
## 2.0.5 (Jan 14, 2024)
7+
## 2.1.0 (Jan 23, 2025)
8+
9+
1. Include `DisableTracePropagation` as a WriterOption
10+
11+
## 2.0.5 (Jan 14, 2025)
812

913
1. Updated confluent-kafka-go-2.8.0
1014

Diff for: test/integration_test.go

+55-7
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ import (
1818
"github.com/stretchr/testify/require"
1919
"github.com/zillow/zfmt"
2020
"github.com/zillow/zkafka/v2"
21+
"go.opentelemetry.io/otel/propagation"
22+
"go.opentelemetry.io/otel/trace/noop"
2123
"golang.org/x/sync/errgroup"
2224
)
2325

2426
// TestKafkaClientsCanReadOwnWritesAndBehaveProperlyAfterRestart will test that a kafka consumer can properly read messages
2527
// written by the kafka producer. It will additionally, confirm that when a group is restarted that it starts off where
26-
// it left off (addressing an off by 1 bug seen with an earlier version)
28+
// it left off (addressing an off by 1 bug seen with an earlier version).
29+
// Finally it'll confirm that otel propagation can be used to manipulate written contents of kafka.Message
30+
// And that options exist to create a zkafka.Writer which disables that propagation. This is done by including a propagator
31+
// which always adds the header "kobe"="bryant". Writer1 uses this propagator, writer2 disables it. Assertions are made
32+
// on the presence of the header.
2733
//
2834
// The following steps are followed
2935
// 1. Create a new consumer group that is reading from the topic
@@ -43,14 +49,34 @@ func TestKafkaClientsCanReadOwnWritesAndBehaveProperlyAfterRestart(t *testing.T)
4349

4450
groupID := uuid.NewString()
4551

46-
client := zkafka.NewClient(zkafka.Config{BootstrapServers: []string{bootstrapServer}}, zkafka.LoggerOption(stdLogger{}))
52+
client := zkafka.NewClient(
53+
zkafka.Config{BootstrapServers: []string{bootstrapServer}},
54+
zkafka.LoggerOption(stdLogger{}),
55+
zkafka.WithClientTextMapPropagator(fakeTextMapPropagator{
56+
inject: func(ctx context.Context, carrier propagation.TextMapCarrier) {
57+
carrier.Set("kobe", "bryant")
58+
},
59+
}),
60+
zkafka.WithClientTracerProviderOption(noop.NewTracerProvider()),
61+
)
4762
defer func() { require.NoError(t, client.Close()) }()
4863

49-
writer, err := client.Writer(ctx, zkafka.ProducerTopicConfig{
50-
ClientID: fmt.Sprintf("writer-%s-%s", t.Name(), uuid.NewString()),
64+
writer1, err := client.Writer(ctx, zkafka.ProducerTopicConfig{
65+
ClientID: fmt.Sprintf("writer1-%s-%s", t.Name(), uuid.NewString()),
66+
Topic: topic,
67+
Formatter: zfmt.JSONFmt,
68+
})
69+
require.NoError(t, err)
70+
71+
writer2, err := client.Writer(ctx, zkafka.ProducerTopicConfig{
72+
ClientID: fmt.Sprintf("writer2-%s-%s", t.Name(), uuid.NewString()),
5173
Topic: topic,
5274
Formatter: zfmt.JSONFmt,
75+
}, func(settings *zkafka.WriterSettings) {
76+
settings.DisableTracePropagation = true
5377
})
78+
require.NoError(t, err)
79+
5480
consumerTopicConfig := zkafka.ConsumerTopicConfig{
5581
ClientID: fmt.Sprintf("reader-%s-%s", t.Name(), uuid.NewString()),
5682
Topic: topic,
@@ -111,11 +137,11 @@ func TestKafkaClientsCanReadOwnWritesAndBehaveProperlyAfterRestart(t *testing.T)
111137
}, readResponses)
112138

113139
// write msg1, and msg2
114-
resWrite1, err := writer.Write(ctx, msg1)
140+
resWrite1, err := writer1.Write(ctx, msg1)
115141
require.NoError(t, err)
116142

117143
msg2 := Msg{Val: "2"}
118-
resWrite2, err := writer.Write(ctx, msg2)
144+
resWrite2, err := writer2.Write(ctx, msg2)
119145
require.NoError(t, err)
120146

121147
// reader will send on channel the messages it has read (should just be msg1)
@@ -125,6 +151,7 @@ func TestKafkaClientsCanReadOwnWritesAndBehaveProperlyAfterRestart(t *testing.T)
125151
require.NoError(t, resp.err)
126152
require.NotNil(t, rmsg1, "expected written message to be read")
127153
require.Equal(t, int(rmsg1.Offset), int(resWrite1.Offset), "expected read offset to match written")
154+
require.Equal(t, "bryant", string(rmsg1.Headers["kobe"]))
128155

129156
gotMsg1 := Msg{}
130157
err = resp.msg.Decode(&gotMsg1)
@@ -151,6 +178,7 @@ func TestKafkaClientsCanReadOwnWritesAndBehaveProperlyAfterRestart(t *testing.T)
151178

152179
// assert offset is for second message written (no replay of old message)
153180
require.Equal(t, int(rmsg2.Offset), int(resWrite2.Offset), "expected read offset to match written")
181+
require.Empty(t, rmsg2.Headers["kobe"])
154182

155183
gotMsg2 := Msg{}
156184
err = rmsg2.Decode(&gotMsg2)
@@ -1285,7 +1313,7 @@ func Test_DeadletterClientDoesntCollideWithProducer(t *testing.T) {
12851313
if msgCount.Load()%2 == 0 {
12861314
return errors.New("random error occurred")
12871315
}
1288-
_, err := processorWriter.WriteRaw(ctx, nil, msg.Value())
1316+
_, err := processorWriter.WriteRaw(ctx, nil, msg.Value(), nil)
12891317

12901318
return err
12911319
})
@@ -1458,3 +1486,23 @@ type partition struct {
14581486
offset int64
14591487
topic string
14601488
}
1489+
1490+
type fakeTextMapPropagator struct {
1491+
inject func(ctx context.Context, carrier propagation.TextMapCarrier)
1492+
}
1493+
1494+
func (f fakeTextMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
1495+
if f.inject != nil {
1496+
f.inject(ctx, carrier)
1497+
}
1498+
}
1499+
1500+
func (f fakeTextMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
1501+
return ctx
1502+
}
1503+
1504+
func (f fakeTextMapPropagator) Fields() []string {
1505+
return nil
1506+
}
1507+
1508+
var _ propagation.TextMapPropagator = (*fakeTextMapPropagator)(nil)

Diff for: writer.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ func newWriter(args writerArgs) (*KWriter, error) {
100100
for _, opt := range args.opts {
101101
opt(&s)
102102
}
103+
if s.DisableTracePropagation {
104+
w.p = nil
105+
}
103106
if s.f != nil {
104107
w.formatter = s.f
105108
}
@@ -130,6 +133,9 @@ func (w *KWriter) WriteKey(ctx context.Context, key string, value any, opts ...W
130133
func (w *KWriter) WriteRaw(ctx context.Context, key *string, value []byte, opts ...WriteOption) (Response, error) {
131134
kafkaMessage := makeProducerMessageRaw(ctx, w.topicConfig.Topic, key, value)
132135
for _, opt := range opts {
136+
if opt == nil {
137+
continue
138+
}
133139
opt.apply(&kafkaMessage)
134140
}
135141
if w.lifecycle.PreWrite != nil {
@@ -248,7 +254,8 @@ func (w *KWriter) Close() {
248254
}
249255

250256
type WriterSettings struct {
251-
f kFormatter
257+
f kFormatter
258+
DisableTracePropagation bool
252259
}
253260

254261
// WriterOption is a function that modify the writer configurations

0 commit comments

Comments
 (0)