← All libraries

CandyLog

CandyLog

Colorful leveled logger

port of charmbracelet/log loggingclioutput

Minimal, colorful leveled logging. Debug / Info / Warn / Error / Fatal with structured key/value context, Text / JSON / Logfmt formatters, and sub-loggers with persistent fields.

Install

composer require sugarcraft/candy-log

Quickstart

use SugarCraft\Log\Logger;

$log = Logger::new();
$log->info('Starting oven', ['degree' => 375]);
$log->warn('Almost ready', ['batch' => 2]);
$log->error('Temperature too low', ['err' => 'underheated']);

$child = $log->with('service', 'bakery');
$child->info('Batch complete');

What's in the box

Leveled loggingDebug, Info, Warn, Error, Fatal. TTY detection enables color automatically.
Three formattersTextFormatter (default), JSONFormatter, LogfmtFormatter — swap via `withFormatter()`.
Structured contextArbitrary key/value pairs attached to every log call.
Sub-loggers`with(...)` creates a child logger that inherits all context.
StandardLogAdapterWrap any PSR-3 logger for `*log.Logger` compatibility.
PSR-3 bridge`PsrBridge` wraps a Logger and exposes the full PSR-3 LoggerInterface API.
Hook systemRegister per-level callbacks via `HookRegistry::onLevel()` for middleware-style interceptors.
Caller info`reportCaller` on Logger adds `file:line` of the true call site to every entry.
PartsOrder DTOConfigure which log-parts appear and in what order — default, syslog, or custom.

Source & demos

Try the quickstart →

API

ClassMethodDescription
Loggernew()Create a new logger
Loggerdebug(msg, context)Log debug message
Loggerinfo(msg, context)Log info message
Loggerwarn(msg, context)Log warning message
Loggererror(msg, context)Log error message
Loggerfatal(msg, context)Log fatal message
Loggerwith(array)Create child logger with persistent context
LoggerwithFormatter(Formatter)Set output formatter
LoggerwithMinLevel(Level)Set minimum output level
LoggerwithPrefix(string)Set per-line prefix
LoggersetReportCaller(bool)Enable/disable caller file:line reporting
LoggersetReportTimestamp(bool)Enable/disable timestamp
Loggerstyles()Get Styles object for level/field styling
Loggerstyles()->keys[name]Per-field ANSI style override (time, level, caller, message, key, value)
PsrBridgenew(Logger, ?HookRegistry)Wrap a Logger with full PSR-3 API
PsrBridgeemergency(msg, ctx)PSR-3 emergency — maps to Level::Fatal
PsrBridgealert(msg, ctx)PSR-3 alert — maps to Level::Fatal
PsrBridgecritical(msg, ctx)PSR-3 critical — maps to Level::Fatal
PsrBridgeerror(msg, ctx)PSR-3 error — maps to Level::Error
PsrBridgewarning(msg, ctx)PSR-3 warning — maps to Level::Warn
PsrBridgenotice(msg, ctx)PSR-3 notice — maps to Level::Info
PsrBridgeinfo(msg, ctx)PSR-3 info — maps to Level::Info
PsrBridgedebug(msg, ctx)PSR-3 debug — maps to Level::Debug
PsrBridgelog(level, msg, ctx)Generic PSR-3 log dispatch
HookRegistryonLevel(Level, callable): intRegister a callback for all events at/above Level
HookRegistryfire(Level, psrLevel, msg, ctx)Dispatch to all matching handlers
HookonLevel(Level, string, string, array)Interface for structured hook implementations
PartsOrdernew(?list)Config DTO for log-part ordering
PartsOrderdefault(): selfPreset: timestamp, level, prefix, caller, message, fields
PartsOrdersyslog(): selfPreset: timestamp, level, message, fields (no prefix/caller)
PartsOrdermessageFirst(): selfPreset: message, level, timestamp, fields
PartsOrderhas(PART_*): boolCheck whether a part is included in the order
PartsOrderPART_TIMESTAMP, PART_LEVEL, PART_PREFIX, PART_CALLER, PART_MESSAGE, PART_FIELDSPart name constants
CallerFormatterfind(): ?stringWalk call stack, return "file:line" of first external caller
LevelDebug, Info, Warn, Error, FatalEnum: syslog-aligned int values (-4, 0, 4, 8, 12)
TextFormatternew(bool, ?string, bool, bool)Human-readable formatter with ANSI color
JsonFormatternew(bool)JSON object per log line
LogfmtFormatternew()Logfmt key=value format
LoginstallPanicHandler()Install global panic handler (catches fatal errors + uncaught exceptions)
LogrestoreTerminal()Restore terminal from altscreen mode
LogsetLogger(Logger)Set the global logger instance
Loginfo(msg, ctx)Static shorthand — delegates to global logger
Logdebug/warn/error/fatal(msg, ctx)Static shorthands for each level

Demos.

VHS-recorded GIFs of every example shipped with the library. Regenerated automatically on every push that touches the source.

All log levels + formats

All log levels + formats

Debug / Info / Warn / Error / Fatal across Text / JSON / Logfmt formatters.