@eventferry/kafka 3.1.0 → 3.2.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 +109 -0
- package/dist/index.cjs +152 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +170 -7
- package/dist/index.d.ts +170 -7
- package/dist/index.js +149 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublishableMessage, PublishResult, PublishErrorKind, Publisher } from '@eventferry/core';
|
|
1
|
+
import { PublishableMessage, PublishResult, Logger, PublishErrorKind, Publisher } from '@eventferry/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Low-level driver contract. Each concrete driver (kafkajs, confluent)
|
|
@@ -130,8 +130,21 @@ interface ProducerBehaviorConfig {
|
|
|
130
130
|
* Requires a stable transactionalId. Default false.
|
|
131
131
|
*/
|
|
132
132
|
transactional?: boolean;
|
|
133
|
-
/**
|
|
134
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Required when `transactional=true`. Must be stable per producer instance
|
|
135
|
+
* — two producers sharing the same id race for the broker-side epoch and
|
|
136
|
+
* fence each other.
|
|
137
|
+
*
|
|
138
|
+
* Accepts a string OR a thunk that resolves the id at connect time. The
|
|
139
|
+
* callable form lets you derive the id from runtime context that's not
|
|
140
|
+
* known at construction (pod name, AZ + replica index, k8s ordinal):
|
|
141
|
+
*
|
|
142
|
+
* transactionalId: () => `${process.env.POD_NAME}-${replicaIndex()}`,
|
|
143
|
+
*
|
|
144
|
+
* For multi-instance EOS, the derived id MUST be stable across a single
|
|
145
|
+
* instance's restarts but UNIQUE across instances.
|
|
146
|
+
*/
|
|
147
|
+
transactionalId?: string | (() => string | Promise<string>);
|
|
135
148
|
/** acks: -1/"all" (default), 0, or 1. */
|
|
136
149
|
acks?: number;
|
|
137
150
|
/** Compression codec. Driver maps to its native enum. */
|
|
@@ -176,6 +189,16 @@ interface ProducerBehaviorConfig {
|
|
|
176
189
|
* silences kafkajs's `KafkaJSPartitionerNotSpecified` warning.
|
|
177
190
|
*/
|
|
178
191
|
partitioner?: KafkaJsPartitionerChoice;
|
|
192
|
+
/**
|
|
193
|
+
* Callback fired when a transactional `sendBatch` triggers the abort
|
|
194
|
+
* path (e.g. mid-batch driver error, broker rejection). Used by the
|
|
195
|
+
* publisher to fan out the matching `KafkaPublisherHooks.onTransactionAbort`
|
|
196
|
+
* hook — but advanced users constructing a driver directly may also wire
|
|
197
|
+
* it themselves. Best-effort: the driver still proceeds to abort the
|
|
198
|
+
* underlying transaction and return per-record failures regardless of
|
|
199
|
+
* whether this callback throws.
|
|
200
|
+
*/
|
|
201
|
+
onTransactionAbort?: (error: Error) => void;
|
|
179
202
|
}
|
|
180
203
|
type DriverKind = "kafkajs" | "confluent";
|
|
181
204
|
|
|
@@ -191,6 +214,12 @@ interface KjsTransaction {
|
|
|
191
214
|
abort(): Promise<void>;
|
|
192
215
|
}
|
|
193
216
|
interface KafkaJsDriverOptions extends KafkaConnectionConfig, ProducerBehaviorConfig {
|
|
217
|
+
/**
|
|
218
|
+
* Optional logger for the driver's own diagnostics (e.g. warnings about
|
|
219
|
+
* unsupported tuning options). When absent the driver falls back to
|
|
220
|
+
* `console.warn` so existing users see the same output.
|
|
221
|
+
*/
|
|
222
|
+
logger?: Logger;
|
|
194
223
|
}
|
|
195
224
|
/**
|
|
196
225
|
* Driver backed by the pure-JS `kafkajs` client. Simple, zero native deps.
|
|
@@ -299,6 +328,110 @@ interface ConfluentClientConfig {
|
|
|
299
328
|
}
|
|
300
329
|
declare function buildConfluentClientConfig(opts: KafkaConnectionConfig & ProducerBehaviorConfig): ConfluentClientConfig;
|
|
301
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Lifecycle hooks fired by `KafkaPublisher`. Every hook is optional. The
|
|
333
|
+
* publisher wraps each invocation in a try/catch and logs (via the
|
|
334
|
+
* configured logger) on failure — a misbehaving hook will NEVER break
|
|
335
|
+
* publishing.
|
|
336
|
+
*
|
|
337
|
+
* Typical wiring:
|
|
338
|
+
* - Custom observability stacks (Datadog APM, New Relic) → `onPublish`,
|
|
339
|
+
* `onError`, `onTransactionAbort`.
|
|
340
|
+
* - Connection-aware readiness probes → `onConnect` / `onDisconnect`.
|
|
341
|
+
* - Audit logs of every published record → `onPublish`.
|
|
342
|
+
*/
|
|
343
|
+
interface KafkaPublisherHooks {
|
|
344
|
+
/** Fires after the underlying client successfully connects. */
|
|
345
|
+
onConnect?(): void | Promise<void>;
|
|
346
|
+
/** Fires after the underlying client disconnects (clean shutdown). */
|
|
347
|
+
onDisconnect?(): void | Promise<void>;
|
|
348
|
+
/**
|
|
349
|
+
* Fires once per record after a publish attempt — both successes and
|
|
350
|
+
* failures. The `result.ok` flag distinguishes them.
|
|
351
|
+
*/
|
|
352
|
+
onPublish?(result: PublishResult, message: PublishableMessage): void | Promise<void>;
|
|
353
|
+
/**
|
|
354
|
+
* Fires for any error surfaced from the publish path — driver-thrown
|
|
355
|
+
* errors, transaction abort errors, etc. `message` is set when the error
|
|
356
|
+
* is per-record; absent for batch-level errors (e.g. connect failure).
|
|
357
|
+
*/
|
|
358
|
+
onError?(error: Error, message?: PublishableMessage): void | Promise<void>;
|
|
359
|
+
/**
|
|
360
|
+
* Fires when a transactional sendBatch's inner abort path is taken.
|
|
361
|
+
* Useful for observability dashboards that track EOS failure rates.
|
|
362
|
+
*/
|
|
363
|
+
onTransactionAbort?(error: Error): void | Promise<void>;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Invoke a hook safely. Never throws back into the caller — logs the hook's
|
|
367
|
+
* failure via the configured logger (or no-op when logger is absent).
|
|
368
|
+
*/
|
|
369
|
+
declare function safeHook(logger: Logger | undefined, hookName: keyof KafkaPublisherHooks, invoke: () => void | Promise<void> | undefined): Promise<void>;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Tracing surface for the publisher.
|
|
373
|
+
*
|
|
374
|
+
* eventferry deliberately does not depend on `@opentelemetry/api` — instead
|
|
375
|
+
* users wire a thin adapter over their tracing system (OpenTelemetry,
|
|
376
|
+
* Datadog, internal, …). This file defines the minimal contract; an
|
|
377
|
+
* OpenTelemetry adapter is ~10 lines (see the README).
|
|
378
|
+
*
|
|
379
|
+
* The contract follows the **current stable** OpenTelemetry messaging
|
|
380
|
+
* semantic conventions
|
|
381
|
+
* ({@link https://github.com/open-telemetry/semantic-conventions/blob/main/docs/messaging/kafka.md spec}):
|
|
382
|
+
*
|
|
383
|
+
* - Span name: `"{topic} publish"`
|
|
384
|
+
* - `SpanKind.PRODUCER`
|
|
385
|
+
* - Required attributes: `messaging.system=kafka`,
|
|
386
|
+
* `messaging.operation.type=publish`, `messaging.destination.name=<topic>`
|
|
387
|
+
* - Recommended: `messaging.batch.message_count`, `messaging.kafka.partition`,
|
|
388
|
+
* `server.address`, `server.port`
|
|
389
|
+
* - One span per batch (NOT per message — per-message spans cause
|
|
390
|
+
* cardinality explosion and the spec actively warns against this)
|
|
391
|
+
*/
|
|
392
|
+
/** Attribute values the spec allows. */
|
|
393
|
+
type SpanAttributeValue = string | number | boolean;
|
|
394
|
+
/**
|
|
395
|
+
* Minimal span surface the publisher needs. Implementations wrap a
|
|
396
|
+
* tracing-system-specific span; methods MUST never throw out of the
|
|
397
|
+
* publisher's hot path (wrap your own SDK calls in try/catch).
|
|
398
|
+
*/
|
|
399
|
+
interface SpanLike {
|
|
400
|
+
setAttribute(key: string, value: SpanAttributeValue): void;
|
|
401
|
+
setAttributes(attrs: Record<string, SpanAttributeValue>): void;
|
|
402
|
+
/** OK on success; ERROR on failure. The `message` is the error message. */
|
|
403
|
+
setStatus(status: {
|
|
404
|
+
code: "ok" | "error";
|
|
405
|
+
message?: string;
|
|
406
|
+
}): void;
|
|
407
|
+
/** Attach an exception to the span (OpenTelemetry `recordException`). */
|
|
408
|
+
recordException(error: Error): void;
|
|
409
|
+
end(): void;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Factory the publisher calls once per `sendBatch` to start a span.
|
|
413
|
+
* Implementations MUST set `SpanKind.PRODUCER` and the messaging semconv
|
|
414
|
+
* attributes on the returned span before returning it.
|
|
415
|
+
*/
|
|
416
|
+
interface KafkaTracer {
|
|
417
|
+
/**
|
|
418
|
+
* Start a publish span.
|
|
419
|
+
* @param name Recommended format: `"{topic} publish"`.
|
|
420
|
+
* @param attributes Initial attributes (the publisher supplies the messaging
|
|
421
|
+
* semconv set: system, destination.name, operation.type,
|
|
422
|
+
* batch.message_count, plus optional kafka.partition and
|
|
423
|
+
* server.address/port).
|
|
424
|
+
*/
|
|
425
|
+
startPublishSpan(name: string, attributes: Record<string, SpanAttributeValue>): SpanLike;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* No-op tracer. Used when the user does not configure one. Cheap allocation
|
|
429
|
+
* — never touches I/O.
|
|
430
|
+
*/
|
|
431
|
+
declare class NoopKafkaTracer implements KafkaTracer {
|
|
432
|
+
startPublishSpan(): SpanLike;
|
|
433
|
+
}
|
|
434
|
+
|
|
302
435
|
interface KafkaPublisherOptions extends KafkaConnectionConfig, ProducerBehaviorConfig {
|
|
303
436
|
/** Which underlying client to use. Default "kafkajs". */
|
|
304
437
|
driver?: DriverKind;
|
|
@@ -307,14 +440,35 @@ interface KafkaPublisherOptions extends KafkaConnectionConfig, ProducerBehaviorC
|
|
|
307
440
|
* Useful for testing or unsupported clients.
|
|
308
441
|
*/
|
|
309
442
|
customDriver?: KafkaDriver;
|
|
443
|
+
/**
|
|
444
|
+
* Optional structured logger. When set, the publisher routes its own
|
|
445
|
+
* diagnostics (driver warnings, hook failures) through it. When omitted,
|
|
446
|
+
* the publisher is silent — only the underlying drivers may still log.
|
|
447
|
+
*/
|
|
448
|
+
logger?: Logger;
|
|
449
|
+
/**
|
|
450
|
+
* Optional lifecycle hooks. Every hook is invoked safely (try/catch +
|
|
451
|
+
* logged via `logger`) and a misbehaving hook will never break publishing.
|
|
452
|
+
*/
|
|
453
|
+
hooks?: KafkaPublisherHooks;
|
|
454
|
+
/**
|
|
455
|
+
* Optional tracer. When set, `publish()` wraps each batch in a span that
|
|
456
|
+
* follows the current stable OpenTelemetry messaging semantic conventions.
|
|
457
|
+
* Use a thin adapter over your tracing SDK (see {@link KafkaTracer}).
|
|
458
|
+
*/
|
|
459
|
+
tracer?: KafkaTracer;
|
|
310
460
|
}
|
|
311
461
|
/**
|
|
312
|
-
* The Publisher the Relay talks to. Wraps a pluggable KafkaDriver and
|
|
313
|
-
*
|
|
314
|
-
* (Redpanda is Kafka-API
|
|
462
|
+
* The Publisher the Relay talks to. Wraps a pluggable KafkaDriver and adds
|
|
463
|
+
* dead-letter routing, observability hooks, and OpenTelemetry-shaped publish
|
|
464
|
+
* spans. Works against Kafka and Redpanda identically (Redpanda is Kafka-API
|
|
465
|
+
* compatible).
|
|
315
466
|
*/
|
|
316
467
|
declare class KafkaPublisher implements Publisher {
|
|
317
468
|
private readonly driver;
|
|
469
|
+
private readonly logger;
|
|
470
|
+
private readonly hooks;
|
|
471
|
+
private readonly tracer;
|
|
318
472
|
constructor(opts: KafkaPublisherOptions);
|
|
319
473
|
connect(): Promise<void>;
|
|
320
474
|
disconnect(): Promise<void>;
|
|
@@ -326,6 +480,15 @@ declare class KafkaPublisher implements Publisher {
|
|
|
326
480
|
publishToDlq(message: PublishableMessage, error: Error): Promise<void>;
|
|
327
481
|
/** Whether the configured driver provides atomic (EOS) batch sends. */
|
|
328
482
|
get transactional(): boolean;
|
|
483
|
+
/**
|
|
484
|
+
* Start a span for the batch following the OTel messaging conventions.
|
|
485
|
+
*
|
|
486
|
+
* Multi-topic batches: per the OTel spec, the span name uses the
|
|
487
|
+
* destination — we pick the FIRST topic in the batch and document the
|
|
488
|
+
* limitation. Callers that publish heterogeneous batches and care about
|
|
489
|
+
* per-topic spans should split their batches upstream.
|
|
490
|
+
*/
|
|
491
|
+
private startBatchSpan;
|
|
329
492
|
}
|
|
330
493
|
|
|
331
|
-
export { type ConfluentClientConfig, ConfluentDriver, type ConfluentDriverOptions, type DriverKind, type KafkaConnectionConfig, type KafkaDriver, KafkaJsDriver, type KafkaJsDriverOptions, type KafkaJsPartitionerChoice, KafkaPublisher, type KafkaPublisherOptions, type OauthBearerToken, type ProducerBehaviorConfig, type SaslConfig, type SaslOauthbearerConfig, type SaslPasswordConfig, type TlsConfig, _resetKafkajsWarnDedup, buildConfluentClientConfig, classifyConfluentError, classifyKafkajsError };
|
|
494
|
+
export { type ConfluentClientConfig, ConfluentDriver, type ConfluentDriverOptions, type DriverKind, type KafkaConnectionConfig, type KafkaDriver, KafkaJsDriver, type KafkaJsDriverOptions, type KafkaJsPartitionerChoice, KafkaPublisher, type KafkaPublisherHooks, type KafkaPublisherOptions, type KafkaTracer, NoopKafkaTracer, type OauthBearerToken, type ProducerBehaviorConfig, type SaslConfig, type SaslOauthbearerConfig, type SaslPasswordConfig, type SpanAttributeValue, type SpanLike, type TlsConfig, _resetKafkajsWarnDedup, buildConfluentClientConfig, classifyConfluentError, classifyKafkajsError, safeHook };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublishableMessage, PublishResult, PublishErrorKind, Publisher } from '@eventferry/core';
|
|
1
|
+
import { PublishableMessage, PublishResult, Logger, PublishErrorKind, Publisher } from '@eventferry/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Low-level driver contract. Each concrete driver (kafkajs, confluent)
|
|
@@ -130,8 +130,21 @@ interface ProducerBehaviorConfig {
|
|
|
130
130
|
* Requires a stable transactionalId. Default false.
|
|
131
131
|
*/
|
|
132
132
|
transactional?: boolean;
|
|
133
|
-
/**
|
|
134
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Required when `transactional=true`. Must be stable per producer instance
|
|
135
|
+
* — two producers sharing the same id race for the broker-side epoch and
|
|
136
|
+
* fence each other.
|
|
137
|
+
*
|
|
138
|
+
* Accepts a string OR a thunk that resolves the id at connect time. The
|
|
139
|
+
* callable form lets you derive the id from runtime context that's not
|
|
140
|
+
* known at construction (pod name, AZ + replica index, k8s ordinal):
|
|
141
|
+
*
|
|
142
|
+
* transactionalId: () => `${process.env.POD_NAME}-${replicaIndex()}`,
|
|
143
|
+
*
|
|
144
|
+
* For multi-instance EOS, the derived id MUST be stable across a single
|
|
145
|
+
* instance's restarts but UNIQUE across instances.
|
|
146
|
+
*/
|
|
147
|
+
transactionalId?: string | (() => string | Promise<string>);
|
|
135
148
|
/** acks: -1/"all" (default), 0, or 1. */
|
|
136
149
|
acks?: number;
|
|
137
150
|
/** Compression codec. Driver maps to its native enum. */
|
|
@@ -176,6 +189,16 @@ interface ProducerBehaviorConfig {
|
|
|
176
189
|
* silences kafkajs's `KafkaJSPartitionerNotSpecified` warning.
|
|
177
190
|
*/
|
|
178
191
|
partitioner?: KafkaJsPartitionerChoice;
|
|
192
|
+
/**
|
|
193
|
+
* Callback fired when a transactional `sendBatch` triggers the abort
|
|
194
|
+
* path (e.g. mid-batch driver error, broker rejection). Used by the
|
|
195
|
+
* publisher to fan out the matching `KafkaPublisherHooks.onTransactionAbort`
|
|
196
|
+
* hook — but advanced users constructing a driver directly may also wire
|
|
197
|
+
* it themselves. Best-effort: the driver still proceeds to abort the
|
|
198
|
+
* underlying transaction and return per-record failures regardless of
|
|
199
|
+
* whether this callback throws.
|
|
200
|
+
*/
|
|
201
|
+
onTransactionAbort?: (error: Error) => void;
|
|
179
202
|
}
|
|
180
203
|
type DriverKind = "kafkajs" | "confluent";
|
|
181
204
|
|
|
@@ -191,6 +214,12 @@ interface KjsTransaction {
|
|
|
191
214
|
abort(): Promise<void>;
|
|
192
215
|
}
|
|
193
216
|
interface KafkaJsDriverOptions extends KafkaConnectionConfig, ProducerBehaviorConfig {
|
|
217
|
+
/**
|
|
218
|
+
* Optional logger for the driver's own diagnostics (e.g. warnings about
|
|
219
|
+
* unsupported tuning options). When absent the driver falls back to
|
|
220
|
+
* `console.warn` so existing users see the same output.
|
|
221
|
+
*/
|
|
222
|
+
logger?: Logger;
|
|
194
223
|
}
|
|
195
224
|
/**
|
|
196
225
|
* Driver backed by the pure-JS `kafkajs` client. Simple, zero native deps.
|
|
@@ -299,6 +328,110 @@ interface ConfluentClientConfig {
|
|
|
299
328
|
}
|
|
300
329
|
declare function buildConfluentClientConfig(opts: KafkaConnectionConfig & ProducerBehaviorConfig): ConfluentClientConfig;
|
|
301
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Lifecycle hooks fired by `KafkaPublisher`. Every hook is optional. The
|
|
333
|
+
* publisher wraps each invocation in a try/catch and logs (via the
|
|
334
|
+
* configured logger) on failure — a misbehaving hook will NEVER break
|
|
335
|
+
* publishing.
|
|
336
|
+
*
|
|
337
|
+
* Typical wiring:
|
|
338
|
+
* - Custom observability stacks (Datadog APM, New Relic) → `onPublish`,
|
|
339
|
+
* `onError`, `onTransactionAbort`.
|
|
340
|
+
* - Connection-aware readiness probes → `onConnect` / `onDisconnect`.
|
|
341
|
+
* - Audit logs of every published record → `onPublish`.
|
|
342
|
+
*/
|
|
343
|
+
interface KafkaPublisherHooks {
|
|
344
|
+
/** Fires after the underlying client successfully connects. */
|
|
345
|
+
onConnect?(): void | Promise<void>;
|
|
346
|
+
/** Fires after the underlying client disconnects (clean shutdown). */
|
|
347
|
+
onDisconnect?(): void | Promise<void>;
|
|
348
|
+
/**
|
|
349
|
+
* Fires once per record after a publish attempt — both successes and
|
|
350
|
+
* failures. The `result.ok` flag distinguishes them.
|
|
351
|
+
*/
|
|
352
|
+
onPublish?(result: PublishResult, message: PublishableMessage): void | Promise<void>;
|
|
353
|
+
/**
|
|
354
|
+
* Fires for any error surfaced from the publish path — driver-thrown
|
|
355
|
+
* errors, transaction abort errors, etc. `message` is set when the error
|
|
356
|
+
* is per-record; absent for batch-level errors (e.g. connect failure).
|
|
357
|
+
*/
|
|
358
|
+
onError?(error: Error, message?: PublishableMessage): void | Promise<void>;
|
|
359
|
+
/**
|
|
360
|
+
* Fires when a transactional sendBatch's inner abort path is taken.
|
|
361
|
+
* Useful for observability dashboards that track EOS failure rates.
|
|
362
|
+
*/
|
|
363
|
+
onTransactionAbort?(error: Error): void | Promise<void>;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Invoke a hook safely. Never throws back into the caller — logs the hook's
|
|
367
|
+
* failure via the configured logger (or no-op when logger is absent).
|
|
368
|
+
*/
|
|
369
|
+
declare function safeHook(logger: Logger | undefined, hookName: keyof KafkaPublisherHooks, invoke: () => void | Promise<void> | undefined): Promise<void>;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Tracing surface for the publisher.
|
|
373
|
+
*
|
|
374
|
+
* eventferry deliberately does not depend on `@opentelemetry/api` — instead
|
|
375
|
+
* users wire a thin adapter over their tracing system (OpenTelemetry,
|
|
376
|
+
* Datadog, internal, …). This file defines the minimal contract; an
|
|
377
|
+
* OpenTelemetry adapter is ~10 lines (see the README).
|
|
378
|
+
*
|
|
379
|
+
* The contract follows the **current stable** OpenTelemetry messaging
|
|
380
|
+
* semantic conventions
|
|
381
|
+
* ({@link https://github.com/open-telemetry/semantic-conventions/blob/main/docs/messaging/kafka.md spec}):
|
|
382
|
+
*
|
|
383
|
+
* - Span name: `"{topic} publish"`
|
|
384
|
+
* - `SpanKind.PRODUCER`
|
|
385
|
+
* - Required attributes: `messaging.system=kafka`,
|
|
386
|
+
* `messaging.operation.type=publish`, `messaging.destination.name=<topic>`
|
|
387
|
+
* - Recommended: `messaging.batch.message_count`, `messaging.kafka.partition`,
|
|
388
|
+
* `server.address`, `server.port`
|
|
389
|
+
* - One span per batch (NOT per message — per-message spans cause
|
|
390
|
+
* cardinality explosion and the spec actively warns against this)
|
|
391
|
+
*/
|
|
392
|
+
/** Attribute values the spec allows. */
|
|
393
|
+
type SpanAttributeValue = string | number | boolean;
|
|
394
|
+
/**
|
|
395
|
+
* Minimal span surface the publisher needs. Implementations wrap a
|
|
396
|
+
* tracing-system-specific span; methods MUST never throw out of the
|
|
397
|
+
* publisher's hot path (wrap your own SDK calls in try/catch).
|
|
398
|
+
*/
|
|
399
|
+
interface SpanLike {
|
|
400
|
+
setAttribute(key: string, value: SpanAttributeValue): void;
|
|
401
|
+
setAttributes(attrs: Record<string, SpanAttributeValue>): void;
|
|
402
|
+
/** OK on success; ERROR on failure. The `message` is the error message. */
|
|
403
|
+
setStatus(status: {
|
|
404
|
+
code: "ok" | "error";
|
|
405
|
+
message?: string;
|
|
406
|
+
}): void;
|
|
407
|
+
/** Attach an exception to the span (OpenTelemetry `recordException`). */
|
|
408
|
+
recordException(error: Error): void;
|
|
409
|
+
end(): void;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Factory the publisher calls once per `sendBatch` to start a span.
|
|
413
|
+
* Implementations MUST set `SpanKind.PRODUCER` and the messaging semconv
|
|
414
|
+
* attributes on the returned span before returning it.
|
|
415
|
+
*/
|
|
416
|
+
interface KafkaTracer {
|
|
417
|
+
/**
|
|
418
|
+
* Start a publish span.
|
|
419
|
+
* @param name Recommended format: `"{topic} publish"`.
|
|
420
|
+
* @param attributes Initial attributes (the publisher supplies the messaging
|
|
421
|
+
* semconv set: system, destination.name, operation.type,
|
|
422
|
+
* batch.message_count, plus optional kafka.partition and
|
|
423
|
+
* server.address/port).
|
|
424
|
+
*/
|
|
425
|
+
startPublishSpan(name: string, attributes: Record<string, SpanAttributeValue>): SpanLike;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* No-op tracer. Used when the user does not configure one. Cheap allocation
|
|
429
|
+
* — never touches I/O.
|
|
430
|
+
*/
|
|
431
|
+
declare class NoopKafkaTracer implements KafkaTracer {
|
|
432
|
+
startPublishSpan(): SpanLike;
|
|
433
|
+
}
|
|
434
|
+
|
|
302
435
|
interface KafkaPublisherOptions extends KafkaConnectionConfig, ProducerBehaviorConfig {
|
|
303
436
|
/** Which underlying client to use. Default "kafkajs". */
|
|
304
437
|
driver?: DriverKind;
|
|
@@ -307,14 +440,35 @@ interface KafkaPublisherOptions extends KafkaConnectionConfig, ProducerBehaviorC
|
|
|
307
440
|
* Useful for testing or unsupported clients.
|
|
308
441
|
*/
|
|
309
442
|
customDriver?: KafkaDriver;
|
|
443
|
+
/**
|
|
444
|
+
* Optional structured logger. When set, the publisher routes its own
|
|
445
|
+
* diagnostics (driver warnings, hook failures) through it. When omitted,
|
|
446
|
+
* the publisher is silent — only the underlying drivers may still log.
|
|
447
|
+
*/
|
|
448
|
+
logger?: Logger;
|
|
449
|
+
/**
|
|
450
|
+
* Optional lifecycle hooks. Every hook is invoked safely (try/catch +
|
|
451
|
+
* logged via `logger`) and a misbehaving hook will never break publishing.
|
|
452
|
+
*/
|
|
453
|
+
hooks?: KafkaPublisherHooks;
|
|
454
|
+
/**
|
|
455
|
+
* Optional tracer. When set, `publish()` wraps each batch in a span that
|
|
456
|
+
* follows the current stable OpenTelemetry messaging semantic conventions.
|
|
457
|
+
* Use a thin adapter over your tracing SDK (see {@link KafkaTracer}).
|
|
458
|
+
*/
|
|
459
|
+
tracer?: KafkaTracer;
|
|
310
460
|
}
|
|
311
461
|
/**
|
|
312
|
-
* The Publisher the Relay talks to. Wraps a pluggable KafkaDriver and
|
|
313
|
-
*
|
|
314
|
-
* (Redpanda is Kafka-API
|
|
462
|
+
* The Publisher the Relay talks to. Wraps a pluggable KafkaDriver and adds
|
|
463
|
+
* dead-letter routing, observability hooks, and OpenTelemetry-shaped publish
|
|
464
|
+
* spans. Works against Kafka and Redpanda identically (Redpanda is Kafka-API
|
|
465
|
+
* compatible).
|
|
315
466
|
*/
|
|
316
467
|
declare class KafkaPublisher implements Publisher {
|
|
317
468
|
private readonly driver;
|
|
469
|
+
private readonly logger;
|
|
470
|
+
private readonly hooks;
|
|
471
|
+
private readonly tracer;
|
|
318
472
|
constructor(opts: KafkaPublisherOptions);
|
|
319
473
|
connect(): Promise<void>;
|
|
320
474
|
disconnect(): Promise<void>;
|
|
@@ -326,6 +480,15 @@ declare class KafkaPublisher implements Publisher {
|
|
|
326
480
|
publishToDlq(message: PublishableMessage, error: Error): Promise<void>;
|
|
327
481
|
/** Whether the configured driver provides atomic (EOS) batch sends. */
|
|
328
482
|
get transactional(): boolean;
|
|
483
|
+
/**
|
|
484
|
+
* Start a span for the batch following the OTel messaging conventions.
|
|
485
|
+
*
|
|
486
|
+
* Multi-topic batches: per the OTel spec, the span name uses the
|
|
487
|
+
* destination — we pick the FIRST topic in the batch and document the
|
|
488
|
+
* limitation. Callers that publish heterogeneous batches and care about
|
|
489
|
+
* per-topic spans should split their batches upstream.
|
|
490
|
+
*/
|
|
491
|
+
private startBatchSpan;
|
|
329
492
|
}
|
|
330
493
|
|
|
331
|
-
export { type ConfluentClientConfig, ConfluentDriver, type ConfluentDriverOptions, type DriverKind, type KafkaConnectionConfig, type KafkaDriver, KafkaJsDriver, type KafkaJsDriverOptions, type KafkaJsPartitionerChoice, KafkaPublisher, type KafkaPublisherOptions, type OauthBearerToken, type ProducerBehaviorConfig, type SaslConfig, type SaslOauthbearerConfig, type SaslPasswordConfig, type TlsConfig, _resetKafkajsWarnDedup, buildConfluentClientConfig, classifyConfluentError, classifyKafkajsError };
|
|
494
|
+
export { type ConfluentClientConfig, ConfluentDriver, type ConfluentDriverOptions, type DriverKind, type KafkaConnectionConfig, type KafkaDriver, KafkaJsDriver, type KafkaJsDriverOptions, type KafkaJsPartitionerChoice, KafkaPublisher, type KafkaPublisherHooks, type KafkaPublisherOptions, type KafkaTracer, NoopKafkaTracer, type OauthBearerToken, type ProducerBehaviorConfig, type SaslConfig, type SaslOauthbearerConfig, type SaslPasswordConfig, type SpanAttributeValue, type SpanLike, type TlsConfig, _resetKafkajsWarnDedup, buildConfluentClientConfig, classifyConfluentError, classifyKafkajsError, safeHook };
|