Log

A configurable logging framework for Chapel programs.

Provides leveled logging (ERROR, WARNING, INFO, DEBUG) with customizable output streams, formatting, and color support. Log levels can be controlled at runtime via environment variables.

Quick start:

import Log;
import Log.{MN, RN, LN};

var log = new Log.logger("myApp");
log.info("Application started");
log.warn("Something looks odd");
log.error("Something went wrong");

// Include source location information:
log.info(MN(), RN(), LN(), "message with location");

Key features:

  • Extensible for custom log formats and outputs by subclassing LogStream and LogFormat

  • Automatic runtime log level control via environment variables (e.g. MYAPP_LOG_LEVEL=debug)

  • Built-in color support with support for auto-detection of TTY output and customizable color schemes

  • Built-in log format/stream options to cover common use cases (e.g. StderrStream, FileStream, JsonFormat)

enum LogLevel { NONE, ERROR, WARNING, INFO, DEBUG }

Represents the severity level of a log message.

Levels are ordered from least to most verbose: NONE < ERROR < WARNING < INFO < DEBUG.

Setting a logger’s level to a given value enables all messages at that level and below. For example, INFO enables INFO, WARNING, and ERROR messages. NONE disables all logging.

enum constant NONE
enum constant ERROR
enum constant WARNING
enum constant INFO
enum constant DEBUG
record logger

The primary interface for emitting log messages.

Create a logger with a name and optional configuration, then call its level methods (info, warn, error, debug) to emit messages.

var log = new Log.logger("myApp");
log.info("server started on port ", port);
log.error("connection failed");
var name : string

The display name for this logger, included in formatted output.

var logLevel : LogLevel

The current log level threshold. Messages below this level are discarded.

var stream : shared LogStream

The output stream where formatted log messages are written.

See LogStream and its subclasses for built-in stream types, or subclass LogStream to implement custom log destinations.

var format : shared LogFormat

The formatter used to produce log message strings.

See LogFormat and its subclasses for built-in formatters, or subclass LogFormat to implement custom formatting logic.

proc init(name: string, logLevel: LogLevel = LogLevel.INFO, colorMode: ColorMode = ColorMode.AUTO, logLevelEnvVar: string = LogLevel.makeEnvName(name), in stream: LogStream? = nil: shared LogStream?, in format: LogFormat? = nil: shared LogFormat?)

Create a new logger.

Arguments:
  • name – A display name for this logger, also used to derive the default environment variable name (e.g. "myApp" checks MY_APP_LOG_LEVEL).

  • logLevel – The default log level. Overridden by the environment variable if set. Defaults to LogLevel.INFO.

  • colorMode – Controls ANSI color output. Defaults to AUTO, which enables color when the output stream is a TTY.

  • logLevelEnvVar – The environment variable name to check for a runtime log level override. Defaults to <NAME>_LOG_LEVEL (uppercased, non-alphanumeric characters replaced with _).

  • stream – The output stream. Pass nil (default) to log use the default output stream (LogStream), or another subclass of LogStream.

  • format – The log formatter. Pass nil (default) to use the standard format (LogFormat), or another subclass of LogFormat.

proc info(message ...)

Log a message at the INFO level. Accepts any number of arguments, which are stringified and concatenated. Use the overload with moduleName, routineName, and lineNumber to include source location in the output (pass MN(), RN(), LN(), respectively, for automatic capture).

The infof variant accepts a format string followed by arguments, using Chapel’s formatted I/O syntax.

proc infof(format: string, args ...)
proc info(moduleName: string, routineName: string, lineNumber: int, message ...)
proc infof(moduleName: string, routineName: string, lineNumber: int, format: string, args ...)
proc debug(message ...)

Log a message at the DEBUG level. This is the most verbose level and is typically used for development diagnostics. Only emitted when the logger’s level is DEBUG.

Accepts the same overloads as info.

proc debugf(format: string, args ...)
proc debug(moduleName: string, routineName: string, lineNumber: int, message ...)
proc debugf(moduleName: string, routineName: string, lineNumber: int, format: string, args ...)
proc warn(message ...)

Log a message at the WARNING level. Use for potentially harmful situations that do not prevent normal operation.

Accepts the same overloads as info.

proc warnf(format: string, args ...)
proc warn(moduleName: string, routineName: string, lineNumber: int, message ...)
proc warnf(moduleName: string, routineName: string, lineNumber: int, format: string, args ...)
proc error(message ...)

Log a message at the ERROR level. Use for error conditions that may still allow the program to continue.

Accepts the same overloads as info.

proc errorf(format: string, args ...)
proc error(moduleName: string, routineName: string, lineNumber: int, message ...)
proc errorf(moduleName: string, routineName: string, lineNumber: int, format: string, args ...)
proc flush()

Flush the output stream, ensuring that all buffered log messages are written out. This can be useful to call before program exit to ensure all logs are captured, or after critical log messages to ensure they are not lost if the program crashes.

