opentelemetry-instrumentation-confluent-kafka 0.46b0__tar.gz → 0.48b0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (12) hide show
  1. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/.gitignore +3 -0
  2. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/PKG-INFO +7 -3
  3. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/pyproject.toml +6 -2
  4. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +27 -0
  5. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/src/opentelemetry/instrumentation/confluent_kafka/package.py +1 -1
  6. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/src/opentelemetry/instrumentation/confluent_kafka/version.py +1 -1
  7. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/tests/test_instrumentation.py +37 -0
  8. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/LICENSE +0 -0
  9. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/README.rst +0 -0
  10. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/src/opentelemetry/instrumentation/confluent_kafka/utils.py +0 -0
  11. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/tests/__init__.py +0 -0
  12. {opentelemetry_instrumentation_confluent_kafka-0.46b0 → opentelemetry_instrumentation_confluent_kafka-0.48b0}/tests/utils.py +0 -0
@@ -58,3 +58,6 @@ _build/
58
58
  # mypy
59
59
  .mypy_cache/
60
60
  target
61
+
62
+ # Benchmark result files
63
+ *-benchmark.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: opentelemetry-instrumentation-confluent-kafka
3
- Version: 0.46b0
3
+ Version: 0.48b0
4
4
  Summary: OpenTelemetry Confluent Kafka instrumentation
5
5
  Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-confluent-kafka
6
6
  Author-email: OpenTelemetry Authors <cncf-opentelemetry-contributors@lists.cncf.io>
@@ -12,12 +12,16 @@ Classifier: License :: OSI Approved :: Apache Software License
12
12
  Classifier: Programming Language :: Python
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
15
19
  Requires-Python: >=3.8
16
20
  Requires-Dist: opentelemetry-api~=1.12
17
- Requires-Dist: opentelemetry-instrumentation==0.46b0
21
+ Requires-Dist: opentelemetry-instrumentation==0.48b0
18
22
  Requires-Dist: wrapt<2.0.0,>=1.0.0
19
23
  Provides-Extra: instruments
20
- Requires-Dist: confluent-kafka<=2.3.0,>=1.8.2; extra == 'instruments'
24
+ Requires-Dist: confluent-kafka<=2.4.0,>=1.8.2; extra == 'instruments'
21
25
  Description-Content-Type: text/x-rst
22
26
 
23
27
  OpenTelemetry confluent-kafka Instrumentation
@@ -19,16 +19,20 @@ classifiers = [
19
19
  "Programming Language :: Python",
20
20
  "Programming Language :: Python :: 3",
21
21
  "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
22
26
  ]
23
27
  dependencies = [
24
- "opentelemetry-instrumentation == 0.46b0",
28
+ "opentelemetry-instrumentation == 0.48b0",
25
29
  "opentelemetry-api ~= 1.12",
26
30
  "wrapt >= 1.0.0, < 2.0.0",
27
31
  ]
28
32
 
29
33
  [project.optional-dependencies]
30
34
  instruments = [
31
- "confluent-kafka >= 1.8.2, <= 2.3.0",
35
+ "confluent-kafka >= 1.8.2, <= 2.4.0",
32
36
  ]
33
37
 
34
38
  [project.entry-points.opentelemetry_instrumentor]
@@ -144,6 +144,10 @@ class AutoInstrumentedConsumer(Consumer):
144
144
  ): # pylint: disable=useless-super-delegation
145
145
  return super().consume(*args, **kwargs)
146
146
 
147
+ # This method is deliberately implemented in order to allow wrapt to wrap this function
148
+ def close(self): # pylint: disable=useless-super-delegation
149
+ return super().close()
150
+
147
151
 
148
152
  class ProxiedProducer(Producer):
149
153
  def __init__(self, producer: Producer, tracer: Tracer):
@@ -156,6 +160,9 @@ class ProxiedProducer(Producer):
156
160
  def poll(self, timeout=-1):
157
161
  return self._producer.poll(timeout)
158
162
 
163
+ def purge(self, in_queue=True, in_flight=True, blocking=True):
164
+ self._producer.purge(in_queue, in_flight, blocking)
165
+
159
166
  def produce(
160
167
  self, topic, value=None, *args, **kwargs
161
168
  ): # pylint: disable=keyword-arg-before-vararg
@@ -178,6 +185,11 @@ class ProxiedConsumer(Consumer):
178
185
  self._current_consume_span = None
179
186
  self._current_context_token = None
180
187
 
188
+ def close(self):
189
+ return ConfluentKafkaInstrumentor.wrap_close(
190
+ self._consumer.close, self
191
+ )
192
+
181
193
  def committed(self, partitions, timeout=-1):
182
194
  return self._consumer.committed(partitions, timeout)
183
195
 
@@ -300,6 +312,9 @@ class ConfluentKafkaInstrumentor(BaseInstrumentor):
300
312
  func, instance, self._tracer, args, kwargs
301
313
  )
302
314
 
315
+ def _inner_wrap_close(func, instance):
316
+ return ConfluentKafkaInstrumentor.wrap_close(func, instance)
317
+
303
318
  wrapt.wrap_function_wrapper(
304
319
  AutoInstrumentedProducer,
305
320
  "produce",
@@ -318,6 +333,12 @@ class ConfluentKafkaInstrumentor(BaseInstrumentor):
318
333
  _inner_wrap_consume,
319
334
  )
320
335
 
336
+ wrapt.wrap_function_wrapper(
337
+ AutoInstrumentedConsumer,
338
+ "close",
339
+ _inner_wrap_close,
340
+ )
341
+
321
342
  def _uninstrument(self, **kwargs):
322
343
  confluent_kafka.Producer = self._original_kafka_producer
323
344
  confluent_kafka.Consumer = self._original_kafka_consumer
@@ -400,3 +421,9 @@ class ConfluentKafkaInstrumentor(BaseInstrumentor):
400
421
  )
401
422
 
402
423
  return records
424
+
425
+ @staticmethod
426
+ def wrap_close(func, instance):
427
+ if instance._current_consume_span:
428
+ _end_current_consume_span(instance)
429
+ func()
@@ -13,4 +13,4 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
- _instruments = ("confluent-kafka >= 1.8.2, <= 2.3.0",)
16
+ _instruments = ("confluent-kafka >= 1.8.2, <= 2.4.0",)
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "0.46b0"
15
+ __version__ = "0.48b0"
@@ -237,7 +237,44 @@ class TestConfluentKafka(TestBase):
237
237
  span_list = self.memory_exporter.get_finished_spans()
238
238
  self._compare_spans(span_list, expected_spans)
239
239
 
240
+ def test_close(self) -> None:
241
+ instrumentation = ConfluentKafkaInstrumentor()
242
+ mocked_messages = [
243
+ MockedMessage("topic-a", 0, 0, []),
244
+ ]
245
+ expected_spans = [
246
+ {"name": "recv", "attributes": {}},
247
+ {
248
+ "name": "topic-a process",
249
+ "attributes": {
250
+ SpanAttributes.MESSAGING_OPERATION: "process",
251
+ SpanAttributes.MESSAGING_KAFKA_PARTITION: 0,
252
+ SpanAttributes.MESSAGING_SYSTEM: "kafka",
253
+ SpanAttributes.MESSAGING_DESTINATION: "topic-a",
254
+ SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value,
255
+ SpanAttributes.MESSAGING_MESSAGE_ID: "topic-a.0.0",
256
+ },
257
+ },
258
+ ]
259
+
260
+ consumer = MockConsumer(
261
+ mocked_messages,
262
+ {
263
+ "bootstrap.servers": "localhost:29092",
264
+ "group.id": "mygroup",
265
+ "auto.offset.reset": "earliest",
266
+ },
267
+ )
268
+ self.memory_exporter.clear()
269
+ consumer = instrumentation.instrument_consumer(consumer)
270
+ consumer.poll()
271
+ consumer.close()
272
+
273
+ span_list = self.memory_exporter.get_finished_spans()
274
+ self._compare_spans(span_list, expected_spans)
275
+
240
276
  def _compare_spans(self, spans, expected_spans):
277
+ self.assertEqual(len(spans), len(expected_spans))
241
278
  for span, expected_span in zip(spans, expected_spans):
242
279
  self.assertEqual(expected_span["name"], span.name)
243
280
  for attribute_key, expected_attribute_value in expected_span[