Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Execution::Logger Class Referencefinal

A simple/portable wrapper on syslog/log4j/WindowsEventlog, with features like throttling, de-duping, varargs, etc. More...

#include <Logger.h>

Classes

struct  Activator
 

Public Types

enum class  Priority : uint8_t
 

Public Member Functions

nonvirtual Traversal::Iterable< shared_ptr< IAppenderRep > > GetAppenders () const
 
nonvirtual void SetAppenders (const shared_ptr< IAppenderRep > &rep)
 
nonvirtual void AddAppender (const shared_ptr< IAppenderRep > &rep)
 
nonvirtual Priority GetMinLogLevel () const
 
nonvirtual void SetMinLogLevel (Priority minLogLevel)
 
nonvirtual bool WouldLog (Priority logLevel) const
 
nonvirtual bool GetBufferingEnabled () const
 
nonvirtual void SetBufferingEnabled (bool logBufferingEnabled)
 
nonvirtual void Flush ()
 
nonvirtual optional< Time::DurationGetSuppressDuplicates () const
 
nonvirtual void SetSuppressDuplicates (const optional< Time::Duration > &suppressDuplicatesThreshold)
 
void Log (Priority logLevel, const wchar_t *format,...)
 

Static Public Attributes

static Logger sThe
 

Detailed Description

A simple/portable wrapper on syslog/log4j/WindowsEventlog, with features like throttling, de-duping, varargs, etc.

OVERVIEW: The point of the Logging Module is to provide a simple, portable wrapper on end-user-targetted application logging. This form of logging is the kind of logging you leave builtin to your application, and write focused on end-user readability. It is NOT (primarily) for debugging (for that - use the Stroika::Foundation::Debug::Trace module).

The Logger is a singleton object. It can be set at any number of application logging

levels. And it will write information to the backend logger its setup with. But default - this is none.

To use the logger and actually get logging - pick a logger rep, and call

SetAppender ();

Note
It is legal to have no appender, in which case logging is silently suppressed.
This logging API CANNOT be used before main () has started, or after main () has completed
(because this requires a call to setup a logger).
Future Note Some future version MIGHT handle this through some static Common mechanism, which might then allow this (such as environment variables, linked variables etc).
Thread-Safety Internally-Synchronized-Thread-Safety
Example Usage
// Usually near the top of 'main()'
Logger::Activator loggerActivation{Logger::Options{
.fLogBufferingEnabled = true,
.fSuppressDuplicatesThreshold = 15s,
}};
if (dockerContainerFlag) {
Logger::sThe.AddAppender (make_shared<Logger::StreamAppender> (FileOutputStream::New (STDOUT_FILENO, AdoptFDPolicy::eDisconnectOnDestruction)));
}
else {
#if qStroika_HasComponent_syslog
Logger::sThe.AddAppender (make_shared<Logger::SysLogAppender> ("Stroika-Sample-Service"sv));
#elif qStroika_Foundation_Common_Platform_Windows
Logger::sThe.AddAppender (make_shared<Logger::WindowsEventLogAppender> ("Stroika-Sample-Service"sv));
#endif
}
nonvirtual void AddAppender(const shared_ptr< IAppenderRep > &rep)
Definition Logger.cpp:250
Example Usage
Logger::sThe.Log (Logger::eError, "Failed to correct something important in file {}"_f, fileName);
void Log(Priority logLevel, const wchar_t *format,...)
Definition Logger.inl:27
See also
DbgTrace
Note
Thread-Safety Internally-Synchronized-Thread-Safety

Definition at line 94 of file Logger.h.

Member Enumeration Documentation

◆ Priority

Names are based on syslog from http://unix.superglobalmegacorp.com/Net2/newsrc/sys/syslog.h.html But the NUMBERS do NOT correspond!

Lower numbers are less interesting (debug) and higher numbers more important (higher priority).

Note
Common::DefaultNames<> supported

Definition at line 188 of file Logger.h.

Member Function Documentation

◆ GetAppenders()

auto Logger::GetAppenders ( ) const

Note - all Stroika provided appenders are internally synchronized.

Definition at line 233 of file Logger.cpp.

◆ SetAppenders()

void Logger::SetAppenders ( const shared_ptr< IAppenderRep > &  rep)

Note - all Stroika provided appenders are internally synchronized.

However, user-defined appenders are assumed internally synchronized (threadsafe).

Note
require all appenders != nullptr, but if a single rep given, that can be nullptr (and interpreted as removing all).

