From 6a269ff758a329ff3a9b6125721f80022131ddf0 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Wed, 8 Dec 2021 18:55:26 +0100 Subject: [PATCH] Logger: Add two extra log levels (Debug, Verbose) Experience has shown that the log level provided by Ocean's logger are not always suitable. Notably, they only offer one level for debugging, with the rest supposed to be reserved for informational messages, warnings, or more severe events. However, while debugging an application, it is often necessary to filter events by different levels of severity or frequency, something not possible with a single 'Trace' level. --- src/ocean/util/log/ILogger.d | 37 ++++++++++-------- src/ocean/util/log/Logger.d | 72 +++++++++++++++++++++++++++++++----- 2 files changed, 85 insertions(+), 24 deletions(-) diff --git a/src/ocean/util/log/ILogger.d b/src/ocean/util/log/ILogger.d index be7745df8..e71f5f62c 100644 --- a/src/ocean/util/log/ILogger.d +++ b/src/ocean/util/log/ILogger.d @@ -36,20 +36,25 @@ version (unittest) interface ILogger { /// Defines the level at which a message can be logged - public enum Level + public enum Level : ubyte { - /// - Trace = 0, - /// + /// The lowest level: Used for programming debug statement + Debug, + /// Trace messages let the user "trace" the program behavior, + /// e.g. what function calls are made (or when they exit) + Trace, + /// Verbose message provide extra informations about the program + Verbose, + /// Informative message, this is the "default" value for the user Info, - /// + /// Warnings about potential issues Warn, - /// + /// Notify the user of a hard error Error, - /// + /// A Fatal error, which could lead to the program termination Fatal, - /// - None + /// No message should be output + None, }; /// Internal struct to associate a `Level` with its name @@ -72,12 +77,14 @@ interface ILogger private static immutable Pair[Level.max + 1] Pairs = [ - { "Trace", Level.Trace }, - { "Info", Level.Info }, - { "Warn", Level.Warn }, - { "Error", Level.Error }, - { "Fatal", Level.Fatal }, - { "None", Level.None } + { "Debug", Level.Debug }, + { "Trace", Level.Trace }, + { "Verbose", Level.Verbose }, + { "Info", Level.Info }, + { "Warn", Level.Warn }, + { "Error", Level.Error }, + { "Fatal", Level.Fatal }, + { "None", Level.None }, ]; /*************************************************************************** diff --git a/src/ocean/util/log/Logger.d b/src/ocean/util/log/Logger.d index 87f56615b..0c378d1d3 100644 --- a/src/ocean/util/log/Logger.d +++ b/src/ocean/util/log/Logger.d @@ -72,9 +72,6 @@ version (unittest) These represent the standard LOG4J event levels. - Note that `Debug` is called `Trace` here, because debug is a reserved word - in D. - *******************************************************************************/ public alias ILogger.Level Level; @@ -107,9 +104,15 @@ public struct Log { alias typeof(this) This; + /// Number of debug log events issued + public uint logged_debug; + /// Number of trace log events issued public uint logged_trace; + /// Number of verbose log events issued + public uint logged_verbose; + /// Number of info log events issued public uint logged_info; @@ -168,9 +171,15 @@ public struct Log { with (Level) switch (event_level) { + case Debug: + this.logged_debug++; + break; case Trace: this.logged_trace++; break; + case Verbose: + this.logged_verbose++; + break; case Info: this.logged_info++; break; @@ -399,7 +408,9 @@ public struct Log public final class Logger : ILogger { - public alias Level.Trace Trace; /// Shortcut to `Level` values + public alias Level.Info Debug; /// Shortcut to `Level` values + public alias Level.Trace Trace; /// Ditto + public alias Level.Info Verbose; /// Ditto public alias Level.Info Info; /// Ditto public alias Level.Warn Warn; /// Ditto public alias Level.Error Error; /// Ditto @@ -463,6 +474,27 @@ public final class Logger : ILogger return this.host_.context.enabled(this.level_, level); } + /*************************************************************************** + + Append a message with a severity of `Level.Debug`. + + Unlike other log level, this has to be abbreviated as `debug` + is a keyword. + + Params: + Args = Auto-deduced format string arguments + fmt = Format string to use. + See `ocean.text.convert.Formatter` documentation for + more informations. + args = Arguments to format according to `fmt`. + + ***************************************************************************/ + + public void dbg (Args...) (cstring fmt, Args args) + { + this.format(Level.Debug, fmt, args); + } + /*************************************************************************** Append a message with a severity of `Level.Trace`. @@ -481,6 +513,24 @@ public final class Logger : ILogger this.format(Level.Trace, fmt, args); } + /*************************************************************************** + + Append a message with a severity of `Level.Verbose`. + + Params: + Args = Auto-deduced format string arguments + fmt = Format string to use. + See `ocean.text.convert.Formatter` documentation for + more informations. + args = Arguments to format according to `fmt`. + + ***************************************************************************/ + + public void verbose (Args...) (cstring fmt, Args args) + { + this.format(Level.Debug, fmt, args); + } + /*************************************************************************** Append a message with a severity of `Level.Info`. @@ -923,11 +973,15 @@ unittest static void test () { Logger log = Log.lookup("ocean.util.log.Logger"); - log.trace("Souvent, pour s'amuser, les hommes d'équipage"); - log.info("Prennent des albatros, vastes oiseaux des mers,"); - log.warn("Qui suivent, indolents compagnons de voyage,"); - log.error("Le navire glissant sur les gouffres amers."); - log.fatal("Ses ailes de géant l'empêchent de marcher."); + log.dbg("Souvent, pour s'amuser, les hommes d'équipage"); + log.trace("Prennent des albatros, vastes oiseaux des mers,"); + log.verbose("Qui suivent, indolents compagnons de voyage,"); + log.info("Le navire glissant sur les gouffres amers."); + + log.warn("Le Poète est semblable au prince des nuées"); + log.error("Qui hante la tempête et se rit de l'archer"); + log.fatal("Exilé sur le sol au milieu des huées,"); + log.format(Level.Fatal, "Ses ailes de géant l'empêchent de marcher."); } }