logging

$npx mdskill add cloudflare/sandbox-sdk/logging

Inject loggers to debug and manage structured output.

  • Enables structured logging with child contexts for debugging.
  • Reads SANDBOX_LOG_LEVEL and SANDBOX_LOG_FORMAT environment variables.
  • Uses createNoOpLogger() for test environments.
  • Emits logs in JSON or pretty formats based on configuration.

SKILL.md

.github/skills/loggingView on GitHub ↗
---
name: logging
description: Use when adding logs, debugging, or working with the Logger across the SDK and container runtime. Covers the constructor-injection pattern, child loggers, env-var configuration, and test mocking. (project)
---

# Logging

## Pattern: Explicit Constructor Injection

Loggers are passed explicitly via constructor injection throughout the codebase. There is no global/ambient logger.

```typescript
import type { Logger } from '@repo/shared';

class MyService {
  constructor(private logger: Logger) {}

  async doWork(context: WorkContext) {
    const childLogger = this.logger.child({ operation: 'work' });
    childLogger.info('Working', { context });
  }
}
```

### Child loggers

Use `logger.child({ ... })` to attach structured context that will appear on every log line from that child. Prefer child loggers at the boundary of a unit of work (request, operation, session) rather than re-passing context on every call.

## Configuration

Two environment variables, both read once at startup:

| Var                  | Values                                 | Purpose               |
| -------------------- | -------------------------------------- | --------------------- |
| `SANDBOX_LOG_LEVEL`  | `debug` \| `info` \| `warn` \| `error` | Minimum level emitted |
| `SANDBOX_LOG_FORMAT` | `json` \| `pretty`                     | Output format         |

Use `json` in production (machine-parseable) and `pretty` for local dev.

## In Tests

Use `createNoOpLogger()` from `@repo/shared` to silence logging in tests:

```typescript
import { createNoOpLogger } from '@repo/shared';

const service = new MyService(createNoOpLogger());
```

Don't construct real loggers in unit tests — they add noise and can mask real failures with log output.

## When Adding Logs

- Log at **info** for significant lifecycle events (operation started/completed)
- Log at **debug** for fine-grained tracing (request bodies, intermediate state)
- Log at **warn** for recoverable anomalies
- Log at **error** for failures that surface to the caller; include the error object as structured context: `logger.error('Failed', { err })`
- Pass structured context as the second argument, not via string interpolation

More from cloudflare/sandbox-sdk

SkillDescription
architectureUse when navigating the codebase for the first time, adding a new client method, adding a new container handler/service, or understanding how a request flows from Worker through the Sandbox DO into the container. Covers the three-layer architecture, client pattern, container runtime structure, and monorepo layout. (project)
changesetsUse when creating a changeset, preparing a release, or bumping versions. Covers which packages to reference, how to write user-facing changeset descriptions, the release automation flow, and the npm/Docker version sync requirement. (project)
coding-standardsUse when writing or reviewing TypeScript in this repo. Covers the no-`any` rule and where to put new types, the uppercase-acronym style guide, and the rules for code comments (no historical context). (project)
examplesUse when working in the examples/ directory, running an example with wrangler dev, adding a new example, or answering questions about EXPOSE directives and the local Docker dev loop. (project)
git-commitUse when creating git commits to ensure commit messages follow project standards. Applies the 7 rules for great commit messages with focus on conciseness and imperative mood.
sandbox-bridgeUse when you need to exercise a real, running Sandbox deployment via HTTP — for example to validate SDK changes against a live container, reproduce a user-reported issue, or experiment with the API (including FUSE bucket mounts) without spinning up `wrangler dev`. Documents the Sandbox bridge worker reachable via `SANDBOX_WORKER_URL` + `SANDBOX_API_KEY` when the host injects them.
session-executionUse when working on or reviewing session execution, command handling, shell state, FIFO-based streaming, or stdout/stderr separation. Relevant for session.ts, command handlers, exec/execStream, or anything involving shell process management. (project)
testingUse when writing or running tests for this project. Covers unit vs E2E test decisions, test file locations, mock patterns, and project-specific testing conventions. (project)