Definition at line 239 of file Logger.cpp.

◆ AddAppender()

void Logger::AddAppender ( const shared_ptr< IAppenderRep > &  rep)

As if calls GetAppenders/SetAppenders

Definition at line 250 of file Logger.cpp.

◆ GetMinLogLevel()

Logger::Priority Stroika::Foundation::Execution::Logger::GetMinLogLevel ( ) const

This defaults to eInfo. Messages of lower priority (e.g. eDebug) will not be logged to the underlying log system.

This is done inline, so in principle, the compiler may eliminate the calls.

The MIN is min inclusive.

Definition at line 14 of file Logger.inl.

◆ SetMinLogLevel()

void Stroika::Foundation::Execution::Logger::SetMinLogLevel ( Priority  minLogLevel)
See also
GetMinLogLevel

Definition at line 18 of file Logger.inl.

◆ WouldLog()

bool Stroika::Foundation::Execution::Logger::WouldLog ( Priority  logLevel) const
See also
GetMinLogLevel This determines if a call to Log() with this argument log-level would write anything.

Definition at line 22 of file Logger.inl.

◆ GetBufferingEnabled()

bool Logger::GetBufferingEnabled ( ) const
Log buffering is DISABLED by default, since it has some cost. But if enabled, Log () calls

queue an internal message, which another thread wakes up to write. This CAN be critical for performance reasons, so the caller can freely log things, and not have their thread blocked.

Beware, this feature CAN mean that something you log, wont make it out of the application if

the application terminates before the log can be flushed.

Example Usage
Log ("QUITTING");
_exit (0);

probably won't get logged. To avoid this issue, call myLogger.Shutdown () (

See also
ShutdownSingleton) before quitting, or call Flush ();

In one application (open-embedded arm linux) I saw a 3ms latency before I added this (2014-05-30).

Definition at line 309 of file Logger.cpp.

◆ SetBufferingEnabled()

void Logger::SetBufferingEnabled ( bool  logBufferingEnabled)
See also
GetBufferingEnabled ()

Definition at line 292 of file Logger.cpp.

◆ Flush()

void Logger::Flush ( )
@see GetBufferingEnabled ()

This has no effect if the buffer is empty or buffering is disabled.

Definition at line 302 of file Logger.cpp.

◆ GetSuppressDuplicates()

optional< Time::Duration > Logger::GetSuppressDuplicates ( ) const

If GetSuppressDuplicates ().has_value (), then a sequence of N (N > 1) identical messages will be replaced with two messages, the second of which appears with the added label [N-2 suppressed].

The duration is the window of time after the last message we wait before emitting the last message. A good default for this might be 5 or 10 seconds.

Definition at line 315 of file Logger.cpp.

◆ SetSuppressDuplicates()

void Logger::SetSuppressDuplicates ( const optional< Time::Duration > &  suppressDuplicatesThreshold)
@see GetSuppressDuplicates ()
@see Options::fSuppressDuplicatesThreshold
Example Usage
Logger::sThe.SetSuppressDuplicates (nullopt); // disable the feature
Logger::sThe.SetSuppressDuplicates ("PT5M"_duration); // anything within 5 minutes suppress
nonvirtual void SetSuppressDuplicates(const optional< Time::Duration > &suppressDuplicatesThreshold)
Definition Logger.cpp:321

Definition at line 321 of file Logger.cpp.

◆ Log()

void Stroika::Foundation::Execution::Logger::Log ( Priority  logLevel,
const wchar_t *  format,
  ... 
)

Log

Design Note: The 'format' parameter must be defined a String (or const wchar_t*), but not const String&, because:

18.10 Other runtime support [support.runtime] ... 3 The restrictions that ISO C places on the second parameter to the va_start() macro in header <stdarg.h> are different in this International Standard. The parameter parmN is the identifier of the rightmost parameter in the variable parameter list of the function definition (the one just before the ...). If the parameter parmN is declared with a function, array, or reference type, or with a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined.

Example Usage
Logger::sThe.Log (Logger::eError, "Failed to correct something important in file {}"_f, fileName);

Definition at line 27 of file Logger.inl.

Member Data Documentation

◆ sThe

Logger Stroika::Foundation::Execution::Logger::sThe
static
Note
- Callers who use this must arrange for Logger::Activator to be created first (and destroyed after) uses.

Definition at line 119 of file Logger.h.


The documentation for this class was generated from the following files: