alog is to agent execution what logger is to syslog: a structured append primitive. It writes timestamped, typed events to JSONL files that any tool can read. AI agents are black boxes. You ask them to do something, they do... something. But what? alog makes agents auditable. Every action becomes a line in a log file that you can search with grep, query with aaud, analyze with jq, or diff against yesterday's log. If you can't inspect it, you can't trust it. alog is the foundation of observable AI agents.
Part of the Shell Agentics toolkit - small programs that compose via pipes and text streams to build larger agentic structures using Unix primitives. No frameworks. No magic. Total observability.
alog — structured execution logger for shell-native AI agents
alog --agent NAME --event TYPE [--message TEXT] [OPTIONS]
echo "message" | alog --agent NAME --event TYPE [OPTIONS]
alog appends structured log entries to JSONL (JSON Lines) files. Each invocation writes exactly one log entry containing a timestamp, agent name, event type, and message. Logs are append-only and human-readable.
--agent=NAME : The name of the agent generating this log entry. Required. Used to determine which log file to write to and appears in the log entry itself.
--event=TYPE : The type of event being logged. Required. Common conventions:
request— an incoming task or messagereasoning— the agent's chain of thought (optional, for transparency)execution— a shell command the agent rancomplete— task finished successfullyerror— something went wrong
--message=TEXT : The log message content. If not provided, reads from stdin. This allows piping output directly into the logger.
--exit-code=N
: Optional exit code to record (typically used with execution events to capture command success/failure).
--log-dir=PATH
: Directory where log files are written. Defaults to $AGENT_LOG_DIR environment variable, or ./logs if not set.
--help : Display usage information and exit.
--version : Display version number and exit.
Logs are written in JSONL format — one JSON object per line. This format is:
- Human-readable (it's just JSON)
- Machine-parseable (use
jqfor queries) - Append-friendly (no file locking needed)
- Grep-friendly (one event = one line)
Example log entries:
{"ts":"2024-01-15T06:00:01Z","agent":"data","event":"request","message":"Verify backup integrity"}
{"ts":"2024-01-15T06:00:03Z","agent":"data","event":"execution","message":"sha256sum /backup/*","exit_code":0}
{"ts":"2024-01-15T06:00:04Z","agent":"data","event":"complete","message":"All 47 files verified"}$AGENT_LOG_DIR/{agent}.jsonl : Per-agent log file. Contains only entries for the named agent.
$AGENT_LOG_DIR/all.jsonl : Combined log file. Contains entries from all agents, interleaved chronologically.
AGENT_LOG_DIR
: Default directory for log files. Overridden by --log-dir.
Log a request received by the "data" agent:
echo "Verify backup integrity" | alog --agent data --event requestLog a command execution with exit code:
alog --agent data --event execution \
--message "sha256sum /backup/2024-01-15/*" \
--exit-code 0Log to a specific directory:
alog --agent aurora --event error \
--message "Disk usage exceeded 90%" \
--log-dir /var/log/agentsTypical usage in an agent script:
# At start of task
echo "$USER_REQUEST" | alog --agent "$AGENT" --event request
# After completing work
echo "$RESULT" | alog --agent "$AGENT" --event completeQuery logs with standard Unix tools:
# What happened today?
grep "2024-01-15" logs/all.jsonl | jq .
# Did any agent hit an error?
grep '"event":"error"' logs/all.jsonl
# What commands did the data agent run?
jq 'select(.agent=="data" and .event=="execution")' logs/data.jsonl0 — Log entry written successfully
1 — Error (missing required arguments, write failure, etc.)
aaud(1) — query and inspect log files created by alog
amem(1) — persistent key-value storage for agents
agent(1) — the LLM inference primitive
JSONL (JSON Lines) was chosen over other formats because:
-
One line = one event. You can
grepfor events,wc -lto count them,tail -fto watch them live. -
No parsing state. Unlike XML or multi-line JSON, you can start reading from any line. Append new entries without rewriting the file.
-
Universal tooling.
jqhandles complex queries. Every programming language has JSON parsers. -
Human-debuggable. When something goes wrong at 3am, you can
catthe log and read it.
-
Append-only by design. Logs are never modified or rotated by this tool. Use standard Unix tools (
logrotate,split) if needed. -
No buffering. Each invocation is a complete write. Safe for concurrent use by multiple agents.
-
Timestamps are UTC. Always. No timezone ambiguity.
-
Exit codes are optional. Not every event has one. Only include when meaningful.
Part of the Shell Agentics project — https://github.com/shellagentics
MIT