lily/logging

Erlang has a perfectly good logging package; JavaScript does not. Lily runs on both runtimes, so this module papers over the gap and the same calls work everywhere.

On Erlang, this is a thin wrapper around the logging hex package (the same logger used by mist and wisp), so Lily log lines blend in with framework logs. On JavaScript, log lines go to console.error / console.warn / console.info / console.debug by level, with the same colour palette the Erlang package uses. Works identically in browsers, Node, Bun, and Deno.

On Erlang, configure installs the logging package’s formatter and set_level sets the minimum level. On JavaScript, configure is a no-op and set_level maintains a programmatic level filter.

import lily/logging

pub fn main() {
  logging.configure()
  logging.set_level(logging.Info)
  logging.info("server ready")
  // Logs `INFO SomeMessage("hello")`:
  logging.auto_info(SomeMessage("hello"))
}

Types

Log severity. Matches the eight levels used by Erlang’s logger and the logging hex package.

pub type Level {
  Alert
  Critical
  Debug
  Emergency
  Error
  Info
  Notice
  Warning
}

Constructors

  • Alert
  • Critical
  • Debug
  • Emergency
  • Error
  • Info
  • Notice
  • Warning

Values

pub fn auto_debug(value: a) -> Nil

Inspect value with string.inspect and log the result at Debug level.

pub fn auto_error(value: a) -> Nil

Inspect value with string.inspect and log the result at Error level.

pub fn auto_info(value: a) -> Nil

Inspect value with string.inspect and log the result at Info level. This is probably used the most.

server.on_message(srv, fn(message, _model, _client_id) {
  logging.auto_info(message)  // e.g. logs "INFO AddTodo(\"milk\")"
})
pub fn auto_log(level: Level, value: a) -> Nil

Inspect value with string.inspect and log the result at the given level. The inspection is skipped when the level is suppressed, so passing a large model at Debug is cheap in production.

pub fn auto_warning(value: a) -> Nil

Inspect value with string.inspect and log the result at Warning level.

pub fn configure() -> Nil

Configure the default logger. On Erlang, this installs the logging package’s pretty formatter and sets the level to Info. On JavaScript, this is a no-op, the console is always ready.

pub fn debug(message: String) -> Nil

Shortcut for log(Debug, message).

pub fn error(message: String) -> Nil

Shortcut for log(Error, message).

pub fn info(message: String) -> Nil

Shortcut for log(Info, message).

pub fn is_enabled(level: Level) -> Bool

Returns True if a message at level would be emitted by the current logger configuration. Useful for guarding expensive payload construction outside the auto_* helpers.

case logging.is_enabled(logging.Debug) {
  True -> logging.debug(expensive_dump(state))
  False -> Nil
}
pub fn log(level: Level, message: String) -> Nil

Log a message at the given level.

pub fn set_level(level: Level) -> Nil

Set the minimum level of log messages to emit. Messages below this level are suppressed.

On Erlang, delegates to logger:set_primary_config. On JavaScript, maintains a module-level threshold, useful on Node/Bun/Deno servers where DevTools is not available.

pub fn warning(message: String) -> Nil

Shortcut for log(Warning, message).

Search Document