---
type: skill
domain: observability
links: [Corpus_Callosum/CONSTITUTION.md, PULSE_OS.md]
---

# LOG_LEGIONNAIRE.md
> **ROLE:** OBSERVABILITY ENGINEER
> **TRIGGER:** "DEBUG"

## Protocol

1. **Enforce structured format.** All logs MUST be JSON with mandatory fields: `timestamp` (ISO 8601), `level`, `agent_id`, `message`. Optional: `trace_id`, `task_id`, `duration_ms`, `error`. No free-form print statements.
2. **Apply correct log levels.** ERROR: something broke, needs human attention. WARN: degraded but functional, auto-recoverable. INFO: key lifecycle events (start, stop, task claimed, task done). DEBUG: internal state, only in dev. Default prod level: INFO.
3. **Add correlation IDs.** Every agent session gets a `trace_id` at boot. Every task gets a `task_id`. Pass both through all log entries so any event can be traced from prompt to disk write.
4. **Set retention policies.** DEBUG logs: 24h then delete. INFO/WARN: 7 days then archive. ERROR: 30 days minimum. Rotate files at 10MB. Never let a log file grow unbounded.
5. **Verify observability.** After any incident, confirm the logs contain enough info to reconstruct what happened WITHOUT reading source code. If not, add the missing context and save the lesson.

## Metrics & Thresholds
- **Structured compliance:** 100% of log entries are valid JSON with required fields
- **Log level distribution:** ERROR <5%, WARN <15%, INFO 60-80%, DEBUG 0% in prod
- **File rotation:** At 10MB per file, max 5 rotated files per service
- **Retention:** DEBUG=24h, INFO/WARN=7d, ERROR=30d
- **Correlation coverage:** 100% of entries have `agent_id`, >95% have `trace_id`

## Good Example
```python
import json, logging, uuid
from datetime import datetime, timezone

class StructuredFormatter(logging.Formatter):
    def format(self, record):
        return json.dumps({
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "level": record.levelname,
            "agent_id": getattr(record, "agent_id", "unknown"),
            "trace_id": getattr(record, "trace_id", "none"),
            "message": record.getMessage(),
            "module": record.module,
        })

# Usage
logger = logging.getLogger("pulse")
logger.info("Task claimed", extra={"agent_id": "claude-1", "trace_id": str(uuid.uuid4())})
```

## Anti-Patterns
- **Print debugging in prod:** Using `print()` instead of structured logging. Prints have no level, no timestamp, no filterability.
- **Logging sensitive data:** Dumping API keys, tokens, or full request bodies into logs. Redact secrets, truncate large payloads.
- **Missing context on errors:** Logging "Error occurred" without the exception, stack trace, or input that caused it. Always log `exc_info=True` for errors.

## Tools
- `python Autonomic_System/Utilities/Tools/brain_query.py --query "logging <module>"`
- `python Autonomic_System/Utilities/Tools/pulse_save.py --agent <you> --learnings "structured logging added to <module>"`
- `python Autonomic_System/Utilities/Tools/pulse_relay.py --tasks "Add structured logging to <module>:observability:fast"`

## Verification Checklist
- [ ] All log entries are valid JSON with `timestamp`, `level`, `agent_id`, `message`
- [ ] No `print()` statements used for logging in production code
- [ ] Correlation IDs (`trace_id`, `task_id`) present in all log entries
- [ ] Log rotation configured (10MB max, 5 files retained)
- [ ] No secrets or API keys appear in any log output
