@@ -113,6 +113,7 @@ def instrument_consumer(consumer: Consumer, tracer_provider=None)
113
113
from .utils import (
114
114
KafkaPropertiesExtractor ,
115
115
_enrich_span ,
116
+ _get_links_from_records ,
116
117
_get_span_name ,
117
118
_kafka_getter ,
118
119
_kafka_setter ,
@@ -136,6 +137,10 @@ def __init__(self, config):
136
137
# This method is deliberately implemented in order to allow wrapt to wrap this function
137
138
def poll (self , timeout = - 1 ): # pylint: disable=useless-super-delegation
138
139
return super ().poll (timeout )
140
+
141
+ # This method is deliberately implemented in order to allow wrapt to wrap this function
142
+ def consume (self , * args , ** kwargs ): # pylint: disable=useless-super-delegation
143
+ return super ().consume (* args , ** kwargs )
139
144
140
145
141
146
class ProxiedProducer (Producer ):
@@ -178,9 +183,11 @@ def commit(self, *args, **kwargs):
178
183
return self ._consumer .commit (* args , ** kwargs )
179
184
180
185
def consume (
181
- self , num_messages = 1 , * args , ** kwargs
186
+ self , * args , ** kwargs
182
187
): # pylint: disable=keyword-arg-before-vararg
183
- return self ._consumer .consume (num_messages , * args , ** kwargs )
188
+ return ConfluentKafkaInstrumentor .wrap_consume (
189
+ self ._consumer .consume , self , self ._tracer , args , kwargs ,
190
+ )
184
191
185
192
def get_watermark_offsets (
186
193
self , partition , timeout = - 1 , * args , ** kwargs
@@ -274,6 +281,11 @@ def _inner_wrap_poll(func, instance, args, kwargs):
274
281
return ConfluentKafkaInstrumentor .wrap_poll (
275
282
func , instance , self ._tracer , args , kwargs
276
283
)
284
+
285
+ def _inner_wrap_consume (func , instance , args , kwargs ):
286
+ return ConfluentKafkaInstrumentor .wrap_consume (
287
+ func , instance , self ._tracer , args , kwargs
288
+ )
277
289
278
290
wrapt .wrap_function_wrapper (
279
291
AutoInstrumentedProducer ,
@@ -286,6 +298,12 @@ def _inner_wrap_poll(func, instance, args, kwargs):
286
298
"poll" ,
287
299
_inner_wrap_poll ,
288
300
)
301
+
302
+ wrapt .wrap_function_wrapper (
303
+ AutoInstrumentedConsumer ,
304
+ "consume" ,
305
+ _inner_wrap_consume ,
306
+ )
289
307
290
308
def _uninstrument (self , ** kwargs ):
291
309
confluent_kafka .Producer = self ._original_kafka_producer
@@ -336,13 +354,7 @@ def wrap_poll(func, instance, tracer, args, kwargs):
336
354
):
337
355
record = func (* args , ** kwargs )
338
356
if record :
339
- links = []
340
- ctx = propagate .extract (record .headers (), getter = _kafka_getter )
341
- if ctx :
342
- for item in ctx .values ():
343
- if hasattr (item , "get_span_context" ):
344
- links .append (Link (context = item .get_span_context ()))
345
-
357
+ links = _get_links_from_records ([record ])
346
358
instance ._current_consume_span = tracer .start_span (
347
359
name = f"{ record .topic ()} process" ,
348
360
links = links ,
@@ -361,3 +373,35 @@ def wrap_poll(func, instance, tracer, args, kwargs):
361
373
)
362
374
363
375
return record
376
+
377
+ @staticmethod
378
+ def wrap_consume (func , instance , tracer , args , kwargs ):
379
+ if instance ._current_consume_span :
380
+ context .detach (instance ._current_context_token )
381
+ instance ._current_context_token = None
382
+ instance ._current_consume_span .end ()
383
+ instance ._current_consume_span = None
384
+
385
+ with tracer .start_as_current_span (
386
+ "recv" , end_on_exit = True , kind = trace .SpanKind .CONSUMER
387
+ ):
388
+ records = func (* args , ** kwargs )
389
+ if len (records ) > 0 :
390
+ links = _get_links_from_records (records )
391
+ instance ._current_consume_span = tracer .start_span (
392
+ name = f"{ records [0 ].topic ()} process" ,
393
+ links = links ,
394
+ kind = SpanKind .CONSUMER ,
395
+ )
396
+
397
+ _enrich_span (
398
+ instance ._current_consume_span ,
399
+ records [0 ].topic (),
400
+ operation = MessagingOperationValues .PROCESS ,
401
+ )
402
+
403
+ instance ._current_context_token = context .attach (
404
+ trace .set_span_in_context (instance ._current_consume_span )
405
+ )
406
+
407
+ return records
0 commit comments