UXLog
UXLog is a small logging facility: a subsystem name, a minimum level, and
messages below that level dropped. os_log/syslog in shape.
#use <UXKit> // or #import "UXLog.xc"Overview
Section titled “Overview”UXLog* net = UXLog.forSubsystem((u8*)"net");net.setMinLevel(UX_LOG_INFO);
net.debug((u8*)"opening socket"); // dropped — below the levelnet.info((u8*)"connected to host"); // [INFO] net: connected to hostnet.warn((u8*)"read timeout after 30s");net.error((u8*)"giving up");Output goes to stdout by default. A syslog sink is a per-backend addition.
One logger per name
Section titled “One logger per name”UXLog.forSubsystem((u8*)"net") == UXLog.forSubsystem((u8*)"net"); // trueforSubsystem returns the same logger for a name, from a process-wide
registry, as os_log’s subsystem registry does.
A level set in one place applies everywhere that subsystem logs, and a module deep in a call stack does not need to be handed a logger. Raising the verbosity of one subsystem takes one line, anywhere.
shared is the unnamed logger for code that has no subsystem of its
own.
Monitors are the interesting part
Section titled “Monitors are the interesting part”net.addMonitor(UXRegex.compile((u8*)"timeout"), &self.onTimeout);Register a UXRegex and a callback, and the
callback fires whenever a logged message matches. The matching uses the
toolkit’s own regex engine.
With monitors, the program can react to its log as it is written. A test asserts that a particular message was produced; a diagnostic panel lights up when an error pattern appears; a retry counter increments without the networking code knowing anything is counting.
[WARN] net: read timeout after 30s MONITOR saw: read timeout after 30sThe callback is a callback, so a monitor
cannot keep its observer alive. When the observer is freed, its monitor
stops firing. This is the same lifetime model as
UXNotificationCenter.
Matching is test, not matches
Section titled “Matching is test, not matches”Monitors search the message rather than requiring the pattern to match all of
it. A pattern of "timeout" fires on "read timeout after 30s".
This suits a log watch. UXValidator’s
regex rule works the other way: its pattern must describe the entire field.
Both use the same engine.
Topics
Section titled “Topics”forSubsystem · shared · setMinLevel · setStdout · debug / info / warn / error · log · addMonitor · removeMonitor · monitorCount · levelName
forSubsystem
Section titled “forSubsystem”static UXLog* forSubsystem(u8* name)The logger for a name, made on first use and shared after that. The name is kept, not copied.
shared
Section titled “shared”static UXLog* shared(void)The default logger.
setMinLevel
Section titled “setMinLevel”void setMinLevel(i32 lvl)UX_LOG_DEBUG, UX_LOG_INFO, UX_LOG_WARN, UX_LOG_ERROR. Messages below it
are dropped, and monitors do not see them.
setStdout
Section titled “setStdout”void setStdout(bool on)Turn the stdout sink off. A logger with stdout off and a monitor attached is a silent watcher. This is useful in a test, where the monitor makes the assertion and the output would be noise.
debug / info / warn / error
Section titled “debug / info / warn / error”void debug(u8* msg)void info(u8* msg)void warn(u8* msg)void error(u8* msg)void log(i32 lvl, u8* msg)The general form. It takes a finished message with no format string, so build
the message with UXStr first.
addMonitor
Section titled “addMonitor”void addMonitor(UXRegex* pattern, callback cb void(u8* msg))removeMonitor
Section titled “removeMonitor”void removeMonitor(callback cb void(u8* msg))Matched on the callback, so the same callback cannot be registered twice with different patterns and removed individually.
monitorCount
Section titled “monitorCount”i32 monitorCount(void)levelName
Section titled “levelName”u8* levelName(i32 lvl)"DEBUG", "INFO", "WARN", "ERROR": what the stdout sink prints in
brackets.
Example
Section titled “Example”[INFO] net: connected to host[WARN] net: read timeout after 30s MONITOR saw: read timeout after 30s[ERROR] net: giving up monitor fired 1 time(s), monitors=1 same logger: 1The debug call, below the level, produced nothing. The program is
website/site/examples/uxkit/toolbox.xc. The doc-examples gate compiles it,
and the listing above is its output.
Conforms to
Section titled “Conforms to”- A plain class (not an
Objectsubclass)
See also
Section titled “See also”UXLogMonitor: one watchUXRegex: the patternsUXNotificationCenter: the same weak-observer lifetime model, for announcements rather than logs