Provide method to set logging level per scope (#8584)

This commit is contained in:
Lee Cannon 2021-06-09 10:23:45 +01:00 committed by GitHub
parent 5fa5fba3ce
commit 50822530d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 1 deletions

View file

@ -117,13 +117,30 @@ pub const level: Level = if (@hasDecl(root, "log_level"))
else else
default_level; default_level;
pub const ScopeLevel = struct {
scope: @Type(.EnumLiteral),
level: Level,
};
const scope_levels = if (@hasDecl(root, "scope_levels"))
root.scope_levels
else
[0]ScopeLevel{};
fn log( fn log(
comptime message_level: Level, comptime message_level: Level,
comptime scope: @Type(.EnumLiteral), comptime scope: @Type(.EnumLiteral),
comptime format: []const u8, comptime format: []const u8,
args: anytype, args: anytype,
) void { ) void {
if (@enumToInt(message_level) <= @enumToInt(level)) { const effective_log_level = blk: {
inline for (scope_levels) |scope_level| {
if (scope_level.scope == scope) break :blk scope_level.level;
}
break :blk level;
};
if (@enumToInt(message_level) <= @enumToInt(effective_log_level)) {
if (@hasDecl(root, "log")) { if (@hasDecl(root, "log")) {
root.log(message_level, scope, format, args); root.log(message_level, scope, format, args);
} else if (std.Target.current.os.tag == .freestanding) { } else if (std.Target.current.os.tag == .freestanding) {

View file

@ -516,4 +516,87 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
break :x tc; break :x tc;
}); });
// It is required to override the log function in order to print to stdout instead of stderr
cases.add("std.log per scope log level override",
\\const std = @import("std");
\\
\\pub const log_level: std.log.Level = .debug;
\\
\\pub const scope_levels = [_]std.log.ScopeLevel{
\\ .{ .scope = .a, .level = .alert },
\\ .{ .scope = .c, .level = .emerg },
\\};
\\
\\const loga = std.log.scoped(.a);
\\const logb = std.log.scoped(.b);
\\const logc = std.log.scoped(.c);
\\
\\pub fn main() !void {
\\ loga.debug("", .{});
\\ logb.debug("", .{});
\\ logc.debug("", .{});
\\
\\ loga.info("", .{});
\\ logb.info("", .{});
\\ logc.info("", .{});
\\
\\ loga.notice("", .{});
\\ logb.notice("", .{});
\\ logc.notice("", .{});
\\
\\ loga.warn("", .{});
\\ logb.warn("", .{});
\\ logc.warn("", .{});
\\
\\ loga.err("", .{});
\\ logb.err("", .{});
\\ logc.err("", .{});
\\
\\ loga.crit("", .{});
\\ logb.crit("", .{});
\\ logc.crit("", .{});
\\
\\ loga.alert("", .{});
\\ logb.alert("", .{});
\\ logc.alert("", .{});
\\
\\ loga.emerg("", .{});
\\ logb.emerg("", .{});
\\ logc.emerg("", .{});
\\}
\\pub fn log(
\\ comptime level: std.log.Level,
\\ comptime scope: @TypeOf(.EnumLiteral),
\\ comptime format: []const u8,
\\ args: anytype,
\\) void {
\\ const level_txt = switch (level) {
\\ .emerg => "emergency",
\\ .alert => "alert",
\\ .crit => "critical",
\\ .err => "error",
\\ .warn => "warning",
\\ .notice => "notice",
\\ .info => "info",
\\ .debug => "debug",
\\ };
\\ const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
\\ const stdout = std.io.getStdOut().writer();
\\ nosuspend stdout.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
\\}
,
\\debug(b):
\\info(b):
\\notice(b):
\\warning(b):
\\error(b):
\\critical(b):
\\alert(a):
\\alert(b):
\\emergency(a):
\\emergency(b):
\\emergency(c):
\\
);
} }