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)
96
95%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Loggers are passed explicitly via constructor injection throughout the codebase. There is no global/ambient logger.
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 });
}
}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.
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.
Use createNoOpLogger() from @repo/shared to silence logging in tests:
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.
logger.error('Failed', { err })f03920a
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.