@@ -17,8 +17,10 @@ package kafka
17
17
import (
18
18
"flag"
19
19
"fmt"
20
+ "log"
20
21
"strings"
21
22
23
+ "github.com/Shopify/sarama"
22
24
"github.com/spf13/viper"
23
25
24
26
"github.com/jaegertracing/jaeger/pkg/kafka/auth"
@@ -33,19 +35,69 @@ const (
33
35
// EncodingZipkinThrift is used for spans encoded as Zipkin Thrift.
34
36
EncodingZipkinThrift = "zipkin-thrift"
35
37
36
- configPrefix = "kafka.producer"
37
- suffixBrokers = ".brokers"
38
- suffixTopic = ".topic"
39
- suffixProtocolVersion = ".protocol-version"
40
- suffixEncoding = ".encoding"
41
- defaultBroker = "127.0.0.1:9092"
42
- defaultTopic = "jaeger-spans"
43
- defaultEncoding = EncodingProto
38
+ configPrefix = "kafka.producer"
39
+ suffixBrokers = ".brokers"
40
+ suffixTopic = ".topic"
41
+ suffixEncoding = ".encoding"
42
+ suffixRequiredAcks = ".required-acks"
43
+ suffixCompression = ".compression"
44
+ suffixCompressionLevel = ".compression-level"
45
+ suffixProtocolVersion = ".protocol-version"
46
+
47
+ defaultBroker = "127.0.0.1:9092"
48
+ defaultTopic = "jaeger-spans"
49
+ defaultEncoding = EncodingProto
50
+ defaultRequiredAcks = "local"
51
+ defaultCompression = "none"
52
+ defaultCompressionLevel = 0
44
53
)
45
54
46
55
var (
47
56
// AllEncodings is a list of all supported encodings.
48
57
AllEncodings = []string {EncodingJSON , EncodingProto , EncodingZipkinThrift }
58
+
59
+ //requiredAcks is mapping of sarama supported requiredAcks
60
+ requiredAcks = map [string ]sarama.RequiredAcks {
61
+ "noack" : sarama .NoResponse ,
62
+ "local" : sarama .WaitForLocal ,
63
+ "all" : sarama .WaitForAll ,
64
+ }
65
+
66
+ // compressionModes is a mapping of supported CompressionType to compressionCodec along with default, min, max compression level
67
+ // https://cwiki.apache.org/confluence/display/KAFKA/KIP-390%3A+Allow+fine-grained+configuration+for+compression
68
+ compressionModes = map [string ]struct {
69
+ compressor sarama.CompressionCodec
70
+ defaultCompressionLevel int
71
+ minCompressionLevel int
72
+ maxCompressionLevel int
73
+ }{
74
+ "none" : {
75
+ compressor : sarama .CompressionNone ,
76
+ defaultCompressionLevel : 0 ,
77
+ },
78
+ "gzip" : {
79
+ compressor : sarama .CompressionGZIP ,
80
+ defaultCompressionLevel : 6 ,
81
+ minCompressionLevel : 1 ,
82
+ maxCompressionLevel : 9 ,
83
+ },
84
+ "snappy" : {
85
+ compressor : sarama .CompressionSnappy ,
86
+ defaultCompressionLevel : 0 ,
87
+ },
88
+ "lz4" : {
89
+ compressor : sarama .CompressionLZ4 ,
90
+ defaultCompressionLevel : 9 ,
91
+ minCompressionLevel : 1 ,
92
+ maxCompressionLevel : 17 ,
93
+ },
94
+ "zstd" : {
95
+ compressor : sarama .CompressionZSTD ,
96
+ defaultCompressionLevel : 3 ,
97
+ minCompressionLevel : - 131072 ,
98
+ maxCompressionLevel : 22 ,
99
+ },
100
+ }
49
101
)
50
102
51
103
// Options stores the configuration options for Kafka
@@ -74,15 +126,50 @@ func (opt *Options) AddFlags(flagSet *flag.FlagSet) {
74
126
defaultEncoding ,
75
127
fmt .Sprintf (`Encoding of spans ("%s" or "%s") sent to kafka.` , EncodingJSON , EncodingProto ),
76
128
)
129
+ flagSet .String (
130
+ configPrefix + suffixRequiredAcks ,
131
+ defaultRequiredAcks ,
132
+ "(experimental) Required kafka broker acknowledgement. i.e. noack, local, all" ,
133
+ )
134
+ flagSet .String (
135
+ configPrefix + suffixCompression ,
136
+ defaultCompression ,
137
+ "(experimental) Type of compression (none, gzip, snappy, lz4, zstd) to use on messages" ,
138
+ )
139
+ flagSet .Int (
140
+ configPrefix + suffixCompressionLevel ,
141
+ defaultCompressionLevel ,
142
+ "(experimental) compression level to use on messages. gzip = 1-9 (default = 6), snappy = none, lz4 = 1-17 (default = 9), zstd = -131072 - 22 (default = 3)" ,
143
+ )
77
144
auth .AddFlags (configPrefix , flagSet )
78
145
}
79
146
80
147
// InitFromViper initializes Options with properties from viper
81
148
func (opt * Options ) InitFromViper (v * viper.Viper ) {
82
149
authenticationOptions := auth.AuthenticationConfig {}
83
150
authenticationOptions .InitFromViper (configPrefix , v )
151
+
152
+ requiredAcks , err := getRequiredAcks (v .GetString (configPrefix + suffixRequiredAcks ))
153
+ if err != nil {
154
+ log .Fatal (err )
155
+ }
156
+
157
+ compressionMode := strings .ToLower (v .GetString (configPrefix + suffixCompression ))
158
+ compressionModeCodec , err := getCompressionMode (compressionMode )
159
+ if err != nil {
160
+ log .Fatal (err )
161
+ }
162
+
163
+ compressionLevel , err := getCompressionLevel (compressionMode , v .GetInt (configPrefix + suffixCompressionLevel ))
164
+ if err != nil {
165
+ log .Fatal (err )
166
+ }
167
+
84
168
opt .config = producer.Configuration {
85
169
Brokers : strings .Split (stripWhiteSpace (v .GetString (configPrefix + suffixBrokers )), "," ),
170
+ RequiredAcks : requiredAcks ,
171
+ Compression : compressionModeCodec ,
172
+ CompressionLevel : compressionLevel ,
86
173
ProtocolVersion : v .GetString (configPrefix + suffixProtocolVersion ),
87
174
AuthenticationConfig : authenticationOptions ,
88
175
}
@@ -94,3 +181,40 @@ func (opt *Options) InitFromViper(v *viper.Viper) {
94
181
func stripWhiteSpace (str string ) string {
95
182
return strings .Replace (str , " " , "" , - 1 )
96
183
}
184
+
185
+ // getCompressionLevel to get compression level from compression type
186
+ func getCompressionLevel (mode string , compressionLevel int ) (int , error ) {
187
+ compressionModeData , ok := compressionModes [mode ]
188
+ if ! ok {
189
+ return 0 , fmt .Errorf ("cannot find compression mode for compressionMode %v" , mode )
190
+ }
191
+
192
+ if compressionLevel == defaultCompressionLevel {
193
+ return compressionModeData .defaultCompressionLevel , nil
194
+ }
195
+
196
+ if compressionModeData .minCompressionLevel > compressionLevel || compressionModeData .maxCompressionLevel < compressionLevel {
197
+ return 0 , fmt .Errorf ("compression level %d for '%s' is not within valid range [%d, %d]" , compressionLevel , mode , compressionModeData .minCompressionLevel , compressionModeData .maxCompressionLevel )
198
+ }
199
+
200
+ return compressionLevel , nil
201
+ }
202
+
203
+ //getCompressionMode maps input modes to sarama CompressionCodec
204
+ func getCompressionMode (mode string ) (sarama.CompressionCodec , error ) {
205
+ compressionMode , ok := compressionModes [mode ]
206
+ if ! ok {
207
+ return 0 , fmt .Errorf ("unknown compression mode: %v" , mode )
208
+ }
209
+
210
+ return compressionMode .compressor , nil
211
+ }
212
+
213
+ //getRequiredAcks maps input ack values to sarama requiredAcks
214
+ func getRequiredAcks (acks string ) (sarama.RequiredAcks , error ) {
215
+ requiredAcks , ok := requiredAcks [strings .ToLower (acks )]
216
+ if ! ok {
217
+ return 0 , fmt .Errorf ("unknown Required Ack: %s" , acks )
218
+ }
219
+ return requiredAcks , nil
220
+ }
0 commit comments