From 7db2c11537552250462a5f4ab162e5ef4183489c Mon Sep 17 00:00:00 2001 From: heidezomp Date: Wed, 12 Aug 2020 14:03:02 +0200 Subject: [PATCH 1/3] std.log: add scoped logging struct * Add a std.log.scoped function that returns a scoped logging struct * Add a std.log.default struct that logs using the .default scope Implementation of daurnimator's proposal: https://github.com/ziglang/zig/issues/5943#issuecomment-669043489 Note that I named the function "scoped" instead of "scope" so as not to clash with the scope parameter that is used everywhere; this seemed a better solution to me than renaming the scope parameter to "s" or "log_scope" or the like. --- lib/std/log.zig | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/lib/std/log.zig b/lib/std/log.zig index d8bcba38cc..d511773654 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -200,3 +200,87 @@ pub fn debug( ) void { log(.debug, scope, format, args); } + +pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { + return struct { + /// Log an emergency message to stderr. This log level is intended to be used + /// for conditions that cannot be handled and is usually followed by a panic. + pub fn emerg( + comptime format: []const u8, + args: anytype, + ) void { + @setCold(true); + log(.emerg, scope, format, args); + } + + /// Log an alert message to stderr. This log level is intended to be used for + /// conditions that should be corrected immediately (e.g. database corruption). + pub fn alert( + comptime format: []const u8, + args: anytype, + ) void { + @setCold(true); + log(.alert, scope, format, args); + } + + /// Log a critical message to stderr. This log level is intended to be used + /// when a bug has been detected or something has gone wrong and it will have + /// an effect on the operation of the program. + pub fn crit( + comptime format: []const u8, + args: anytype, + ) void { + @setCold(true); + log(.crit, scope, format, args); + } + + /// Log an error message to stderr. This log level is intended to be used when + /// a bug has been detected or something has gone wrong but it is recoverable. + pub fn err( + comptime format: []const u8, + args: anytype, + ) void { + @setCold(true); + log(.err, scope, format, args); + } + + /// Log a warning message to stderr. This log level is intended to be used if + /// it is uncertain whether something has gone wrong or not, but the + /// circumstances would be worth investigating. + pub fn warn( + comptime format: []const u8, + args: anytype, + ) void { + log(.warn, scope, format, args); + } + + /// Log a notice message to stderr. This log level is intended to be used for + /// non-error but significant conditions. + pub fn notice( + comptime format: []const u8, + args: anytype, + ) void { + log(.notice, scope, format, args); + } + + /// Log an info message to stderr. This log level is intended to be used for + /// general messages about the state of the program. + pub fn info( + comptime format: []const u8, + args: anytype, + ) void { + log(.info, scope, format, args); + } + + /// Log a debug message to stderr. This log level is intended to be used for + /// messages which are only useful for debugging. + pub fn debug( + comptime format: []const u8, + args: anytype, + ) void { + log(.debug, scope, format, args); + } + }; +} + +pub const default = scoped(.default); From 25607079f0f405d09202378d7435a59a7a96d649 Mon Sep 17 00:00:00 2001 From: heidezomp Date: Wed, 12 Aug 2020 15:37:56 +0200 Subject: [PATCH 2/3] std.log: add documentation for scoped logging * Add short documentation to std.log.scoped and std.log.default * Update the module documentation and example to explain the difference between using explicit scopes, using a scoped logging namespace, and using the default namespace --- lib/std/log.zig | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/std/log.zig b/lib/std/log.zig index d511773654..8411293867 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -2,12 +2,16 @@ const std = @import("std.zig"); const builtin = std.builtin; const root = @import("root"); -//! std.log is standardized interface for logging which allows for the logging +//! std.log is a standardized interface for logging which allows for the logging //! of programs and libraries using this interface to be formatted and filtered //! by the implementer of the root.log function. //! //! The scope parameter should be used to give context to the logging. For //! example, a library called 'libfoo' might use .libfoo as its scope. +//! This parameter can either be passed explicitly to the logging functions +//! provided here, or a scoped logging namespace can be created +//! using the `log.scoped` function. If logging scopes are not relevant for +//! your use case, the `log.default` scope namespace can be used. //! //! An example root.log might look something like this: //! @@ -44,16 +48,26 @@ const root = @import("root"); //! } //! //! pub fn main() void { +//! // Using explicit scopes: //! // Won't be printed as log_level is .warn //! std.log.info(.my_project, "Starting up.", .{}); //! std.log.err(.nice_library, "Something went very wrong, sorry.", .{}); //! // Won't be printed as it gets filtered out by our log function //! std.log.err(.lib_that_logs_too_much, "Added 1 + 1", .{}); +//! +//! // Using a scoped logging namespace: +//! const scoped_log = std.log.scoped(.my_project); +//! scoped_log.alert("The scope for this message is implicitly .my_project", .{}); +//! +//! // Using the default namespace: +//! // Won't be printed as log_level is .warn +//! std.log.default.info("I don't care about my namespace", .{}); //! } //! ``` //! Which produces the following output: //! ``` //! [err] (nice_library): Something went very wrong, sorry. +//! [alert] (my_project): The scope for this message is implicitly .my_project //! ``` pub const Level = enum { @@ -201,6 +215,8 @@ pub fn debug( log(.debug, scope, format, args); } +/// Returns a scoped logging namespace that logs all messages using the scope +/// provided here. pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { return struct { /// Log an emergency message to stderr. This log level is intended to be used @@ -283,4 +299,5 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { }; } +/// The default scoped logging namespace. pub const default = scoped(.default); From bf2ed0f571736241151a358b2533d45cb769db68 Mon Sep 17 00:00:00 2001 From: heidezomp Date: Wed, 12 Aug 2020 15:54:21 +0200 Subject: [PATCH 3/3] std.log: don't state in docs that messages are logged to stderr Since the logger implementation can be overridden, the messages might not be logged to stderr at all. --- lib/std/log.zig | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/std/log.zig b/lib/std/log.zig index 8411293867..9a0dcecc05 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -129,7 +129,7 @@ fn log( } } -/// Log an emergency message to stderr. This log level is intended to be used +/// Log an emergency message. This log level is intended to be used /// for conditions that cannot be handled and is usually followed by a panic. pub fn emerg( comptime scope: @Type(.EnumLiteral), @@ -140,7 +140,7 @@ pub fn emerg( log(.emerg, scope, format, args); } -/// Log an alert message to stderr. This log level is intended to be used for +/// Log an alert message. This log level is intended to be used for /// conditions that should be corrected immediately (e.g. database corruption). pub fn alert( comptime scope: @Type(.EnumLiteral), @@ -151,7 +151,7 @@ pub fn alert( log(.alert, scope, format, args); } -/// Log a critical message to stderr. This log level is intended to be used +/// Log a critical message. This log level is intended to be used /// when a bug has been detected or something has gone wrong and it will have /// an effect on the operation of the program. pub fn crit( @@ -163,7 +163,7 @@ pub fn crit( log(.crit, scope, format, args); } -/// Log an error message to stderr. This log level is intended to be used when +/// Log an error message. This log level is intended to be used when /// a bug has been detected or something has gone wrong but it is recoverable. pub fn err( comptime scope: @Type(.EnumLiteral), @@ -174,7 +174,7 @@ pub fn err( log(.err, scope, format, args); } -/// Log a warning message to stderr. This log level is intended to be used if +/// Log a warning message. This log level is intended to be used if /// it is uncertain whether something has gone wrong or not, but the /// circumstances would be worth investigating. pub fn warn( @@ -185,7 +185,7 @@ pub fn warn( log(.warn, scope, format, args); } -/// Log a notice message to stderr. This log level is intended to be used for +/// Log a notice message. This log level is intended to be used for /// non-error but significant conditions. pub fn notice( comptime scope: @Type(.EnumLiteral), @@ -195,7 +195,7 @@ pub fn notice( log(.notice, scope, format, args); } -/// Log an info message to stderr. This log level is intended to be used for +/// Log an info message. This log level is intended to be used for /// general messages about the state of the program. pub fn info( comptime scope: @Type(.EnumLiteral), @@ -205,7 +205,7 @@ pub fn info( log(.info, scope, format, args); } -/// Log a debug message to stderr. This log level is intended to be used for +/// Log a debug message. This log level is intended to be used for /// messages which are only useful for debugging. pub fn debug( comptime scope: @Type(.EnumLiteral), @@ -219,7 +219,7 @@ pub fn debug( /// provided here. pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { return struct { - /// Log an emergency message to stderr. This log level is intended to be used + /// Log an emergency message. This log level is intended to be used /// for conditions that cannot be handled and is usually followed by a panic. pub fn emerg( comptime format: []const u8, @@ -229,7 +229,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.emerg, scope, format, args); } - /// Log an alert message to stderr. This log level is intended to be used for + /// Log an alert message. This log level is intended to be used for /// conditions that should be corrected immediately (e.g. database corruption). pub fn alert( comptime format: []const u8, @@ -239,7 +239,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.alert, scope, format, args); } - /// Log a critical message to stderr. This log level is intended to be used + /// Log a critical message. This log level is intended to be used /// when a bug has been detected or something has gone wrong and it will have /// an effect on the operation of the program. pub fn crit( @@ -250,7 +250,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.crit, scope, format, args); } - /// Log an error message to stderr. This log level is intended to be used when + /// Log an error message. This log level is intended to be used when /// a bug has been detected or something has gone wrong but it is recoverable. pub fn err( comptime format: []const u8, @@ -260,7 +260,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.err, scope, format, args); } - /// Log a warning message to stderr. This log level is intended to be used if + /// Log a warning message. This log level is intended to be used if /// it is uncertain whether something has gone wrong or not, but the /// circumstances would be worth investigating. pub fn warn( @@ -270,7 +270,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.warn, scope, format, args); } - /// Log a notice message to stderr. This log level is intended to be used for + /// Log a notice message. This log level is intended to be used for /// non-error but significant conditions. pub fn notice( comptime format: []const u8, @@ -279,7 +279,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.notice, scope, format, args); } - /// Log an info message to stderr. This log level is intended to be used for + /// Log an info message. This log level is intended to be used for /// general messages about the state of the program. pub fn info( comptime format: []const u8, @@ -288,7 +288,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { log(.info, scope, format, args); } - /// Log a debug message to stderr. This log level is intended to be used for + /// Log a debug message. This log level is intended to be used for /// messages which are only useful for debugging. pub fn debug( comptime format: []const u8,