# "Logging" _Path: en/lua/system/logger_ > "Structured logging with debug, info, warn, and error levels." ## Table of Contents - Logging ## Content # Logging The `logger` module writes structured messages at debug, info, warn, and error levels. This is an API reference. Each snippet is an isolated logging operation and assumes an execution context with the desired logger configuration. Log calls return no values. When the execution context provides them, each call also adds the process `pid` and the source `location` derived from the current frame. ## Loading ```lua local logger = require("logger") ``` ### `logger:debug` Write a debug-level log message. ```lua logger:debug("message", {key = "value"}) ``` ### `logger:info` Write an info-level log message. ```lua logger:info("message", {key = "value"}) ``` ### `logger:warn` Write a warning-level log message. ```lua logger:warn("message", {key = "value"}) ``` ### `logger:error` Write an error-level log message. ```lua logger:error("message", {key = "value"}) ``` All four log-level methods accept the same parameters: | Parameter | Type | Description | |-----------|------|-------------| | `message` | string | Log message | | `fields` | table? | Contextual key-value pairs | Only string keys become field names. Strings, numbers, integers, booleans, errors, and structured Lua values are converted to log fields; non-string keys are ignored. For `logger:error`, a field named `error` is emitted as an error field and removed from the supplied table before the remaining fields are processed. Do not reuse that table if the `error` entry must remain intact. ### `logger:with` Create a child logger that adds the same fields to every message. ```lua local function request_logger(request_id) return logger:with({request_id = request_id}) end request_logger("req-123"):info("message") ``` | Parameter | Type | Description | |-----------|------|-------------| | `fields` | table | Fields to attach to all logs | **Returns:** `Logger` The original logger is unchanged. Child loggers can be chained with additional `with` and `named` calls. ### `logger:named` Create a child logger with a name. ```lua local named = logger:named("auth") named:info("message") ``` | Parameter | Type | Description | |-----------|------|-------------| | `name` | string | Logger name | **Returns:** `Logger` An empty name raises a Lua argument error. It is not returned as a structured `errors.INVALID` value. `logger:named("")` raises a Lua argument error (`name cannot be empty`) instead of returning an error value. Logging methods return nothing. See [Error Handling](lua/core/errors.md) for working with errors. ## Navigation Previous: "Environment Variables" (lua/system/env) Next: "Terminal I/O" (lua/system/io)