# Structured Logging

Codewalkers uses [pino](https://getpino.io/) for structured JSON logging on the backend.

## Architecture

- **pino** writes structured JSON to **stderr** so CLI user output on stdout stays clean
- **console.log** remains for CLI command handlers (user-facing output on stdout)
- The `apps/server/logging/` module (ProcessLogWriter/LogManager) is a separate concern — it captures per-agent process stdout/stderr to files

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `CW_LOG_LEVEL` | Log level override (`fatal`, `error`, `warn`, `info`, `debug`, `trace`, `silent`) | `info` (production), `debug` (development) |
| `CW_LOG_PRETTY` | Set to `1` for human-readable colorized output via pino-pretty | unset (JSON output) |

## Log Levels

| Level | Usage |
|-------|-------|
| `fatal` | Process will exit (uncaught exceptions, DB migration failure) |
| `error` | Operation failed (agent crash, parse failure, clone failure) |
| `warn` | Degraded (account exhausted, no accounts available, stale PID, reconcile marking crashed) |
| `info` | State transitions (agent spawned/stopped/resumed, dispatch decision, server started, account selected/switched) |
| `debug` | Implementation details (command being built, session ID extraction, worktree paths, schema selection) |

## Adding Logging to a New Module

```typescript
import { createModuleLogger } from '../logger/index.js';

const log = createModuleLogger('my-module');

// Use structured data as first arg, message as second
log.info({ taskId, agentId }, 'task dispatched');
log.error({ err: error }, 'operation failed');
log.debug({ path, count }, 'processing items');
```

## Module Names

| Module | Used in |
|--------|---------|
| `agent-manager` | `apps/server/agent/manager.ts` |
| `dispatch` | `apps/server/dispatch/manager.ts` |
| `http` | `apps/server/server/index.ts` |
| `server` | `apps/server/cli/index.ts` (startup) |
| `git` | `apps/server/git/manager.ts`, `apps/server/git/clone.ts`, `apps/server/git/project-clones.ts` |
| `db` | `apps/server/db/ensure-schema.ts` |

## Testing

Logs are silenced in tests via `CW_LOG_LEVEL=silent` in `vitest.config.ts`.

## Quick Start

```sh
# Pretty logs during development
CW_LOG_LEVEL=debug CW_LOG_PRETTY=1 cw --server

# JSON logs for production/piping
cw --server 2>server.log
```
