bunpen: lay groundwork for a better logger
This commit is contained in:
70
pkgs/additional/bunpen/log/tree/treelogger.ha
Normal file
70
pkgs/additional/bunpen/log/tree/treelogger.ha
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
// vim: set shiftwidth=2 :
|
||||||
|
//
|
||||||
|
// the "tree logger" ("hierarchical logger") allows selective display of log messages.
|
||||||
|
// it works by deriving a "depth" from each log statement, similar in notion to
|
||||||
|
// a log level, and then only forwarding log statements less than some depth.
|
||||||
|
//
|
||||||
|
// the "depth" is derived from the format string in `printfln`.
|
||||||
|
// typical fmts are like:
|
||||||
|
// - `printfln("message from root: {}", ...)`: has depth=0
|
||||||
|
// - `printfln("[module] says {}", ...)`: has depth=1
|
||||||
|
// - `printfln("[module/child] says {}", ...)`: has depth=2
|
||||||
|
// - `printfln("[module/child/grandchild] says {}", ...)`: has depth=3
|
||||||
|
//
|
||||||
|
// TODO: how are `println`'s handled?
|
||||||
|
|
||||||
|
use fmt;
|
||||||
|
use log;
|
||||||
|
|
||||||
|
export type logger = struct {
|
||||||
|
// vtable (println, printfln)
|
||||||
|
base: log::logger,
|
||||||
|
// where to forward those logs which pass the filter
|
||||||
|
forward: nullable *log::logger,
|
||||||
|
// 0 = log nothing
|
||||||
|
// 1 = log "toplevel" items (depth 1)
|
||||||
|
// 2 = log items of depth 1 or 2
|
||||||
|
// ...
|
||||||
|
level: uint,
|
||||||
|
};
|
||||||
|
|
||||||
|
let _global: logger = logger {
|
||||||
|
base = log::logger {
|
||||||
|
println = &log_println,
|
||||||
|
printfln = &log_printfln,
|
||||||
|
},
|
||||||
|
forward = null, // can't evaluate &log::default at compile time, so set null
|
||||||
|
level = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// treelogger with program lifetime, in case you don't want to manage that yourself
|
||||||
|
export const global: *logger = &_global;
|
||||||
|
|
||||||
|
// alias for `log::setlogger`, so that caller doesn't have to do manual casting
|
||||||
|
export fn install(me: *logger) void = {
|
||||||
|
log::setlogger(me: *log::logger);
|
||||||
|
};
|
||||||
|
|
||||||
|
export fn set_level(me: *logger, level: uint) void = {
|
||||||
|
me.level = level;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn log_println(base: *log::logger, fields: fmt::formattable...) void = {
|
||||||
|
let me = base: *logger;
|
||||||
|
if (me.level > 0) {
|
||||||
|
log::lprintln(get_forward(me), fields...);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fn log_printfln(base: *log::logger, fmt: str, fields: fmt::field...) void = {
|
||||||
|
let me = base: *logger;
|
||||||
|
if (me.level > 0) {
|
||||||
|
log::lprintfln(get_forward(me), fmt, fields...);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fn get_forward(me: *logger) *log::logger = {
|
||||||
|
return match (me.forward) {
|
||||||
|
case null => yield log::default;
|
||||||
|
case let l: *log::logger => yield l;
|
||||||
|
};
|
||||||
|
};
|
@@ -1,6 +1,7 @@
|
|||||||
// vim: set shiftwidth=2 :
|
// vim: set shiftwidth=2 :
|
||||||
use config;
|
use config;
|
||||||
use log;
|
use log;
|
||||||
|
use log::tree;
|
||||||
use restrict;
|
use restrict;
|
||||||
use rt;
|
use rt;
|
||||||
use rtext;
|
use rtext;
|
||||||
@@ -33,10 +34,9 @@ export fn main() void = {
|
|||||||
case let other: config::cli_request => yield other;
|
case let other: config::cli_request => yield other;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
log::tree::install(tree::global);
|
||||||
if (req.debug) {
|
if (req.debug) {
|
||||||
log::setlogger(log::default);
|
log::tree::set_level(tree::global, 1);
|
||||||
} else {
|
|
||||||
log::setlogger(log::silent);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let what = restrict::resources {
|
let what = restrict::resources {
|
||||||
|
Reference in New Issue
Block a user