improved logging
This commit is contained in:
@@ -272,7 +272,9 @@ if (is_actor(some_value)) {
|
||||
|
||||
### log
|
||||
|
||||
Logging functions: `log.console(msg)`, `log.error(msg)`, `log.system(msg)`.
|
||||
Channel-based logging. Any `log.X(value)` writes to channel `"X"`. Three channels are conventional: `log.console(msg)`, `log.error(msg)`, `log.system(msg)` — but any name works.
|
||||
|
||||
Channels are routed to configurable **sinks** (console or file) defined in `.cell/log.toml`. See [Logging](/docs/logging/) for the full guide.
|
||||
|
||||
### use(path)
|
||||
|
||||
|
||||
78
docs/cli.md
78
docs/cli.md
@@ -286,6 +286,84 @@ Clean build artifacts.
|
||||
pit clean
|
||||
```
|
||||
|
||||
## Logging
|
||||
|
||||
### pit log
|
||||
|
||||
Manage log sinks and read log files. See [Logging](/docs/logging/) for the full guide.
|
||||
|
||||
### pit log list
|
||||
|
||||
List configured sinks.
|
||||
|
||||
```bash
|
||||
pit log list
|
||||
```
|
||||
|
||||
### pit log add
|
||||
|
||||
Add a log sink.
|
||||
|
||||
```bash
|
||||
pit log add <name> console [options] # add a console sink
|
||||
pit log add <name> file <path> [options] # add a file sink
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `--format=pretty|bare|json` — output format (default: `pretty` for console, `json` for file)
|
||||
- `--channels=ch1,ch2` — channels to subscribe (default: `console,error,system`). Use `'*'` for all channels (quote to prevent shell glob expansion).
|
||||
- `--exclude=ch1,ch2` — channels to exclude (useful with `'*'`)
|
||||
|
||||
```bash
|
||||
pit log add terminal console --format=bare --channels=console
|
||||
pit log add errors file .cell/logs/errors.jsonl --channels=error
|
||||
pit log add dump file .cell/logs/dump.jsonl '--channels=*' --exclude=console
|
||||
```
|
||||
|
||||
### pit log remove
|
||||
|
||||
Remove a sink.
|
||||
|
||||
```bash
|
||||
pit log remove <name>
|
||||
```
|
||||
|
||||
### pit log read
|
||||
|
||||
Read entries from a file sink.
|
||||
|
||||
```bash
|
||||
pit log read <sink> [options]
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `--lines=N` — show last N entries
|
||||
- `--channel=X` — filter by channel
|
||||
- `--since=timestamp` — only show entries after timestamp (seconds since epoch)
|
||||
|
||||
```bash
|
||||
pit log read errors --lines=50
|
||||
pit log read dump --channel=debug --lines=10
|
||||
pit log read errors --since=1702656000
|
||||
```
|
||||
|
||||
### pit log tail
|
||||
|
||||
Follow a file sink in real time.
|
||||
|
||||
```bash
|
||||
pit log tail <sink> [--lines=N]
|
||||
```
|
||||
|
||||
`--lines=N` controls how many existing entries to show on start (default: 10).
|
||||
|
||||
```bash
|
||||
pit log tail dump
|
||||
pit log tail errors --lines=20
|
||||
```
|
||||
|
||||
## Developer Commands
|
||||
|
||||
Compiler pipeline tools, analysis, and testing. These are primarily useful for developing the ƿit compiler and runtime.
|
||||
|
||||
202
docs/logging.md
Normal file
202
docs/logging.md
Normal file
@@ -0,0 +1,202 @@
|
||||
---
|
||||
title: "Logging"
|
||||
description: "Configurable channel-based logging with sinks"
|
||||
weight: 25
|
||||
type: "docs"
|
||||
---
|
||||
|
||||
Logging in ƿit is channel-based. Any `log.X(value)` call writes to channel `"X"`. Channels are routed to **sinks** — named destinations that format and deliver log output to the console or to files.
|
||||
|
||||
## Channels
|
||||
|
||||
Three channels are conventional:
|
||||
|
||||
| Channel | Usage |
|
||||
|---------|-------|
|
||||
| `log.console(msg)` | General output |
|
||||
| `log.error(msg)` | Errors and warnings |
|
||||
| `log.system(msg)` | Internal system messages |
|
||||
|
||||
Any name works. `log.debug(msg)` creates channel `"debug"`, `log.perf(msg)` creates `"perf"`, and so on.
|
||||
|
||||
```javascript
|
||||
log.console("server started on port 8080")
|
||||
log.error("connection refused")
|
||||
log.debug({query: "SELECT *", rows: 42})
|
||||
```
|
||||
|
||||
Non-text values are JSON-encoded automatically.
|
||||
|
||||
## Default Behavior
|
||||
|
||||
With no configuration, a default sink routes `console`, `error`, and `system` to the terminal in pretty format:
|
||||
|
||||
```
|
||||
[a3f12] [console] main.ce:5 server started on port 8080
|
||||
[a3f12] [error] main.ce:12 connection refused
|
||||
```
|
||||
|
||||
The format is `[actor_id] [channel] file:line message`.
|
||||
|
||||
## Configuration
|
||||
|
||||
Logging is configured in `.cell/log.toml`. Each `[sink.NAME]` section defines a sink.
|
||||
|
||||
```toml
|
||||
[sink.terminal]
|
||||
type = "console"
|
||||
format = "bare"
|
||||
channels = ["console"]
|
||||
|
||||
[sink.errors]
|
||||
type = "file"
|
||||
path = ".cell/logs/errors.jsonl"
|
||||
channels = ["error"]
|
||||
|
||||
[sink.everything]
|
||||
type = "file"
|
||||
path = ".cell/logs/all.jsonl"
|
||||
channels = ["*"]
|
||||
exclude = ["console"]
|
||||
```
|
||||
|
||||
### Sink fields
|
||||
|
||||
| Field | Values | Description |
|
||||
|-------|--------|-------------|
|
||||
| `type` | `"console"`, `"file"` | Where output goes |
|
||||
| `format` | `"pretty"`, `"bare"`, `"json"` | How output is formatted |
|
||||
| `channels` | array of names, or `["*"]` | Which channels this sink receives |
|
||||
| `exclude` | array of names | Channels to skip (useful with `"*"`) |
|
||||
| `path` | file path | Output file (file sinks only) |
|
||||
|
||||
### Formats
|
||||
|
||||
**pretty** — human-readable, one line per message. Includes actor ID, channel, source location, and message.
|
||||
|
||||
```
|
||||
[a3f12] [console] main.ce:5 server started
|
||||
```
|
||||
|
||||
**bare** — minimal. Actor ID and message only.
|
||||
|
||||
```
|
||||
[a3f12] server started
|
||||
```
|
||||
|
||||
**json** — structured JSONL (one JSON object per line). Used for file sinks and machine consumption.
|
||||
|
||||
```json
|
||||
{"actor_id":"a3f12...","timestamp":1702656000.5,"channel":"console","event":"server started","source":{"file":"main.ce","line":5,"column":3,"function":"init"}}
|
||||
```
|
||||
|
||||
## Log Records
|
||||
|
||||
Every log call produces a record:
|
||||
|
||||
```javascript
|
||||
{
|
||||
actor_id: "a3f12...", // full actor GUID
|
||||
timestamp: 1702656000.5, // seconds since epoch
|
||||
channel: "console", // channel name
|
||||
event: "the message", // value passed to log
|
||||
source: {
|
||||
file: "main.ce",
|
||||
line: 5,
|
||||
column: 3,
|
||||
function: "init"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
File sinks write one JSON-encoded record per line. Console sinks format the record according to their format setting.
|
||||
|
||||
## CLI
|
||||
|
||||
The `pit log` command manages sinks and reads log files. See [CLI — pit log](/docs/cli/#pit-log) for the full reference.
|
||||
|
||||
```bash
|
||||
pit log list # show sinks
|
||||
pit log add terminal console --format=bare --channels=console
|
||||
pit log add dump file .cell/logs/dump.jsonl --channels='*' --exclude=console
|
||||
pit log remove terminal
|
||||
pit log read dump --lines=20 --channel=error
|
||||
pit log tail dump
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Development setup
|
||||
|
||||
Route console output to the terminal with minimal formatting. Send everything else to a structured log file for debugging.
|
||||
|
||||
```toml
|
||||
[sink.terminal]
|
||||
type = "console"
|
||||
format = "bare"
|
||||
channels = ["console"]
|
||||
|
||||
[sink.debug]
|
||||
type = "file"
|
||||
path = ".cell/logs/debug.jsonl"
|
||||
channels = ["*"]
|
||||
exclude = ["console"]
|
||||
```
|
||||
|
||||
```javascript
|
||||
log.console("listening on :8080") // -> terminal: [a3f12] listening on :8080
|
||||
log.error("bad request") // -> debug.jsonl only
|
||||
log.debug({latency: 0.042}) // -> debug.jsonl only
|
||||
```
|
||||
|
||||
### Separate error log
|
||||
|
||||
Keep a dedicated error log alongside a full dump.
|
||||
|
||||
```toml
|
||||
[sink.terminal]
|
||||
type = "console"
|
||||
format = "pretty"
|
||||
channels = ["console", "error", "system"]
|
||||
|
||||
[sink.errors]
|
||||
type = "file"
|
||||
path = ".cell/logs/errors.jsonl"
|
||||
channels = ["error"]
|
||||
|
||||
[sink.all]
|
||||
type = "file"
|
||||
path = ".cell/logs/all.jsonl"
|
||||
channels = ["*"]
|
||||
```
|
||||
|
||||
### JSON console
|
||||
|
||||
Output structured JSON to the console for piping into other tools.
|
||||
|
||||
```toml
|
||||
[sink.json_out]
|
||||
type = "console"
|
||||
format = "json"
|
||||
channels = ["console", "error"]
|
||||
```
|
||||
|
||||
```bash
|
||||
pit run myapp.ce | jq '.event'
|
||||
```
|
||||
|
||||
### Reading logs
|
||||
|
||||
```bash
|
||||
# Last 50 error entries
|
||||
pit log read errors --lines=50
|
||||
|
||||
# Errors since a timestamp
|
||||
pit log read errors --since=1702656000
|
||||
|
||||
# Filter a wildcard sink to one channel
|
||||
pit log read all --channel=debug --lines=10
|
||||
|
||||
# Follow a log file in real time
|
||||
pit log tail all
|
||||
```
|
||||
Reference in New Issue
Block a user