authorgravatar for leecannon@leecannon.xyzLee Cannon <leecannon@leecannon.xyz> 2021-06-09 10:23:45+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-06-09 12:23:45+03:00
log50822530d334336b6ca00424547e8c03ebb6e2df
treecac5f01523c37aeb84c13a8043447dfa8bb9c24d
parent5fa5fba3ce57b128b37b371eb3daa8ca39221613
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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


2 files changed, 101 insertions(+), 1 deletions(-)

lib/std/log.zig+18-1
......@@ -117,13 +117,30 @@ pub const level: Level = if (@hasDecl(root, "log_level"))
117117else
118118 default_level;
119119
120pub const ScopeLevel = struct {
121 scope: @Type(.EnumLiteral),
122 level: Level,
123};
124
125const scope_levels = if (@hasDecl(root, "scope_levels"))
126 root.scope_levels
127else
128 [0]ScopeLevel{};
129
120130fn log(
121131 comptime message_level: Level,
122132 comptime scope: @Type(.EnumLiteral),
123133 comptime format: []const u8,
124134 args: anytype,
125135) void {
126 if (@enumToInt(message_level) <= @enumToInt(level)) {
136 const effective_log_level = blk: {
137 inline for (scope_levels) |scope_level| {
138 if (scope_level.scope == scope) break :blk scope_level.level;
139 }
140 break :blk level;
141 };
142
143 if (@enumToInt(message_level) <= @enumToInt(effective_log_level)) {
127144 if (@hasDecl(root, "log")) {
128145 root.log(message_level, scope, format, args);
129146 } else if (std.Target.current.os.tag == .freestanding) {
test/compare_output.zig+83
......@@ -516,4 +516,87 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
516516
517517 break :x tc;
518518 });
519
520 // It is required to override the log function in order to print to stdout instead of stderr
521 cases.add("std.log per scope log level override",
522 \\const std = @import("std");
523 \\
524 \\pub const log_level: std.log.Level = .debug;
525 \\
526 \\pub const scope_levels = [_]std.log.ScopeLevel{
527 \\ .{ .scope = .a, .level = .alert },
528 \\ .{ .scope = .c, .level = .emerg },
529 \\};
530 \\
531 \\const loga = std.log.scoped(.a);
532 \\const logb = std.log.scoped(.b);
533 \\const logc = std.log.scoped(.c);
534 \\
535 \\pub fn main() !void {
536 \\ loga.debug("", .{});
537 \\ logb.debug("", .{});
538 \\ logc.debug("", .{});
539 \\
540 \\ loga.info("", .{});
541 \\ logb.info("", .{});
542 \\ logc.info("", .{});
543 \\
544 \\ loga.notice("", .{});
545 \\ logb.notice("", .{});
546 \\ logc.notice("", .{});
547 \\
548 \\ loga.warn("", .{});
549 \\ logb.warn("", .{});
550 \\ logc.warn("", .{});
551 \\
552 \\ loga.err("", .{});
553 \\ logb.err("", .{});
554 \\ logc.err("", .{});
555 \\
556 \\ loga.crit("", .{});
557 \\ logb.crit("", .{});
558 \\ logc.crit("", .{});
559 \\
560 \\ loga.alert("", .{});
561 \\ logb.alert("", .{});
562 \\ logc.alert("", .{});
563 \\
564 \\ loga.emerg("", .{});
565 \\ logb.emerg("", .{});
566 \\ logc.emerg("", .{});
567 \\}
568 \\pub fn log(
569 \\ comptime level: std.log.Level,
570 \\ comptime scope: @TypeOf(.EnumLiteral),
571 \\ comptime format: []const u8,
572 \\ args: anytype,
573 \\) void {
574 \\ const level_txt = switch (level) {
575 \\ .emerg => "emergency",
576 \\ .alert => "alert",
577 \\ .crit => "critical",
578 \\ .err => "error",
579 \\ .warn => "warning",
580 \\ .notice => "notice",
581 \\ .info => "info",
582 \\ .debug => "debug",
583 \\ };
584 \\ const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
585 \\ const stdout = std.io.getStdOut().writer();
586 \\ nosuspend stdout.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
587 \\}
588 ,
589 \\debug(b):
590 \\info(b):
591 \\notice(b):
592 \\warning(b):
593 \\error(b):
594 \\critical(b):
595 \\alert(a):
596 \\alert(b):
597 \\emergency(a):
598 \\emergency(b):
599 \\emergency(c):
600 \\
601 );
519602}