Operation logging requires Node/Next.js SDK and ingester 1.4.0+ (compatibility table),
plus a matching platform deployment. Do not assume your installed package or
hosted deployment supports the feature. Use
the capability checks below before adding imports. Basic error and usage
capture can continue while operation logging is pending.
Check your installation
Use your project’s package manager to install SDK 1.4.0+ and update its lockfile. Check the actual installed package, including the resolved Node dependency of@autter/runtime-next:
@autter/runtime-next/server. A dependency
range or source package version alone does not establish release support.
For self-hosted deployments, update the ingester first, publish/install the SDK
release next, and update platform consumers last. Check hosted capability
separately; local source changes do not upgrade the hosted service.
Use a secret server Runtime ingest key, such as
AUTTER_RUNTIME_KEY, scoped to
your repository. An Autter CLI/PAT or MCP access token is a different credential.
Browser client keys cannot send /v1/logs. Create Runtime keys under Settings
→ Access Tokens → Runtime ingest keys; share the environment variable name
with your coding agent, without pasting the key value.
An empty authenticated request checks route availability without adding records:
200 checks acceptance,
not storage or dashboard availability. A 401 means authentication failed;
403 can mean a client key was used; 404 indicates missing endpoint support.
Check exporter diagnostics and stored records separately.
Initialize once before startup
Add logging options to your existing initialization. Keep HTTP, database, queue and LLM instrumentations so traces explain the dependency calls inside an operation.GIT_SHA to the deployed commit SHA. Reuse existing providers; do not
register a second SDK. If another OTel SDK owns the process, resolve provider
ownership before adding Runtime. For an ESM app, follow the loader setup in
the Node package guide.
logging.console defaults to true. Set it to false when an existing logger
already writes stdout; export still runs. logging.minLevel accepts debug,
info, warning, or error. It filters ordinary messages while retaining
completed operation summaries. The warning method is named warn.
Next.js
Initialize ininstrumentation.ts and use Node for routes that import logging APIs:
withRuntimeOperation, runtimeLogger and the other logging APIs from
@autter/runtime-next/server in server application code. A route using them
can declare export const runtime = "nodejs". These APIs use Node async
context and cannot run in edge handlers or browser bundles. Client components
keep @autter/runtime-next/client and /v1/browser capture.
Record a customer operation
Wrap a meaningful request, job, or scheduled task. Use stable names; put opaque identifiers and bounded business context in attributes. The example accepts your existing application services rather than implementing payment logic:withRuntimeOperation returns the callback’s result and emits one completed
summary. It uses an always-recorded process span. If you already wrap this unit
in withProcessSpan, convert that wrapper when steps and outcomes help; avoid
two wrappers for the same boundary.
operation.step measures elapsed time and whether its callback threw. A payment
step that returns { confirmed: false } completed its callback; the declared
operation outcome explains the business failure. A thrown step error is
rethrown; your application can catch and recover it. Await all steps before
returning. Up to 64 steps are recorded.
Declare the business result
The SDK cannot infer business success from a normal return. Declare the outcome
you observed. A caught and recovered step failure does not automatically fail
the overall operation.
A thrown operation error is captured in its process span and rethrown unchanged.
A declared final
failed outcome emits an autter.outcome trace event with the
reporting callsite stack. Both use existing issue capture. The summary is related
evidence, rather than another issue. Avoid capturing the same thrown exception
again at that boundary. The reporting callsite identifies where you declared the
failure; analysis must still confirm the cause against source.
Keep diagnostics separate from issues
runtimeLogger and scoped loggers provide debug, info, warn, and error.
runtimeLogger.error(error, context) records diagnostics; it does not
automatically open an issue. Use captureException for a handled exception
that needs grouping, or declare a failed operation result. Keep captureMessage
for messages that intentionally need issue grouping.
Preserve Pino, Winston, or your existing logger. Add selected Runtime diagnostic
calls where context helps; Runtime does not automatically forward every record
from those loggers. An existing OTLP log exporter can send records directly as
described below. Avoid forwarding the same message twice.
Context and correlation
Context accepts nested objects, arrays, scalars, null and undefined. Object updates deep-merge; arrays replace. Logs inherit the active operation name/ID, parent operation ID, context, and active OTel trace/span IDs. SDK-owned IDs cannot be overwritten through user context. Structured trace attributes are encoded as JSON for OTel compatibility. Concurrent operations keep separate async context. It does not cross processes or queues. Pass an opaque workflow identifier in the job payload and set it as custom context in the consumer. That identifier alone does not create an automatic parent operation or an issue-evidence link. Runtime evidence links use captured trace/operation IDs, rather than similar timestamps.Flush before short-lived work ends
AwaitflushRuntimeLogs() before a job or serverless invocation loses its
execution window. It flushes logs only; use your existing Runtime lifecycle
flush for traces and metrics as well. Handle delivery failure according to
your telemetry policy without silently changing the business result.
shutdown() before exit. It attempts log export before closing
tracing and reports undelivered records. Keep your application’s shutdown and
exit policy; do not shut down a shared SDK after each request.
Node buffers up to 1,000 records or 4 MiB. Batches contain up to 50 records or
roughly 512 KiB. A flush has a 10-second budget and at most three attempts per
batch. Failed batches stay buffered for later flushes; automatic retry intervals
back off up to 30 seconds. Overflow drops records, and runtimeLogStats() reports
buffered/dropped counts. This is best-effort telemetry, not an audit log or
durable delivery.
Other languages and existing OTLP loggers
Use your language’s logs provider, logger bridge and OTLP/HTTP log exporter, or a Collector logs pipeline. A trace exporter or endpoint environment variable alone does not create a logs pipeline. Check your installed SDK’s logging API. When your exporter supports signal-specific environment variables:
Check the exported OTLP value types: some language logger bridges only support
scalar attributes. Structured steps must remain an array of objects for the
step display; a JSON string is not that array. Keep ordinary diagnostics working
if your bridge cannot produce structured summaries.
Include the actual trace/span IDs in the OTLP record fields. A failed summary
alone is a log; keep exception/ERROR trace capture or a failed
autter.outcome
event for issue detection. For raw OTel, that event uses
autter.outcome.status=error, a stable autter.outcome.name, a short
autter.outcome.message, and ERROR span status. No Node package is needed.
Verify stored logs and failure evidence
Use an isolated test environment for synthetic verification. Emit one structured message and two stubbed operations of the same name: a declared failure and a success. Keep service/environment/release identical so they can be compared. Avoid real payments, production jobs, or model calls.- Await log flushing and check exporter diagnostics. Record the operation IDs.
- Open your repository’s Runtime → Logs. Filter by service, environment and time, then inspect the message and summaries. Confirm nested context, measured steps, declared outcome, release, and captured IDs.
- Open the failed issue’s Operation evidence. Confirm the linked operation and trace spans; check a matching successful comparison when available.
- Verify traces/errors, metrics and any LLM capture separately. A console line,
log export, relay
202, or empty preflight does not prove all pipelines work. - Remove temporary selftest routes and debug/sampling overrides before commit or deployment. In production, inspect existing traffic instead.

