Skip to content

Structured logging / MDC context propagation across actor hops #53

@pathosDev

Description

@pathosDev

`Logger` today emits flat `(level, message, source)` records. Real distributed-system debugging needs context that travels alongside the message — correlation IDs, trace IDs, user IDs — so log lines from different actors / services / hops stitch together into a coherent trail.

Akka calls this MDC (Mapped Diagnostic Context). In TypeScript the right primitive is `AsyncLocalStorage` from `node:async_hooks` (also available in Bun) — a per-async-call-stack key-value store the logger reads automatically.

API:

```ts
import { LogContext } from 'actor-ts';

LogContext.run({ correlationId: 'abc-123', userId: 'u-42' }, () => {
// every log call inside this scope auto-includes the context
this.log.info('processing payment');
// and it propagates through tells/asks too
paymentRouter.tell({ kind: 'charge', amount: 100 });
});
```

When `paymentRouter` 's actor logs, the same `{correlationId, userId}` is attached because the message-dispatch wraps `onReceive` in a `LogContext.run(...)` from the originating context.

Components:

File Task
`src/Logger.ts` Read context from `AsyncLocalStorage` and merge into every log record.
`src/LogContext.ts` (new) Public API: `run(ctx, fn)`, `get()`, `with(ctx, fn)`.
`src/internal/ActorCell.ts` Wrap mailbox dispatch in `LogContext.run(envelope.context, ...)`; the envelope carries the originating context.
`src/cluster/RemoteActorRef.ts` Carry context across the wire as part of `EnvelopeMsg`.
`tests/unit/Logger.test.ts` Context propagates through tells; `run` is properly scoped.
`tests/multi-node/log-context-cross-node.test.ts` (new) Originating tell on A; remote actor on B logs with the same correlationId.

Estimate: 2-3 days.

Verification:

  • Local: tell from a wrapped scope; receiver's log includes the context.
  • Remote: same, but the receiver is on another node.
  • No-op: outside `LogContext.run`, log records don't carry stale context (defensive — empty ctx).

Out of scope:

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: highTop priority — high impact, plan next

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions