---
title: "Log structured events · Agent Wranglers"
url: https://agentwranglers.se/playbook/operations/logs/structured-logs
updated: 2026-10-20
licence: "All rights reserved"
---

# Log structured events

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Logs](https://agentwranglers.se/playbook/operations/logs)
- Rule: Write each log entry as one line of structured data, such as JSON, with a time, a level, an event name and its fields.
- How: Use a logging library that writes JSON, such as pino, structlog or Monolog. Write the time in UTC as ISO 8601 with milliseconds, and keep server clocks synced with NTP. Name events with fixed words, like `order.paid`, and put values in fields, not in the message text. Write to standard output and let the platform collect it, as the Twelve-Factor App advises.
- Check: Pipe one hour of logs through a JSON parser, such as `jq`. Every line parses, and every line has a time, a level and an event.

Example:

```js
import pino from 'pino';

const log = pino({
  timestamp: pino.stdTimeFunctions.isoTime,
  formatters: { level: label => ({ level: label }) },
  messageKey: 'event',
});
log.warn({ request_id: '7f3c2a9e', order: 'A-1042', attempt: 2 }, 'payment.retry');
```

```python
import structlog

structlog.configure(processors=[
    structlog.contextvars.merge_contextvars,
    structlog.processors.add_log_level,
    structlog.processors.TimeStamper(fmt="iso", utc=True, key="time"),
    structlog.processors.JSONRenderer(),
])
structlog.get_logger().warning("payment.retry", request_id="7f3c2a9e", order="A-1042", attempt=2)
```

```json
{"time":"2026-11-02T09:15:04.120Z","level":"warn","event":"payment.retry","request_id":"7f3c2a9e","order":"A-1042","attempt":2}
```

```sh
journalctl -u shop --since -1h -o cat | jq -s -e 'all(.time and .level and .event)' > /dev/null && echo PASS
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers operations playbook: https://agentwranglers.se/playbook/operations/logs/structured-logs`.

- Next: [Tie every line to its request](https://agentwranglers.se/playbook/operations/logs/request-ids)
- [Logs](https://agentwranglers.se/playbook/operations/logs)
