ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
alox.cpp
1// #################################################################################################
2// alib::lox - ALox Logging Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14// ====================================== Global Fragment ======================================
19
20// =========================================== Module ==========================================
21#if ALIB_C20_MODULES
22 module ALib.ALox;
23 import ALib.Lang;
25 import ALib.Monomem;
26 import ALib.Boxing;
27 import ALib.EnumRecords;
28 import ALib.Strings;
30 import ALib.Variables;
31 import ALib.Camp;
32 import ALib.Camp.Base;
33 import ALib.ALox.Impl;
34#else
35# include "ALib.Lang.H"
36# include "ALib.Containers.List.H"
37# include "ALib.Monomem.H"
38# include "ALib.Boxing.H"
40# include "ALib.Variables.H"
41# include "ALib.Camp.H"
42# include "ALib.Camp.Base.H"
43# include "ALib.ALox.H"
44# include "ALib.ALox.Impl.H"
45#endif
46// ====================================== Implementation =======================================
47#if !DOXYGEN
48namespace alib::lox::detail {
51 return loxes.size();
52}
53void shutdownLoxes() {
54 while ( loxes.IsNotEmpty() )
55 loxes.back()->~Lox();
56 loxes.Reset();
57}
58
59}
60#endif
61
62namespace alib::lox {
63
65
66// #################################################################################################
67// Lox management
68// #################################################################################################
69#if !DOXYGEN
70
71#if ALOX_DBG_LOG
72 Lox* DEBUG_LOX = nullptr; // will be created in ALoxCamp::Bootstrap
73#endif
74
75#endif
76
77
78// The lox singletons for debug and release logging
80{
82
83 // search
84 for( auto* it : detail::loxes )
85 if( it->GetName().Equals<CHK, lang::Case::Ignore>( name ) )
86 return it;
87
88
89 // create?
90 if ( create == lang::CreateIfNotExists::Yes )
91 {
92 Lox* newLox= new Lox ( name, false );
93 detail::loxes.emplace_back( newLox );
94 return newLox;
95 }
96
97 // not found
98 return nullptr;
99}
100
102{
104
105 // check
106 if ( lox == nullptr )
107 {
108 ALIB_ERROR( "ALOX", "Nullptr given" )
109 return;
110 }
111
112 // remove
113 if( operation == lang::ContainerOp::Remove )
114 {
115 for( auto search= detail::loxes.begin() ; search != detail::loxes.end() ; ++search )
116 if ( *search == lox )
117 {
118 (void) detail::loxes.erase( search );
119 return;
120 }
121 ALIB_WARNING( "ALOX", "Given lox named \"{}\" could not be found for removal.",
122 lox != nullptr ? lox->GetName() : "<null>" )
123 }
124
125 // insert
126 else
127 {
128 for( auto* it : detail::loxes )
129 if( it->GetName().Equals<NC>( lox->GetName() ) )
130 {
131 ALIB_ERROR( "ALOX", "Given lox named \"{}\" was already registered. "
132 "Registration ignored.", lox->GetName() )
133 return;
134 }
135 detail::loxes.emplace_back( lox );
136 }
137}
138
139
140Lox::Lox(const NString& name, bool doRegister )
141{
143
144 if( doRegister )
146}
147
155
156
157// #################################################################################################
158// Static methods of Lox
159// #################################################################################################
161{
162 //--- check configuration setting "CONSOLE_TYPE" ---
164 if(variable.Define())
165 variable= String( A_CHAR("Default") );
166
167 Substring val = variable;
168 val.Trim();
169 if( val.IsEmpty() ||
170 val.Equals<NC, lang::Case::Ignore>( A_CHAR("Default") ) ) goto DEFAULT;
171
172 if( val.Equals<NC, lang::Case::Ignore>( A_CHAR("Plain") ) ) return new ConsoleLogger ( name );
173 if( val.Equals<NC, lang::Case::Ignore>( A_CHAR("Ansi") ) ) return new AnsiConsoleLogger( name );
174
175 if( val.Equals<NC, lang::Case::Ignore>( A_CHAR("Windows") ) )
176 #if defined( _WIN32 )
177 return new WindowsConsoleLogger( name );
178 #else
179 goto DEFAULT;
180 #endif
181 ALIB_WARNING( "ALOX", "Unrecognized value in config variable \"{}\" = \"{}\".",
182 variable, variable.GetString() )
183
184 DEFAULT:
185 if( variable.Define(variables::Priority::Standard) )
186 variable.GetString().Reset(A_CHAR("Default"));
187
188 #if defined( _WIN32 )
189 // if there is no console window we do not do colors
190 if ( !BASECAMP.HasConsoleWindow )
191 return new ConsoleLogger( name );
192 else
193 return new WindowsConsoleLogger( name );
194 #else
195 return new AnsiConsoleLogger( name );
196 #endif
197}
198
199
200#if ALOX_DBG_LOG
201// #################################################################################################
202// Auto detection of DEBUG environment
203// #################################################################################################
205TextLogger* Log::IDELogger = nullptr;
206
208{
209 static bool recursion= false;
210 if( recursion )
211 return;
212 recursion= true;
213
214 // block recursion caused by log operations in this code
215 if ( DebugLogger != nullptr )
216 {
217 ALIB_WARNING( "ALOX", "Log::AddDebugLogger(): called twice." )
218 recursion= false;
219 return;
220 }
221 DebugLogger= reinterpret_cast<decltype(DebugLogger)>(-1);
222
223 // add a VStudio logger if this is a VStudio debug session
224 #if defined(_MSC_VER) && ALIB_DEBUG
225 if( BASECAMP.IsDebuggerPresent() )
226 {
227 Variable variable= variables::CampVariable( ALOX, Variables::NO_IDE_LOGGER );
228 bool createIDELogger= variable.IsNotDefined() || (variable.GetBool() == false);
229
230 if(createIDELogger)
231 {
232 IDELogger= new VStudioLogger("IDE_LOGGER");
233
234 // add logger
235 lox->SetVerbosity( IDELogger, Verbosity::Verbose, "/" );
236 lox->SetVerbosity( IDELogger, Verbosity::Warning, Lox::InternalDomains );
237 }
238 }
239 #endif
240
241 // add a default console logger
242 DebugLogger= Lox::CreateConsoleLogger("DEBUG_LOGGER");
243
244 // add logger by setting verbosities
245 lox->SetVerbosity( DebugLogger, Verbosity::Verbose );
246 lox->SetVerbosity( DebugLogger, Verbosity::Warning, Lox::InternalDomains );
247
248 // check various variables, if existed already externally. If not, create them empty or
249 // with debug defaults (only done here, namely for debug logger)
250 {ALIB_LOCK_WITH(ALOX.GetConfig())
251 // Verbosity: If not, set 'ExportAll' flag
252 Variable variable= variables::CampVariable( ALOX );
253 Box replacements[2]= { "LOG", "DEBUG_LOGGER" };
254 variable.Declare( Variables::VERBOSITY, replacements );
255 if( variable.IsNotDefined() )
256 {
257 (void) variable.Define();
258 variable.Get<CVVerbosities>().ExportAll= true;
259 }
260
261 variable.Declare( Variables::SPTR_LOX , "LOG" ); (void) variable.Define();
262 variable.Declare( Variables::DOMAIN_SUBSTITUTION, "LOG" ); (void) variable.Define();
263 variable.Declare( Variables::PREFIXES , "LOG" ); (void) variable.Define();
264 variable.Declare( Variables::DUMP_STATE_ON_EXIT , "LOG" ); (void) variable.Define();
265 if( dynamic_cast<AnsiConsoleLogger*>(DebugLogger) != nullptr )
266 variable.Declare( Variables::CONSOLE_LIGHT_COLORS ); (void) variable.Define();
267 }
268
269 // set ALib's assertion plugin with one that uses ALox
270 SetALibAssertionPlugin( lox );
271
272 recursion= false;
273}
274
276{
277 // remove ALox specific assertion plugin of ALib
278 SetALibAssertionPlugin( nullptr );
279
280 // remove debug logger(s)
281 ALIB_ASSERT_WARNING( DebugLogger != nullptr, "ALOX",
282 "Log::RemoveDebugLogger(): no debug logger to remove." )
283
284 if ( DebugLogger != nullptr )
285 {
286 lox->RemoveLogger( DebugLogger );
287
288 delete DebugLogger;
289 DebugLogger= nullptr;
290 }
291
292 #if defined(_WIN32) && ALIB_DEBUG
293 if ( IDELogger != nullptr )
294 {
295 lox->RemoveLogger( IDELogger );
296
297 delete IDELogger;
298 IDELogger= nullptr;
299 }
300 #endif
301}
302#endif // ALOX_DBG_LOG
303
304
305// #################################################################################################
306// ALoxAssertionPlugin
307// #################################################################################################
308#if ALIB_DEBUG
309
310//==================================================================================================
311/// This function will be set to global pointer \alib{assert::PLUGIN} when calling
312/// method \alib{lox;Log::AddDebugLogger}.<br>
313/// If no debug-logging is used, or method \b AddDebugLogger is not used, then
314/// this function can also be used with a different \b Lox and explicitly activated using
315/// the static method \alib{lox;Log::SetALibAssertionPlugin}.
316/// Uses internal domain <b>"/ALIB"</b> for logging, respectively to what the global variable
317/// \ref ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX is set.
318/// @param ci Information about the scope of invocation.
319/// @param type The type of the message. As a convention, \c 0 is an assertion, \c 1 is a
320/// warning, \c 2 is an info message, \c 3 or above are a verbose messages.
321/// @param domain The domain of the assertion, warning, or message.
322/// Will be appended to the \alox domain.
323/// @param msg The assembled message to print.
324//==================================================================================================
326 int type,
327 std::string_view domain,
328 std::string_view msg );
329
330std::string_view const ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX = "/ALIB";
331
332#if !DOXYGEN
333namespace { Lox* assertionLox= nullptr; }
334#endif
335
337
338 // remove plugin
339 if ( pLox == nullptr )
340 {
341 if ( assertionLox == nullptr )
342 return;
343
344 assertionLox->Acquire( ALIB_CALLER );
345 assertionLox->GetLogableContainer().Add( "ALoxAssertionPlugin removed "
346 "from Lox {!Q}", assertionLox->GetName() );
347 assertionLox->Entry( ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX, Verbosity::Verbose );
348 assertionLox->Release ();
349 assertionLox = nullptr;
350 assert::PLUGIN= nullptr;
351 return;
352 }
353
354 // add plugin
355 assertionLox = pLox;
357 assertionLox->Acquire( ALIB_CALLER );
358 assertionLox->GetLogableContainer().Add( "ALoxAssertionPlugin set to Lox {!Q}.", pLox->GetName() );
359 assertionLox->Entry( ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX, Verbosity::Verbose );
360
361 // we set the verbosity only now. This should
362 // - allow to have the above verbose message seen once
363 // - in case the values become externalized, this setting is written to such external
364 // configuration file and thus is not displayed a second time.
365 assertionLox->SetVerbosity( DebugLogger, Verbosity::Warning, ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX );
366 assertionLox->Release ();
367}
368
370 int type,
371 std::string_view domain,
372 std::string_view msg )
373{
374 assertionLox->Acquire( ci );
375
376 auto& logables= assertionLox->GetLogableContainer();
377 logables.Add( msg );
378
379 auto verbosity= type == 0 ? Verbosity::Error :
380 type == 1 ? Verbosity::Warning :
381 type == 2 ? Verbosity::Info :
382 Verbosity::Verbose ;
383
384 NString256 dom(ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX); dom << '/' << domain;
385
386 assertionLox->Entry( dom, verbosity );
387 assertionLox->Release ();
388}
389
390
391#endif //ALIB_DEBUG
392
393# include "ALib.Lang.CIMethods.H"
394}// namespace [alib::lox]
395
static ALIB_DLL textlogger::TextLogger * DebugLogger
The debug logger created by AddDebugLogger.
Definition log.inl:40
static ALIB_DLL void RemoveDebugLogger(Lox *lox)
Definition alox.cpp:275
static ALIB_DLL void AddDebugLogger(Lox *lox)
Definition alox.cpp:207
static ALIB_DLL void SetALibAssertionPlugin(Lox *lox)
Definition alox.cpp:336
static ALIB_DLL textlogger::TextLogger * IDELogger
An (additional) IDE specific logger, that might be created by AddDebugLogger.
Definition log.inl:43
This class acts as a container for Loggers and provides a convenient interface to logging.
Definition lox.inl:15
ALIB_DLL ~Lox()
Destructs a lox.
Definition alox.cpp:148
ALIB_DLL Lox(const NString &name, bool doRegister=true)
Definition alox.cpp:140
detail::LoxImpl * impl
The implementation.
Definition lox.inl:23
static ALIB_DLL textlogger::TextLogger * CreateConsoleLogger(const NString &name=nullptr)
Definition alox.cpp:160
static constexpr NString InternalDomains
Definition lox.inl:47
const NString & GetName()
Definition lox.inl:126
static ALIB_DLL void Register(Lox *lox, lang::ContainerOp operation)
Definition alox.cpp:101
static ALIB_DLL Lox * Get(const NString &name, lang::CreateIfNotExists create=lang::CreateIfNotExists::No)
Definition alox.cpp:79
constexpr bool IsEmpty() const
Definition string.inl:367
bool Equals(const TString< TChar > &rhs) const
Definition string.inl:541
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
ALIB_DLL bool Define(Priority requestedPriority=Priority::Standard)
Definition variable.cpp:280
#define ALIB_CALLER
Definition alib.inl:1001
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
Definition alib.inl:1046
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1050
#define ALIB_ERROR(domain,...)
Definition alib.inl:1045
#define ALIB_LOCK_RECURSIVE_WITH(lock)
Definition alib.inl:1323
#define ALIB_LOCK_WITH(lock)
Definition alib.inl:1322
void(* PLUGIN)(const CallerInfo &ci, int type, std::string_view domain, std::string_view msg)
Definition assert.cpp:172
ContainerOp
Denotes standard container operations.
@ Remove
Denotes removals.
@ Insert
Denotes insertions.
CreateIfNotExists
Denotes whether something should be created if it does not exist.
@ Yes
Create if something does not exist.
void shutdownLoxes()
Internal lox management.
integer dbgCountLoxes()
void ALoxAssertionPlugin(const lang::CallerInfo &ci, int type, std::string_view domain, std::string_view msg)
Definition alox.cpp:369
std::string_view const ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX
Definition alox.cpp:330
ALIB_DLL Lox * DEBUG_LOX
@ CONSOLE_LIGHT_COLORS
Denotes configuration variable ALOX/CONSOLE_LIGHT_COLORS used by colorful specializations of class Te...
Definition aloxcamp.inl:67
@ CONSOLE_TYPE
Denotes configuration variable ALOX/CONSOLE_TYPE used by Lox::CreateConsoleLogger.
Definition aloxcamp.inl:25
@ VERBOSITY
Denotes configuration variable ALOX/LOGGERNAME/VERBOSITY_WITH_LOXNAME.
Definition aloxcamp.inl:28
@ DOMAIN_SUBSTITUTION
Denotes configuration variable ALOX/LOXNAME/DOMAIN_SUBSTITUTION used by class Lox.
Definition aloxcamp.inl:37
@ DUMP_STATE_ON_EXIT
Denotes configuration variable ALOX/LOXNAME/DUMP_STATE_ON_EXIT used by class Lox.
Definition aloxcamp.inl:43
@ SPTR_LOX
Denotes configuration variable ALOX/LOXNAME/SOURCE_PATH_TRIM_RULES used by class Lox.
Definition aloxcamp.inl:34
@ PREFIXES
Denotes configuration variable ALOX/LOXNAME/PREFIXES used by class Lox.
Definition aloxcamp.inl:40
ALIB_DLL TMonoAllocator< lang::HeapAllocator > GLOBAL_ALLOCATOR
ALIB_DLL RecursiveLock GLOBAL_ALLOCATOR_LOCK
variables::Variable CampVariable(camp::Camp &camp)
Definition camp.inl:349
variables::Variable Variable
Type alias in namespace alib.
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class Basecamp.
Definition basecamp.cpp:81
lox::loggers::AnsiConsoleLogger AnsiConsoleLogger
Type alias in namespace alib.
lox::loggers::ConsoleLogger ConsoleLogger
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2390
lox::ALoxCamp ALOX
The singleton instance of ALib Camp class ALoxCamp.
Definition aloxcamp.cpp:53
lox::loggers::WindowsConsoleLogger WindowsConsoleLogger
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1216
lox::Lox Lox
Type alias in namespace alib.
Definition lox.inl:1446
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256>.
strings::TSubstring< character > Substring
Type alias in namespace alib.
containers::List< TAllocator, T, TRecycling > List
Type alias in namespace alib.
Definition list.inl:746
lox::textlogger::TextLogger TextLogger
Type alias in namespace alib.
See sibling type NC.
Definition chk_nc.inl:33
static ALIB_DLL void Destruct(LoxImpl *lox)
static ALIB_DLL LoxImpl * Construct(const NString &name)