# logger — Structured JSON Logging > `import { log } from 'puffy-core/logger'` > CJS: `const { logger: { log } } = require('puffy-core')` --- ## log Outputs a structured JSON log entry. Uses `console.log` for INFO/WARN, `console.error` for ERROR/CRITICAL. ### Signature ``` log(payload: Object) → void ``` ### Payload properties | Property | Type | Default | Description | |---|---|---|---| | `level` | string | `'INFO'` | One of `'INFO'`, `'WARN'`, `'ERROR'`, `'CRITICAL'` | | `message` | string | — | Log message | | `code` | string | — | Error or event code | | `opId` | string | — | Operation ID for tracing/correlation | | `test` | boolean | `false` | Test flag | | `metric` | number | — | Numeric metric value | | `unit` | string | — | Metric unit | | `time` | number | — | Shorthand: sets `metric` to this value and `unit` to `'ms'` | | `data` | any | — | Arbitrary data payload | | `errors` | Error\|Error[]\|string[] | — | Errors to log (converted to `{message, stack}`) | Any additional properties on the payload are included in the output. ### Examples ```js // Basic info log log({ level: 'INFO', message: 'User created', data: { userId: 123 } }) // Output: {"level":"INFO","test":false,"message":"User created","data":{"userId":123}} // Error log with error objects log({ level: 'ERROR', message: 'Request failed', code: 'ERR_TIMEOUT', errors: [new Error('Connection timed out')] }) // Output: {"level":"ERROR","test":false,"message":"Request failed","code":"ERR_TIMEOUT", // "errors":[{"message":"Connection timed out","stack":"Error: Connection timed out\n..."}]} // Timing log (time shorthand sets metric + unit='ms') log({ level: 'INFO', message: 'Query completed', time: 150 }) // Output: {"level":"INFO","test":false,"message":"Query completed","metric":150,"unit":"ms"} // With operation ID for tracing log({ level: 'INFO', message: 'Processing order', opId: 'req-abc-123', data: { orderId: 456 } }) ``` ### Global metadata via environment variable Set `process.env.LOG_META` to a JSON string to attach metadata to every log entry: ```js process.env.LOG_META = JSON.stringify({ service:'user-api', env:'production' }) log({ level:'INFO', message:'Server started' }) // Output includes: {"level":"INFO",...,"service":"user-api","env":"production"} ``` GOTCHA: Error objects in the `errors` field are converted to plain `{message, stack}` objects for JSON serialization. If you pass a string instead of an Error, it becomes `{message: "your string", stack: ""}`.