class LogStream

Base class for log output destinations. LogStream can be subclassed to override and customize aspects of the log output.

The default implementation writes log messages to stdout.

Customization points for subclasses:

  • Override write to change how messages are written.

  • Override flush to control flushing behavior.

  • Override handleError to implement custom error handling when I/O errors occur during writing or flushing.

  • Override getFile to return the underlying file for this stream. This is important for proper auto-color detection when using ColorMode.AUTO.

proc write(message: string)
proc flush()
proc handleError(error, args)
proc getFile() : file

Return the underlying file for this stream.

class StderrStream : LogStream

A LogStream that writes log messages to stderr instead of stdout.

override proc write(message: string)
override proc flush()
override proc getFile() : file
class FileStream : LogStream

A LogStream that writes log messages to a file.

var log = new Log.logger("app",
                             stream=new Log.FileStream("app.log"));
proc init(filename: string)

Create a FileStream that writes to the given file path. The file is created or truncated on open.

Arguments:

filename – The path to the log file.

override proc write(message: string)
override proc flush()
override proc getFile() : file
class JsonStream : FileStream

A FileStream that writes log entries as a JSON array to a file.

The output file contains a JSON object with a "logs" key holding an array of entries. Pair with JsonFormat to produce valid JSON log entries.

var log = new Log.logger("app",
                             stream=new Log.JsonStream("app.json"),
                             format=new Log.JsonFormat());
proc init(filename: string)

Create a JsonStream that writes JSON log entries to the given file.

Arguments:

filename – The path to the JSON log file.

override proc write(message: string)

Write a JSON log entry to the file. The message argument should already be a valid JSON object string (as produced by JsonFormat).

enum ColorMode { AUTO, ALWAYS, NEVER }

Controls whether ANSI color escape codes are included in log output.

enum constant AUTO

Enable color when the output stream is connected to a TTY.

enum constant ALWAYS

Always include ANSI color codes.

enum constant NEVER

Never include color codes (plain text output).

class LogFormat

Controls how log messages are formatted before being written to a LogStream.

The format is defined by a template string containing placeholders delimited by %. The following placeholders are available:

  • %T% — timestamp (dateTime cast to string)

  • %LL% — log level (e.g. info, error)

  • %M% — module name

  • %R% — routine name

  • %N% — line number

  • %NAME% — logger name

  • %m% — the log message

The default format string is "%T% %M%.%R%:%N% [%LL%] - %m%".

For example, the following creates a logger that produces messages like "myApp [info]: message":

var fmt = new Log.LogFormat("%NAME% [%LL%]: %m%");
var log = new Log.logger("app", format=fmt);

Customization points for subclasses:

  • Override format for complete control over message formatting.

  • Override styleForTimestamp to change the styling of the timestamp portion of the output.

  • Override styleForLogName to change the styling of the logger name in the output.

  • Override styleForLogLevel to change the styling of the log level label in the output.

var formatString : templateString

The compiled template string used to produce log messages.

var useColor : bool

Whether ANSI color codes are applied to the formatted output.

proc init(formatString: string = "%T% %M%.%R%:%N% [%LL%] - %m%", useColor: bool = false)

Create a LogFormat with the given template string.

Arguments:

formatString – A template string with %-delimited placeholders.

proc setUseColor(colorMode: ColorMode, stream: borrowed LogStream? = nil)

Compute whether color should be used based on the given mode and stream.

This is called automatically by the logger at initialization, but can be called manually to update color usage if the output stream changes or if you want to change color modes at runtime.

Arguments:
  • colorMode – The color mode to use

  • stream – The output stream that will be printing the log messages.

proc format(timestamp: dateTime, level: LogLevel, moduleName: string, routineName: string, lineNumber: int, loggerName: string, message: string) : string

Produce a formatted log message string from the given components. Override this method in a subclass for complete control over how log messages are formatted.

proc styleForTimestamp(level: LogLevel) : styledText

Returns the styledText applied to the timestamp in the formatted output. Override in a subclass to customize.

proc styleForLogName(level: LogLevel) : styledText

Returns the styledText applied to the logger name in the formatted output. Override in a subclass to customize.

proc styleForLogLevel(level: LogLevel) : styledText

Returns the styledText applied to the log level label in the formatted output. Override in a subclass to customize.

class JsonFormat : LogFormat

A LogFormat that produces JSON object strings.

Each call to format returns a single-line JSON object containing all log fields. String values are escaped for safe JSON output. Pair with JsonStream to write a complete JSON log file.

var log = new Log.logger("app",
                             stream=new Log.JsonStream("app.json"),
                             format=new Log.JsonFormat());
override proc format(timestamp: dateTime, level: LogLevel, moduleName: string, routineName: string, lineNumber: int, loggerName: string, message: string) : string