Repository navigation
Configuration
All settings are process-wide and can be changed at any time from any thread.
Logging is disabled by default. Nothing is written until enable_logging(). disable_logging() turns it off again, and log_is_enabled() returns the current state.
Level::Debug < Level::Info < Level::Warn < Level::Error. Messages below the minimum level are dropped. The default minimum is Info.
coretrace::set_min_level(coretrace::Level::Warn); // Warn and Error only
coretrace::Level current = coretrace::min_level();The CT_LOG_LEVEL environment variable sets the startup default: debug, info, warn or error, case-insensitive. Any other value means info. A call to set_min_level() always wins over it.
A message can carry a module tag: log(Level::Info, Module("alloc"), "...").
- Until a module is enabled, every message passes.
- Once a module has been enabled with
enable_module(), tagged messages pass only if their module is enabled. Messages without a tag always pass. -
disable_module()removes one name. It never lets more messages through: after the last name is removed, tagged messages stay filtered. -
enable_all_modules()clears the filter, and every message passes again. -
module_is_enabled(name)tells whether a tagged message with that name would pass. -
Module("")counts as untagged: it bypasses the filter and prints no tag.
Names are case-sensitive. The filter holds up to 32 names of at most 31 characters. enable_module() returns false, and changes nothing, for an empty name, a longer name, or a full table.
CT_DEBUG=alloc,trace enables modules at startup. Spaces around names are ignored (CT_DEBUG="alloc, trace" works). Empty items are skipped, and so are names that do not fit the limits.
CT_LOG_LEVEL and CT_DEBUG are read once, at the first logger call that needs them (log(), a getter such as min_level(), or a filter setter) or, on POSIX, at the first fork(), whichever comes first. A module function called before that point makes the library ignore CT_DEBUG. Called afterwards, it changes the set loaded from CT_DEBUG.
set_prefix("==myapp==") replaces the default ==ct== tag. The string is copied, and truncated to 63 characters.
set_timestamps(true) starts each line with an ISO 8601 UTC timestamp with milliseconds: [2026-09-30T08:15:02.417] .
set_source_location(true) adds file.cpp:42 after the level. The file name and line come from std::source_location at the call site. Level converts implicitly to LogEntry, which captures it.
The library colors its output when stderr is a terminal: isatty() on POSIX, or a console that accepts virtual terminal sequences on Windows. It decides once per process, on first use. A child of fork() keeps the decision the parent had already made. Setting NO_COLOR to any non-empty value disables colors. An empty NO_COLOR keeps them, as no-color.org specifies.
| Level | Color |
|---|---|
DEBUG |
cyan |
INFO |
green |
WARN |
yellow |
ERROR |
red |
color(Color::Bold) returns an escape sequence you can put in your own messages, or an empty string when colors are off. The decision is based on stderr even when a custom sink is installed. Set NO_COLOR=1 if a sink must not receive escape sequences.
| Variable | Effect |
|---|---|
CT_LOG_LEVEL |
Startup minimum level: debug, info, warn, error (case-insensitive) |
CT_DEBUG |
Startup list of enabled modules, comma-separated |
NO_COLOR |
Disables colors when set to a non-empty value |
Using the library
Working on the library