kafka-crab-js 2.0.1 → 2.1.0-alpha.2

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.
package/README.md CHANGED
@@ -128,6 +128,7 @@ This major version includes important breaking changes that improve API consiste
128
128
  8. [Best Practices](#best-practices)
129
129
  9. [Contributing](#contributing)
130
130
  10. [License](#license)
131
+ 11. [OpenTelemetry Instrumentation](#opentelemetry-instrumentation)
131
132
 
132
133
  ## Installation
133
134
 
@@ -468,6 +469,7 @@ You can find some examples on the [example](https://github.com/flash-tecnologia/
468
469
  | `logLevel` | `string` | `info` | Log level for the client |
469
470
  | `brokerAddressFamily` | `string` | `"v4"` | Address family to use for the connection (v4, v6) |
470
471
  | `configuration` | `Record<string, any>` | `{}` | Additional configuration options for the client. **v2.0.0+**: Now supports any value type (string, number, boolean, object) |
472
+ | `otel` | `KafkaOtelInstrumentationConfig \| false` | `undefined` | Enable and configure OpenTelemetry instrumentation (see [OpenTelemetry Instrumentation](#opentelemetry-instrumentation)) |
471
473
 
472
474
  ### ConsumerConfiguration
473
475
 
@@ -500,6 +502,30 @@ You can find some examples on the [example](https://github.com/flash-tecnologia/
500
502
 
501
503
  You can see the available options here: [librdkafka](https://docs.confluent.io/platform/current/clients/librdkafka/html/md_CONFIGURATION.html).
502
504
 
505
+ ### OpenTelemetry Configuration
506
+
507
+ OpenTelemetry is enabled by default when the `otel` field is omitted or set to an object. Set `otel: false` to disable instrumentation entirely.
508
+
509
+ ```ts
510
+ const client = new KafkaClient({
511
+ brokers: 'localhost:29092',
512
+ clientId: 'payments-service',
513
+ otel: {
514
+ serviceName: 'payments-api',
515
+ ignoreTopics: topic => topic.startsWith('internal.'),
516
+ messageHook: (span, message) => {
517
+ span.setAttribute('app.message.key', message.key?.toString('utf8'))
518
+ },
519
+ },
520
+ })
521
+ ```
522
+
523
+ When instrumentation is active:
524
+
525
+ - Producer `send` calls automatically propagate the active span context via Kafka headers while preserving custom headers and their Buffer/string types.
526
+ - Consumer `recv`, `recvBatch`, and stream consumers generate spans that capture consumer group, topic, partition, offset, and batch size.
527
+ - Hooks registered through `messageHook` and `producerHook` execute within the active span context so that additional attributes/events can be attached safely.
528
+
503
529
  ## Performance Benchmarks
504
530
 
505
531
  ### Running Benchmarks
@@ -625,6 +651,60 @@ npx tsx benchmark/utils/setup.ts
625
651
  npx tsx benchmark/consumer.ts
626
652
  ```
627
653
 
654
+ ## OpenTelemetry Instrumentation
655
+
656
+ Kafka Crab JS offers turnkey tracing for Kafka workloads:
657
+
658
+ - **Seamless propagation** – Producer instrumentation injects `traceparent`/`tracestate` into Kafka headers while retaining any existing headers (including `Buffer` values) so downstream systems continue to see custom metadata.
659
+ - **Consumer & stream coverage** – Standard consumers, batch consumers, and `createStreamConsumer` streams emit spans that include consumer group, topic, partition, offset, and batch size semantics.
660
+ - **Hook-friendly spans** – Both `messageHook` and `producerHook` callbacks run inside the active span context, simplifying attribute decoration or error handling.
661
+ - **Header normalization helpers** – The runtime automatically normalizes mixed header carriers to Buffers when talking to the native binding, removing the need for manual conversions.
662
+
663
+ ### Minimal Setup Example
664
+
665
+ ```ts
666
+ import { KafkaClient } from 'kafka-crab-js'
667
+ import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'
668
+ import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'
669
+ import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'
670
+ import { context } from '@opentelemetry/api'
671
+
672
+ const provider = new NodeTracerProvider()
673
+ provider.addSpanProcessor(new SimpleSpanProcessor(exporter))
674
+ provider.register()
675
+
676
+ context.setGlobalContextManager(new AsyncHooksContextManager().enable())
677
+
678
+ const client = new KafkaClient({
679
+ brokers: 'localhost:29092',
680
+ clientId: 'orders-api',
681
+ otel: {
682
+ serviceName: 'orders-service',
683
+ producerHook: span => span.setAttribute('messaging.client.kind', 'producer'),
684
+ },
685
+ })
686
+
687
+ const producer = client.createProducer()
688
+ await producer.send({
689
+ topic: 'orders',
690
+ messages: [{
691
+ payload: Buffer.from(JSON.stringify({ orderId: '123' })),
692
+ headers: { 'custom-header': 'foo' },
693
+ }],
694
+ })
695
+
696
+ const consumer = client.createStreamConsumer({
697
+ groupId: 'orders-consumer',
698
+ enableAutoCommit: false,
699
+ })
700
+
701
+ consumer.on('data', message => {
702
+ console.log(message.headers?.['custom-header']?.toString())
703
+ })
704
+ ```
705
+
706
+ Set `otel: false` in the client configuration to opt-out.
707
+
628
708
  ## License
629
709
 
630
710
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.