From ae44478b30d890fe0fb04022f44d474dcdcc3f9d Mon Sep 17 00:00:00 2001 From: Lassi Pulkkinen Date: Thu, 31 Oct 2024 03:11:21 +0200 Subject: Initial commit (import old repo) --- tracer.ha | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 tracer.ha (limited to 'tracer.ha') diff --git a/tracer.ha b/tracer.ha new file mode 100644 index 0000000..99f4189 --- /dev/null +++ b/tracer.ha @@ -0,0 +1,66 @@ +use memio; +use time::date; +use fmt; +use io; +use strings; +use trace; + +type Tracer = struct { + trace::tracer, + sink: io::handle, +}; + +fn newtracer(sink: io::handle) Tracer = + Tracer { + log = &tracer_log, + sink = sink, + }; + +fn tracer_log( + tr: *trace::tracer, + ctx: nullable *trace::context, + lvl: trace::level, + fmt: str, + fields: fmt::field... +) void = { + const tr = tr: *Tracer; + + // XXX: ideally there would be a statically allocated buffer for + // reasonably short messages and allocation would only happen for + // messages longer than that. ideally ideally there would be locking so + // we wouldn't need to allocate at all. + const buf = memio::dynamic_from(alloc([], 256)); + defer io::close(&buf)!; + + const now = date::now(); + io::write(&buf, [0x5b])!; // "[" + date::format(&buf, date::STAMP, &now)!; + io::write(&buf, [0x5d, 0x20])!; // "] " + + const lvlstr = switch (lvl) { + case trace::level::ERROR => + yield "error: "; + case trace::level::WARN => + yield "warning: "; + case trace::level::INFO => + yield "info: "; + case trace::level::DEBUG => + yield "debug: "; + case trace::level::TRACE => + yield "trace: "; + }; + io::write(&buf, strings::toutf8(lvlstr))!; + + let ctx_ = ctx; + for (true) match (ctx_) { + case let ctx__: *trace::context => + fmt::fprintf(&buf, ctx__.fmt, ctx__.fields...)!; + io::write(&buf, [0x3a, 0x20])!; // ": " + ctx_ = ctx__.next; + case null => break; + }; + + fmt::fprintfln(&buf, fmt, fields...)!; + + io::write(tr.sink, memio::buffer(&buf)): void; +}; -- cgit v1.2.3