authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2021-06-24 04:11:28-06:00
committergravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2021-06-24 04:11:28-06:00
log642f5df0abbcfda47df94ba657b24a913d6903d4
treef650c7aef0f394885d5c1580a7bf262f37ecc807
parent31c49ad64ded02b9dde57f5d3ef102a771fa5cf7

Expose default std.log implementation

This allows root.log implementations to capture log messages, process them, and forward them to the default implementation if desired.

1 files changed, 32 insertions(+), 19 deletions(-)

lib/std/log.zig+32-19
...@@ -145,30 +145,43 @@ fn log(...@@ -145,30 +145,43 @@ fn log(
145 if (@typeInfo(@TypeOf(root.log)) != .Fn)145 if (@typeInfo(@TypeOf(root.log)) != .Fn)
146 @compileError("Expected root.log to be a function");146 @compileError("Expected root.log to be a function");
147 root.log(message_level, scope, format, args);147 root.log(message_level, scope, format, args);
148 } else if (std.Target.current.os.tag == .freestanding) {
149 // On freestanding one must provide a log function; we do not have
150 // any I/O configured.
151 return;
152 } else {148 } else {
153 const level_txt = switch (message_level) {149 defaultLog(message_level, scope, format, args);
154 .emerg => "emergency",
155 .alert => "alert",
156 .crit => "critical",
157 .err => "error",
158 .warn => "warning",
159 .notice => "notice",
160 .info => "info",
161 .debug => "debug",
162 };
163 const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
164 const stderr = std.io.getStdErr().writer();
165 const held = std.debug.getStderrMutex().acquire();
166 defer held.release();
167 nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
168 }150 }
169 }151 }
170}152}
171153
154/// The default implementation for root.log. root.log may forward log messages
155/// to this function.
156pub fn defaultLog(
157 comptime message_level: Level,
158 comptime scope: @Type(.EnumLiteral),
159 comptime format: []const u8,
160 args: anytype,
161) void {
162 if (std.Target.current.os.tag == .freestanding) {
163 // On freestanding one must provide a log function; we do not have
164 // any I/O configured.
165 return;
166 }
167
168 const level_txt = switch (message_level) {
169 .emerg => "emergency",
170 .alert => "alert",
171 .crit => "critical",
172 .err => "error",
173 .warn => "warning",
174 .notice => "notice",
175 .info => "info",
176 .debug => "debug",
177 };
178 const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
179 const stderr = std.io.getStdErr().writer();
180 const held = std.debug.getStderrMutex().acquire();
181 defer held.release();
182 nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
183}
184
172/// Returns a scoped logging namespace that logs all messages using the scope185/// Returns a scoped logging namespace that logs all messages using the scope
173/// provided here.186/// provided here.
174pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {187pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {