# Logging Logging has two layers. The bare `log` verb is the always-on disk logger: it appends formatted values to `<tmp-dir>/deft.log` and bypasses every host-level redirect (TUI error console, echo capture). On top of it, the leveled `log/debug`, `log/info`, `log/warn`, and `log/error` functions tag each record and feed the workspace error console, and the `[debug ...]` / `[info ...]` / `[warn ...]` / `[error ...]` macros from `deft/stdext/logging` add level filtering at compile time. Everything except the macros is available without an import. ## Functions | Function | Purpose | |---|---| | `log v ...` | Append values to `<tmp-dir>/deft.log`, bypassing capture and TUI redirects | | `log/debug v ...` | `DEBUG` record — log file only, not the error console | | `log/info v ...` | `INFO` record — log file and error console | | `log/warn v ...` | `WARN` record — log file and error console | | `log/error v ...` | `ERROR` record — log file and error console | Notes: - `<tmp-dir>` is the per-process temp directory (`[fs/tmp-dir]`, e.g. `/tmp/deft-12345`). Bare `log` writes the values space-separated plus a newline, with no level or timestamp; the `log/*` functions prefix `[<epoch-ms>] LEVEL ` and write one line per call regardless of host. - In the TUI hosts, `log/info`, `log/warn`, and `log/error` also surface in the workspace error console; `log/debug` stays in the file. In the scripting binary the console reporter is a no-op, so every level goes to disk only. - The `log/*` functions are not level-filtered: they always write. Filtering lives in the macros from `deft/stdext/logging`, loaded with `require` — it must be `require`, not `import`, so the macros are available at compile time. Each macro appends the call site as `(file:line:col)` and wraps its `log/*` call in `[macro/compile-when ...]`. - `DEFT_LOG_LEVEL` is read when the logging module loads. A filtered call site produces no runtime code at all. Accepted values are `debug` (the default), `info`, `warn`, `error`, and `off` / `none`; changing the variable requires a recompile for the filtering to shift. ## Examples
require "deft/stdext/logging"

[debug "loading" "/etc/app.conf"]        # file only
[info "server started on port" 8080]     # file + error console
[warn "disk usage at" 91 "%"]
[error "failed to open" "/etc/missing"]

# Built-ins ignore DEFT_LOG_LEVEL and always write, with their own tag:
[log/info "this still lands in deft.log"]
[log "and so does this"]                 # bare log: no level, no console
### Inspecting the log file
set state %{ :user "alice" :tries 2 }
[log "state snapshot" $state]
[log %{ :event :sync :ok true }]

set path [fs/join [fs/tmp-dir] "deft.log"]
echo $path
echo [unwrap [fs/read $path]]
With `DEFT_LOG_LEVEL=warn`, the `[info ...]` and `[debug ...]` call sites above compile to nothing, while `[warn ...]` and `[error ...]` remain; the direct `log/*` calls are unaffected. ## See Also - IO — channels, `echo`, and the bare `log` verb - Filesystem — reading the log file back - Debug Server — runtime error reporting