Skip to content

feat(sdk): structured JSON logging + per-request ms.Log(ctx)#127

Merged
I-am-nothing merged 1 commit into
mainfrom
feat/sdk-structured-logging
Jun 29, 2026
Merged

feat(sdk): structured JSON logging + per-request ms.Log(ctx)#127
I-am-nothing merged 1 commit into
mainfrom
feat/sdk-structured-logging

Conversation

@I-am-nothing

Copy link
Copy Markdown
Contributor

What

First slice of the module log pipeline (dev half). The SDK had zero slog — module authors logged unstructured text to stderr, so the platform Logcat had nothing structured/attributable to read. This adds the source side:

  • JSON slog handler on stdout as the process default (configureLogging), captured identically by CloudWatch (prod Lambda) and the mirrorstack dev runner (dev) — no transport code. Level via MS_LOG_LEVEL (default info).
  • Per-request correlated logger (requestLogMiddleware, mounted after the dev-schema middleware so identity is established; runs on both serving paths since it only reads context). Tags each line with the trusted module_id / request_id / app_id / user_id / app_role.
  • ms.Log(ctx) *slog.Logger — the sanctioned author API.
  • request_id prefers the Lambda AwsRequestID (shares CloudWatch's own request grouping), else a fresh ids.NewUUID().

The SDK's own stderr diagnostic logger is left as-is (low-volume; deferred).

Why it's safe / minimal

Everything reuses primitives already vendored: ms.AppID/auth.Get for the trusted identity, internal/ids.NewUUID, and aws-lambda-go/lambdacontext (already a dep). No new dependencies; +177 lines, one new file + two small wirings.

Verification

go build ./... green; go test ./internal/core/ green (incl. the new logging_test.go pinning the correlation fields end-to-end through the middleware + the AwsRequestID-preferred request id); gofmt clean.

Next slices: dispatch Redis ring + POST /internal/modules/{id}/logs ingest → CLI runner tap → web useModuleLogs swap.

🤖 Generated with Claude Code

The SDK had zero slog — module authors logged unstructured text to stderr, so
the platform Logcat had nothing attributable to read.

Add a JSON slog handler on stdout as the process default (captured by CloudWatch
in prod and the `mirrorstack dev` runner in dev) plus a per-request middleware
that attaches a correlated *slog.Logger to the context — tagged with the trusted
module_id/request_id/app_id/user_id/app_role — exposed as ms.Log(ctx).
request_id prefers the Lambda AwsRequestID (shares CloudWatch's grouping), else a
fresh dev id. Level via MS_LOG_LEVEL (default info). The SDK's own stderr
diagnostics are left as-is.

First slice of the module log pipeline (dev half); the dispatch ingest + ring,
CLI tap, and web swap follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@I-am-nothing I-am-nothing merged commit 34bcfc3 into main Jun 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant