@loipv/nestjs-kafka 0.0.7 → 0.1.0
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 +262 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/consumer-options.interface.d.ts +1 -0
- package/dist/interfaces/kafka-module-options.interface.d.ts +6 -0
- package/dist/interfaces/kafka-module-options.interface.js.map +1 -1
- package/dist/kafka.module.js +9 -0
- package/dist/kafka.module.js.map +1 -1
- package/dist/services/consumer-registry.service.d.ts +7 -1
- package/dist/services/consumer-registry.service.js +112 -13
- package/dist/services/consumer-registry.service.js.map +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/kafka-client.service.d.ts +3 -1
- package/dist/services/kafka-client.service.js +51 -6
- package/dist/services/kafka-client.service.js.map +1 -1
- package/dist/services/tracing.service.d.ts +56 -0
- package/dist/services/tracing.service.js +286 -0
- package/dist/services/tracing.service.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +15 -2
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ A production-ready NestJS module for Kafka client and consumer functionality bui
|
|
|
11
11
|
- **Back Pressure**: Automatic pause/resume when consumers are overwhelmed
|
|
12
12
|
- **Idempotency**: In-memory duplicate prevention with TTL
|
|
13
13
|
- **Dead Letter Queue (DLQ)**: Automatic retry with exponential backoff
|
|
14
|
+
- **OpenTelemetry Tracing**: Distributed tracing across produce → consume with same trace ID
|
|
14
15
|
- **Health Checks**: Integration with `@nestjs/terminus`
|
|
15
16
|
- **Graceful Shutdown**: Proper cleanup on application shutdown
|
|
16
17
|
|
|
@@ -28,6 +29,14 @@ Make sure you have the following peer dependencies installed:
|
|
|
28
29
|
npm install @nestjs/common @nestjs/core @nestjs/terminus reflect-metadata rxjs
|
|
29
30
|
```
|
|
30
31
|
|
|
32
|
+
### Optional: OpenTelemetry Tracing
|
|
33
|
+
|
|
34
|
+
For distributed tracing support:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/auto-instrumentations-node
|
|
38
|
+
```
|
|
39
|
+
|
|
31
40
|
## Quick Start
|
|
32
41
|
|
|
33
42
|
### 1. Import KafkaModule
|
|
@@ -481,6 +490,49 @@ async handleBinary(message: KafkaMessage) {
|
|
|
481
490
|
|
|
482
491
|
### Retry & Restart on Failure
|
|
483
492
|
|
|
493
|
+
#### Retry Mechanism (Without DLQ)
|
|
494
|
+
|
|
495
|
+
When **NOT using DLQ**, the library implements an in-memory retry mechanism with exponential backoff:
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
@Consumer('orders', {
|
|
499
|
+
retry: {
|
|
500
|
+
retries: 3, // Default: 3 retries
|
|
501
|
+
initialRetryTime: 1000, // Default: 1000ms
|
|
502
|
+
multiplier: 2, // Default: 2 (exponential backoff)
|
|
503
|
+
skipMessageOnMaxRetries: false, // Default: false (throw error)
|
|
504
|
+
},
|
|
505
|
+
})
|
|
506
|
+
async handleOrders(message: KafkaMessagePayload) {
|
|
507
|
+
// If this fails, it will retry: 1s, 2s, 4s delays
|
|
508
|
+
// After 3 retries, error is thrown (consumer may stop/restart)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Skip message to avoid blocking consumer (useful for multi-topic consumers)
|
|
512
|
+
@Consumer('non-critical-logs', {
|
|
513
|
+
retry: {
|
|
514
|
+
retries: 5,
|
|
515
|
+
skipMessageOnMaxRetries: true, // Skip message after max retries
|
|
516
|
+
},
|
|
517
|
+
})
|
|
518
|
+
async handleLogs(message: KafkaMessagePayload) {
|
|
519
|
+
// If this fails 5 times, message is skipped (offset committed)
|
|
520
|
+
// Consumer continues processing next message
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
**Important Notes:**
|
|
525
|
+
- **Default behavior** (`skipMessageOnMaxRetries: false`): Error is thrown after max retries, ensuring no message is silently dropped
|
|
526
|
+
- **Skip mode** (`skipMessageOnMaxRetries: true`): Message is skipped after max retries to prevent consumer blocking
|
|
527
|
+
- **With DLQ**: Messages are sent to DLQ topic after max retries (recommended approach)
|
|
528
|
+
|
|
529
|
+
**When to use skip mode:**
|
|
530
|
+
- Multi-topic consumers where one failing topic shouldn't block others
|
|
531
|
+
- Non-critical messages that can be safely dropped
|
|
532
|
+
- Development/debugging environments
|
|
533
|
+
|
|
534
|
+
#### Consumer Restart Control
|
|
535
|
+
|
|
484
536
|
Control consumer restart behavior when errors occur:
|
|
485
537
|
|
|
486
538
|
```typescript
|
|
@@ -574,6 +626,7 @@ interface ConsumerOptions {
|
|
|
574
626
|
factor?: number; // Default: 0.2
|
|
575
627
|
multiplier?: number; // Default: 2
|
|
576
628
|
restartOnFailure?: boolean | ((error: Error) => Promise<boolean>);
|
|
629
|
+
skipMessageOnMaxRetries?: boolean; // Default: false (throw error after max retries)
|
|
577
630
|
};
|
|
578
631
|
}
|
|
579
632
|
```
|
|
@@ -680,6 +733,213 @@ export class HealthController {
|
|
|
680
733
|
}
|
|
681
734
|
```
|
|
682
735
|
|
|
736
|
+
## OpenTelemetry Tracing
|
|
737
|
+
|
|
738
|
+
The library supports distributed tracing with OpenTelemetry, allowing you to trace messages from producer to consumer with the same trace ID.
|
|
739
|
+
|
|
740
|
+
### How It Works
|
|
741
|
+
|
|
742
|
+
1. **Producer**: When sending a message, the library creates a span and injects the trace context (W3C Trace Context format) into Kafka message headers
|
|
743
|
+
2. **Consumer**: When receiving a message, the library extracts the trace context from headers and creates a child span linked to the producer's trace
|
|
744
|
+
3. **Batch Consumer**: For batch processing, the first message's trace becomes the parent, and all other messages are added as span links
|
|
745
|
+
|
|
746
|
+
```
|
|
747
|
+
┌─────────────────┐ ┌─────────────────┐
|
|
748
|
+
│ HTTP Request │ │ Consumer App │
|
|
749
|
+
│ TraceID: abc │ │ │
|
|
750
|
+
│ ┌───────────┐ │ Kafka Topic │ ┌───────────┐ │
|
|
751
|
+
│ │ publish │──┼─────────────────────────┼──│ process │ │
|
|
752
|
+
│ │ span │ │ Headers: │ │ span │ │
|
|
753
|
+
│ │ │ │ traceparent: 00-abc... │ │ │ │
|
|
754
|
+
│ └───────────┘ │ │ └───────────┘ │
|
|
755
|
+
│ │ │ TraceID: abc │
|
|
756
|
+
└─────────────────┘ └─────────────────┘
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
### Prerequisites
|
|
760
|
+
|
|
761
|
+
1. Install OpenTelemetry packages:
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
2. **IMPORTANT**: Initialize OpenTelemetry SDK **BEFORE** your NestJS app starts:
|
|
768
|
+
|
|
769
|
+
```typescript
|
|
770
|
+
// tracing.ts
|
|
771
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
772
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
773
|
+
import { Resource } from '@opentelemetry/resources';
|
|
774
|
+
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
|
|
775
|
+
|
|
776
|
+
const sdk = new NodeSDK({
|
|
777
|
+
resource: new Resource({
|
|
778
|
+
[ATTR_SERVICE_NAME]: 'my-kafka-service',
|
|
779
|
+
}),
|
|
780
|
+
traceExporter: new OTLPTraceExporter({
|
|
781
|
+
url: 'http://localhost:4318/v1/traces', // Jaeger/OTLP endpoint
|
|
782
|
+
}),
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
sdk.start();
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
// main.ts
|
|
790
|
+
import './tracing'; // MUST be first import
|
|
791
|
+
import { NestFactory } from '@nestjs/core';
|
|
792
|
+
import { AppModule } from './app.module';
|
|
793
|
+
|
|
794
|
+
async function bootstrap() {
|
|
795
|
+
const app = await NestFactory.create(AppModule);
|
|
796
|
+
await app.listen(3000);
|
|
797
|
+
}
|
|
798
|
+
bootstrap();
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Important: Disable KafkaJS Auto-Instrumentation
|
|
802
|
+
|
|
803
|
+
If you're using `@opentelemetry/auto-instrumentations-node`, you **MUST** disable the KafkaJS auto-instrumentation to use this library's tracing. Otherwise, you'll get duplicate spans and the library's spans (with `consumer.group` attribute) won't be used.
|
|
804
|
+
|
|
805
|
+
```typescript
|
|
806
|
+
// tracing.ts
|
|
807
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
808
|
+
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
809
|
+
|
|
810
|
+
const sdk = new NodeSDK({
|
|
811
|
+
instrumentations: [
|
|
812
|
+
getNodeAutoInstrumentations({
|
|
813
|
+
// Disable kafkajs auto-instrumentation
|
|
814
|
+
'@opentelemetry/instrumentation-kafkajs': {
|
|
815
|
+
enabled: false,
|
|
816
|
+
},
|
|
817
|
+
}),
|
|
818
|
+
],
|
|
819
|
+
// ... other config
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
sdk.start();
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### Enable Tracing
|
|
826
|
+
|
|
827
|
+
```typescript
|
|
828
|
+
// app.module.ts
|
|
829
|
+
import { Module } from '@nestjs/common';
|
|
830
|
+
import { KafkaModule, ConsumerModule } from '@loipv/nestjs-kafka';
|
|
831
|
+
|
|
832
|
+
@Module({
|
|
833
|
+
imports: [
|
|
834
|
+
KafkaModule.forRoot({
|
|
835
|
+
clientId: 'my-app',
|
|
836
|
+
brokers: ['localhost:9092'],
|
|
837
|
+
tracing: {
|
|
838
|
+
enabled: true, // Required: enable tracing
|
|
839
|
+
tracerName: 'my-kafka-service', // Optional: custom tracer name
|
|
840
|
+
tracerVersion: '1.0.0', // Optional: custom tracer version
|
|
841
|
+
},
|
|
842
|
+
}),
|
|
843
|
+
ConsumerModule.forRoot(),
|
|
844
|
+
],
|
|
845
|
+
})
|
|
846
|
+
export class AppModule {}
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
### Tracing Options
|
|
850
|
+
|
|
851
|
+
| Option | Type | Default | Description |
|
|
852
|
+
|--------|------|---------|-------------|
|
|
853
|
+
| `enabled` | boolean | `false` | Enable OpenTelemetry tracing |
|
|
854
|
+
| `tracerName` | string | `'@loipv/nestjs-kafka'` | Custom tracer name |
|
|
855
|
+
| `tracerVersion` | string | `'0.0.1'` | Custom tracer version |
|
|
856
|
+
|
|
857
|
+
### Span Names
|
|
858
|
+
|
|
859
|
+
Span names include the consumer group for easy identification in tracing UI:
|
|
860
|
+
|
|
861
|
+
| Type | Span Name Format | Example |
|
|
862
|
+
|------|------------------|---------|
|
|
863
|
+
| Producer | `{topic} publish` | `orders publish` |
|
|
864
|
+
| Consumer | `{groupId} {topic} process` | `order-group orders process` |
|
|
865
|
+
| Batch Consumer | `{groupId} {topic} process batch` | `order-group orders process batch` |
|
|
866
|
+
|
|
867
|
+
### Span Attributes (OpenTelemetry Semantic Conventions v1.24+)
|
|
868
|
+
|
|
869
|
+
**Producer Span:**
|
|
870
|
+
|
|
871
|
+
| Attribute | Example | Description |
|
|
872
|
+
|-----------|---------|-------------|
|
|
873
|
+
| `messaging.system` | `kafka` | Messaging system |
|
|
874
|
+
| `messaging.destination.name` | `orders` | Topic name |
|
|
875
|
+
| `messaging.operation.name` | `publish` | Operation name |
|
|
876
|
+
| `messaging.operation.type` | `publish` | Operation type |
|
|
877
|
+
| `messaging.destination.partition.id` | `0` | Partition (if specified) |
|
|
878
|
+
| `messaging.kafka.message.key` | `customer-123` | Message key (if present) |
|
|
879
|
+
|
|
880
|
+
**Consumer Span:**
|
|
881
|
+
|
|
882
|
+
| Attribute | Example | Description |
|
|
883
|
+
|-----------|---------|-------------|
|
|
884
|
+
| `messaging.system` | `kafka` | Messaging system |
|
|
885
|
+
| `messaging.destination.name` | `orders` | Topic name |
|
|
886
|
+
| `messaging.destination.partition.id` | `0` | Partition number |
|
|
887
|
+
| `messaging.operation.name` | `process` | Operation name |
|
|
888
|
+
| `messaging.operation.type` | `process` | Operation type |
|
|
889
|
+
| `messaging.kafka.offset` | `12345` | Message offset |
|
|
890
|
+
| `messaging.kafka.consumer.group` | `order-group` | Consumer group ID |
|
|
891
|
+
| `messaging.kafka.message.key` | `customer-123` | Message key (if present) |
|
|
892
|
+
|
|
893
|
+
**Batch Consumer Span (additional):**
|
|
894
|
+
|
|
895
|
+
| Attribute | Example | Description |
|
|
896
|
+
|-----------|---------|-------------|
|
|
897
|
+
| `messaging.batch.message_count` | `100` | Number of messages in batch |
|
|
898
|
+
|
|
899
|
+
### Batch Tracing with Links
|
|
900
|
+
|
|
901
|
+
For batch consumers (`batch: true`), messages from different requests/traces are processed together. The library handles this by:
|
|
902
|
+
|
|
903
|
+
1. **First message's trace** becomes the **parent** (for trace continuity)
|
|
904
|
+
2. **All other messages** are added as **span links** (shows relationship in tracing UI)
|
|
905
|
+
|
|
906
|
+
```
|
|
907
|
+
Request A (trace-A) ──publish──▶ Message 1 ──┐
|
|
908
|
+
Request B (trace-B) ──publish──▶ Message 2 ──┼──▶ Batch Consumer Span
|
|
909
|
+
Request C (trace-C) ──publish──▶ Message 3 ──┘ │
|
|
910
|
+
├── Parent: trace-A
|
|
911
|
+
└── Links: [trace-B, trace-C]
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
This allows you to:
|
|
915
|
+
- Follow the full trace from the first message's request
|
|
916
|
+
- See all related traces via span links in your tracing UI (Jaeger, Zipkin, etc.)
|
|
917
|
+
|
|
918
|
+
### Trace Context Propagation
|
|
919
|
+
|
|
920
|
+
The library uses W3C Trace Context format for propagation via Kafka headers:
|
|
921
|
+
|
|
922
|
+
| Header | Format | Example |
|
|
923
|
+
|--------|--------|---------|
|
|
924
|
+
| `traceparent` | `{version}-{traceId}-{spanId}-{flags}` | `00-abc123...-def456...-01` |
|
|
925
|
+
| `tracestate` | Vendor-specific state | `vendor=value` |
|
|
926
|
+
|
|
927
|
+
### Troubleshooting
|
|
928
|
+
|
|
929
|
+
**No spans appearing:**
|
|
930
|
+
1. Ensure `tracing.enabled: true` in KafkaModule options
|
|
931
|
+
2. Ensure OpenTelemetry SDK is initialized **before** NestJS app starts
|
|
932
|
+
3. Ensure `@opentelemetry/api` is installed
|
|
933
|
+
4. If using auto-instrumentations, disable `@opentelemetry/instrumentation-kafkajs`
|
|
934
|
+
|
|
935
|
+
**Missing `messaging.kafka.consumer.group` attribute:**
|
|
936
|
+
- You're likely using `@opentelemetry/instrumentation-kafkajs` which creates its own spans
|
|
937
|
+
- Disable it and use this library's TracingService instead
|
|
938
|
+
|
|
939
|
+
**Duplicate spans:**
|
|
940
|
+
- Both auto-instrumentation and this library are creating spans
|
|
941
|
+
- Disable `@opentelemetry/instrumentation-kafkajs` in auto-instrumentations config
|
|
942
|
+
|
|
683
943
|
## API Reference
|
|
684
944
|
|
|
685
945
|
### Exports
|
|
@@ -694,6 +954,7 @@ export { Consumer } from './decorators';
|
|
|
694
954
|
|
|
695
955
|
// Services
|
|
696
956
|
export { KafkaClient } from './services/kafka-client.service';
|
|
957
|
+
export { TracingService } from './services/tracing.service';
|
|
697
958
|
export { DlqMetricsService } from './services/dlq-metrics.service';
|
|
698
959
|
export { CircuitBreakerService } from './services/circuit-breaker.service';
|
|
699
960
|
|
|
@@ -704,6 +965,7 @@ export { KafkaHealthIndicator } from './health/kafka-health-indicator';
|
|
|
704
965
|
export {
|
|
705
966
|
KafkaModuleOptions,
|
|
706
967
|
KafkaModuleAsyncOptions,
|
|
968
|
+
TracingOptions,
|
|
707
969
|
ConsumerOptions,
|
|
708
970
|
DlqOptions,
|
|
709
971
|
DlqRetryOptions,
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export { KafkaModule } from './kafka.module';
|
|
|
2
2
|
export { ConsumerModule } from './consumer.module';
|
|
3
3
|
export { Consumer, InjectKafkaClient } from './decorators';
|
|
4
4
|
export { KafkaClient, ConnectionBoundClient, } from './services/kafka-client.service';
|
|
5
|
+
export { TracingService } from './services/tracing.service';
|
|
5
6
|
export { KafkaHealthIndicator } from './health/kafka-health-indicator';
|
|
6
7
|
export * from './interfaces';
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.KafkaHealthIndicator = exports.ConnectionBoundClient = exports.KafkaClient = exports.InjectKafkaClient = exports.Consumer = exports.ConsumerModule = exports.KafkaModule = void 0;
|
|
17
|
+
exports.KafkaHealthIndicator = exports.TracingService = exports.ConnectionBoundClient = exports.KafkaClient = exports.InjectKafkaClient = exports.Consumer = exports.ConsumerModule = exports.KafkaModule = void 0;
|
|
18
18
|
var kafka_module_1 = require("./kafka.module");
|
|
19
19
|
Object.defineProperty(exports, "KafkaModule", { enumerable: true, get: function () { return kafka_module_1.KafkaModule; } });
|
|
20
20
|
var consumer_module_1 = require("./consumer.module");
|
|
@@ -25,6 +25,8 @@ Object.defineProperty(exports, "InjectKafkaClient", { enumerable: true, get: fun
|
|
|
25
25
|
var kafka_client_service_1 = require("./services/kafka-client.service");
|
|
26
26
|
Object.defineProperty(exports, "KafkaClient", { enumerable: true, get: function () { return kafka_client_service_1.KafkaClient; } });
|
|
27
27
|
Object.defineProperty(exports, "ConnectionBoundClient", { enumerable: true, get: function () { return kafka_client_service_1.ConnectionBoundClient; } });
|
|
28
|
+
var tracing_service_1 = require("./services/tracing.service");
|
|
29
|
+
Object.defineProperty(exports, "TracingService", { enumerable: true, get: function () { return tracing_service_1.TracingService; } });
|
|
28
30
|
var kafka_health_indicator_1 = require("./health/kafka-health-indicator");
|
|
29
31
|
Object.defineProperty(exports, "KafkaHealthIndicator", { enumerable: true, get: function () { return kafka_health_indicator_1.KafkaHealthIndicator; } });
|
|
30
32
|
__exportStar(require("./interfaces"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AAGvB,2CAA2D;AAAlD,sGAAA,QAAQ,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AAGpC,wEAGyC;AAFvC,mHAAA,WAAW,OAAA;AACX,6HAAA,qBAAqB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AAGvB,2CAA2D;AAAlD,sGAAA,QAAQ,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AAGpC,wEAGyC;AAFvC,mHAAA,WAAW,OAAA;AACX,6HAAA,qBAAqB,OAAA;AAEvB,8DAA4D;AAAnD,iHAAA,cAAc,OAAA;AAGvB,0EAAuE;AAA9D,8HAAA,oBAAoB,OAAA;AAG7B,+CAA6B"}
|
|
@@ -17,6 +17,11 @@ export interface ProducerConfig {
|
|
|
17
17
|
transactionTimeout?: number;
|
|
18
18
|
maxInFlightRequests?: number;
|
|
19
19
|
}
|
|
20
|
+
export interface TracingOptions {
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
tracerName?: string;
|
|
23
|
+
tracerVersion?: string;
|
|
24
|
+
}
|
|
20
25
|
export declare const DEFAULT_KAFKA_CONNECTION: string;
|
|
21
26
|
export interface KafkaModuleOptions {
|
|
22
27
|
name?: string;
|
|
@@ -31,6 +36,7 @@ export interface KafkaModuleOptions {
|
|
|
31
36
|
producer?: ProducerConfig;
|
|
32
37
|
defaultConsumerGroupId?: string;
|
|
33
38
|
logLevel?: 'NOTHING' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
|
|
39
|
+
tracing?: TracingOptions;
|
|
34
40
|
}
|
|
35
41
|
export interface KafkaModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
36
42
|
name?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kafka-module-options.interface.js","sourceRoot":"","sources":["../../lib/interfaces/kafka-module-options.interface.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"kafka-module-options.interface.js","sourceRoot":"","sources":["../../lib/interfaces/kafka-module-options.interface.ts"],"names":[],"mappings":";;;AAgFA,oDAEC;AAGD,8CAEC;AAGD,kDAEC;AA7DY,QAAA,wBAAwB,GAAW,SAAS,CAAC;AA8C7C,QAAA,oBAAoB,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAGnE,SAAgB,oBAAoB,CAAC,IAAa;IAChD,OAAO,iBAAiB,IAAI,IAAI,gCAAwB,EAAE,CAAC;AAC7D,CAAC;AAGD,SAAgB,iBAAiB,CAAC,IAAa;IAC7C,OAAO,cAAc,IAAI,IAAI,gCAAwB,EAAE,CAAC;AAC1D,CAAC;AAGD,SAAgB,mBAAmB,CAAC,IAAa;IAC/C,OAAO,gBAAgB,IAAI,IAAI,gCAAwB,EAAE,CAAC;AAC5D,CAAC"}
|
package/dist/kafka.module.js
CHANGED
|
@@ -18,12 +18,14 @@ const common_1 = require("@nestjs/common");
|
|
|
18
18
|
const interfaces_1 = require("./interfaces");
|
|
19
19
|
const kafka_core_service_1 = require("./services/kafka-core.service");
|
|
20
20
|
const kafka_client_service_1 = require("./services/kafka-client.service");
|
|
21
|
+
const tracing_service_1 = require("./services/tracing.service");
|
|
21
22
|
const kafka_health_indicator_1 = require("./health/kafka-health-indicator");
|
|
22
23
|
const KAFKA_CONNECTION_NAMES = Symbol('KAFKA_CONNECTION_NAMES');
|
|
23
24
|
const CORE_PROVIDERS = [
|
|
24
25
|
kafka_core_service_1.KafkaCoreService,
|
|
25
26
|
kafka_client_service_1.KafkaClient,
|
|
26
27
|
kafka_health_indicator_1.KafkaHealthIndicator,
|
|
28
|
+
tracing_service_1.TracingService,
|
|
27
29
|
];
|
|
28
30
|
let KafkaModule = KafkaModule_1 = class KafkaModule {
|
|
29
31
|
kafkaCore;
|
|
@@ -69,22 +71,27 @@ let KafkaModule = KafkaModule_1 = class KafkaModule {
|
|
|
69
71
|
];
|
|
70
72
|
return {
|
|
71
73
|
module: KafkaModule_1,
|
|
74
|
+
global: true,
|
|
72
75
|
providers,
|
|
73
76
|
exports: [
|
|
77
|
+
interfaces_1.KAFKA_MODULE_OPTIONS,
|
|
74
78
|
optionsToken,
|
|
75
79
|
clientToken,
|
|
76
80
|
kafka_core_service_1.KafkaCoreService,
|
|
77
81
|
kafka_client_service_1.KafkaClient,
|
|
78
82
|
kafka_health_indicator_1.KafkaHealthIndicator,
|
|
83
|
+
tracing_service_1.TracingService,
|
|
79
84
|
],
|
|
80
85
|
};
|
|
81
86
|
}
|
|
82
87
|
static forRootMultiple(optionsArray) {
|
|
83
88
|
const providers = [];
|
|
84
89
|
const exports = [
|
|
90
|
+
interfaces_1.KAFKA_MODULE_OPTIONS,
|
|
85
91
|
kafka_core_service_1.KafkaCoreService,
|
|
86
92
|
kafka_client_service_1.KafkaClient,
|
|
87
93
|
kafka_health_indicator_1.KafkaHealthIndicator,
|
|
94
|
+
tracing_service_1.TracingService,
|
|
88
95
|
];
|
|
89
96
|
for (const options of optionsArray) {
|
|
90
97
|
const connectionName = options.name || interfaces_1.DEFAULT_KAFKA_CONNECTION;
|
|
@@ -163,11 +170,13 @@ let KafkaModule = KafkaModule_1 = class KafkaModule {
|
|
|
163
170
|
imports: [...(options.imports || [])],
|
|
164
171
|
providers,
|
|
165
172
|
exports: [
|
|
173
|
+
interfaces_1.KAFKA_MODULE_OPTIONS,
|
|
166
174
|
optionsToken,
|
|
167
175
|
clientToken,
|
|
168
176
|
kafka_core_service_1.KafkaCoreService,
|
|
169
177
|
kafka_client_service_1.KafkaClient,
|
|
170
178
|
kafka_health_indicator_1.KafkaHealthIndicator,
|
|
179
|
+
tracing_service_1.TracingService,
|
|
171
180
|
],
|
|
172
181
|
global: options.global ?? true,
|
|
173
182
|
};
|
package/dist/kafka.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kafka.module.js","sourceRoot":"","sources":["../lib/kafka.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAQwB;AACxB,6CAQsB;AACtB,sEAAiE;AACjE,0EAGyC;
|
|
1
|
+
{"version":3,"file":"kafka.module.js","sourceRoot":"","sources":["../lib/kafka.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { IdempotencyService } from './idempotency.service';
|
|
|
5
5
|
import { PressureManagerService } from './pressure-manager.service';
|
|
6
6
|
import { DlqService } from './dlq.service';
|
|
7
7
|
import { DlqRetryService } from './dlq-retry.service';
|
|
8
|
+
import { TracingService } from './tracing.service';
|
|
8
9
|
import { ConsumerMetadata } from '../interfaces';
|
|
9
10
|
export declare class ConsumerRegistryService implements OnApplicationShutdown {
|
|
10
11
|
private readonly kafkaCore;
|
|
@@ -13,10 +14,12 @@ export declare class ConsumerRegistryService implements OnApplicationShutdown {
|
|
|
13
14
|
private readonly pressureManager;
|
|
14
15
|
private readonly dlqService;
|
|
15
16
|
private readonly dlqRetryService;
|
|
17
|
+
private readonly tracingService?;
|
|
16
18
|
private readonly logger;
|
|
17
19
|
private consumerGroups;
|
|
18
20
|
private isShuttingDown;
|
|
19
|
-
|
|
21
|
+
private messageRetryStates;
|
|
22
|
+
constructor(kafkaCore: KafkaCoreService, batchProcessor: BatchProcessorService, idempotencyService: IdempotencyService, pressureManager: PressureManagerService, dlqService: DlqService, dlqRetryService: DlqRetryService, tracingService?: TracingService | undefined);
|
|
20
23
|
registerConsumers(consumers: ConsumerMetadata[]): void;
|
|
21
24
|
private registerConsumer;
|
|
22
25
|
private buildRestartOnFailure;
|
|
@@ -26,6 +29,9 @@ export declare class ConsumerRegistryService implements OnApplicationShutdown {
|
|
|
26
29
|
private startBatchGroupConsumer;
|
|
27
30
|
private processBatchMessages;
|
|
28
31
|
private handleError;
|
|
32
|
+
private getMessageKey;
|
|
33
|
+
private sleep;
|
|
34
|
+
private clearMessageRetryState;
|
|
29
35
|
gracefulShutdown(): Promise<void>;
|
|
30
36
|
onApplicationShutdown(): Promise<void>;
|
|
31
37
|
}
|