ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
lox.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_alox of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace lox {
9
10//==================================================================================================
11/// This class acts as a container for \e Loggers and provides a convenient interface to logging.
12//==================================================================================================
13class Lox
14{
15 #if !DOXYGEN
16 friend class ALox;
17 friend struct detail::LI;
18 #endif
19
20 protected:
21 /// The implementation.
22 detail::LoxImpl* impl;
23
24 public:
25 /// This is the path for logging to the internal domain. By manipulating this
26 /// <em>%Log %Domain's %Verbosity</em>, the verbosity of \alox itself can be controlled.
27 /// For example, with \e Verbosity.INFO, the 'on the fly' creation of <em>Log Domains</em>
28 /// are logged, which can be helpful to determine the <em>Lo bg Domains</em> that are
29 /// created by libraries and larger projects.
30 ///
31 /// The following Subdomains are used by \alox:
32 ///
33 /// Subdomain | Description
34 /// - - - - - -| - - - - - - - - - - - - - - - - - - -
35 /// LGR | Used when \e %Loggers are registered, retrieved or removed from a \b %Lox and when the \e Verbosity of a <em>Log Domain</em> for a \e %Logger is changed.<br>In addition used with method \b %Lox::SetStartTime.
36 /// DMN | Used when <em>Log Domains</em> are registered (on first use), when <em>Scope Domains</em> are set or removed and when <em>Domain Substitution Rules</em> are set.
37 /// PFX | Used when <em>Prefix Logables</em> are set or removed.
38 /// THR | Used with method \b %Lox::MapThreadName.
39 /// LGD | Used with storing and retrieving <em>Log Data</em> objects.
40 ///
41 /// \note For internal logging an separated <em>domain tree</em> is used. This means, that
42 /// setting the root domain of a \b %Lox to a certain \e Verbosity does \e not affect
43 /// the internal domains. In other words, the \e Verbosity of the internal domain
44 /// (or one of its Subdomains) has to be set explicitly.
45 ///
46 static constexpr NString InternalDomains { "$/" };
47
48 //################################################################################################
49 // Constructors/destructor
50 //################################################################################################
51 /// Constructs a new, empty Lox with the given \p{name}.
52 /// The name is immutable and all \b %Lox objects registered with \alox must be unique.
53 /// Lower case letters in the name are converted to upper case.
54 /// The name \c "Log" is reserved for the internal default singleton used for debug-logging.
55 /// In addition, name \c "GLOBAL" is not allowed.
56 ///
57 /// If parameter \p{register} is \c true (the default), static method
58 /// \alib{lox,ALoxCamp::Register} is invoked and the object will be
59 /// retrievable with static method
60 /// \alib{lox,ALoxCamp::Get}. In some situations, such 'registration'
61 /// may not be wanted.
62 ///
63 /// @param name The name of the Lox. Will be copied and converted to upper case.
64 /// @param doRegister If \c true, this object is registered with the static class
65 /// \alib{lox,ALoxCamp}.
66 /// Optional and defaults to \c true.
68 Lox(const NString& name, bool doRegister =true );
69
70 /// Destructs a lox
72 ~Lox();
73
74
75 /// Returns a \b %Lox with the given name.
76 /// A \b %Lox is only found if it was created and registered with \alox using #Register.
77 /// If not found, and parameter \p{create} is \c true (the default), a new \b Lox is created,
78 /// registered and returned.
79 ///
80 /// @param name The name of the \b %Lox to search and optionally to create.
81 /// Comparison is case-insensitive.
82 /// @param create Denotes whether a \b %Lox that was not found is created.
83 /// Optional and defaults to \b %CreateIfNotExists::No.
84 /// @return The \b Lox found, \c nullptr in case of failure.
86 static Lox* Get( const NString& name,
88
89 /// Registers or un-registers a \b %Lox object statically with \alox.
90 /// Once registered, any code entity of the same process is enabled to retrieve
91 /// the \b %Lox using #Get.<br>
92 /// No two objects with the same name must be registered. If this is done, the latter
93 /// will not be registered and not be found by #Get. In debug-compilations, an \alib
94 /// assertion is raised if a name is registered twice.<br>
95 /// Note that name comparison is performed case <b>in</b>-sensitive.
96 ///
97 /// If debug-logging is enabled (depends on optional compiler-symbols) and used, the
98 /// singleton of type \c %Lox provided for debug-logging is registered. This uses the name
99 /// \c "Log".
100 ///
101 /// Registration is \e not mandatory but done by default by the constructor of class \b %Lox.
102 /// Therefore, to keep a \b Lox private, an optional parameter is available.
103 ///
104 /// @param lox The \b %Lox to register.
105 /// @param operation If \b %ContainerOp::Remove, the given \p{Lox} is deregistered.
106 /// Defaults to \b %ContainerOp::Insert.
108 static void Register( Lox* lox, lang::ContainerOp operation );
109
110
111 //################################################################################################
112 // Interface
113 //################################################################################################
114 /// Returns the name of this \b %Lox. The name is user-defined, and provided in the
115 /// constructor,
116 /// converted to upper case and otherwise immutable.
117 ///
118 /// @returns The name of this %Lox.
119 const NString& GetName() { return detail::LI::GetName( impl ); }
120
121 /// Returns the number of logs that have been performed with this \b Lox.
122 /// The counter is not used internally other than for providing a
123 /// unique log number: While each logger attached has a own number, if more than one
124 /// logger is attached, their numbers may differ due to different log domain settings.
125 /// \note
126 /// The result is given as a mutual reference to the internal counter, which is allowed
127 /// to be manipulated. This is, for example, used in unit tests.
128 ///
129 /// @returns \c true if this instance was registered with \alox, \c false if not.
131
132 /// Acquires this \b %Lox and sets the scope information data for the next log.
133 /// @param ci The source location that the call is placed at.
135
136 /// Releases ownership of this object. If #Acquire was called multiple times, the same
137 /// number of calls to this method have to be performed to release ownership.
139
140 /// Resets this object.
141 ///
142 /// \attention
143 /// This method was introduced to support resetting the debug \b %Lox objects in the unit
144 /// tests. In real applications, and for release logging it recommended to delete a Lox
145 /// and create a new one instead of resetting one.
146 /// Side effects might appear when using this method!
148
149 /// Changes the capacity of the \b %LRUCacheTable for parsed file names by calling
150 /// \alib{containers;LRUCacheTable::Reserve}.
151 /// @param numberOfLists The number of LRU-lists to use.
152 /// @param entriesPerList The maximum length of each cache list.
153 void SetFileNameCacheCapacity(integer numberOfLists, integer entriesPerList )
154 { detail::LI::SetFileNameCacheCapacity(impl, numberOfLists, entriesPerList ); }
155
156 /// Adds \p{path} to an internal list of substrings that are used to trim the path of
157 /// a source file name. Trimmed paths are used for \e Scope mechanisms and can be
158 /// logged (e.g., with meta-information of class \b TextLogger.
159 ///
160 /// By default such setting affects all instances of class \b Lox, not only
161 /// this instance. This can be altered using parameter \p{global}.
162 /// one other The given trim information can either
163 ///
164 /// If given \p{path} starts with character <c> '*'</c>, the rest of the string is searched
165 /// within source paths. Otherwise, it is checked if a source path starts with the given
166 /// path.
167 ///
168 /// Parameter \p{trimReplacement} optionally provides a replacement string for the trimmed
169 /// path. This can be used, for example, to provide the right absolute path for an IDE
170 /// to find source files of a library.
171 ///
172 /// Parameter \p{includeString} determines if the searched substring should be included in the
173 /// resulting source path or not. In addition, parameter \p{trimOffset}, which can be negative
174 /// or positive, is added to the position of trimming. This can be used to increase the
175 /// length of the search path, and then cut only a portion of what was searched for.
176 ///
177 /// Finally, parameter \p{sensitivity} determines whether the match is performed case
178 /// sensitive or not. It defaults to non-sensitive, for convenience and for the fact that,
179 /// for example, Microsoft C++ compiler's preprocessor passes lower case path-strings!
180 ///
181 /// \note
182 /// If the platform (compiler) specific path separator is <c>'/'</c>, then characters
183 /// <c>'\'</c> found in parameters \p{path} and \p{trimReplacement} are replaced by <c>'\'</c>
184 /// and vice versa. This allows specifying paths and substrings thereof in a platform
185 /// independent way.
186 ///
187 /// \attention
188 /// Setting global rules (when parameter \p{global} equals \c Inclusion::Include) is not
189 /// protected by a \c mutex against concurrent access. Therefore, global rules have
190 /// to be either at bootstrap of a process, before threads are created, or such creation
191 /// has to 'manually' be protected by locking all existing instances of this class!
192 ///
193 /// @param path The path to search for. If not starting with <c> '*'</c>,
194 /// a prefix is searched.
195 /// @param includeString Determines if \p{path} should be included in the trimmed path or
196 /// not.
197 /// Optional and defaults to \b %Inclusion::Exclude.
198 /// @param trimOffset Adjusts the portion of \p{path} that is trimmed.
199 /// Optional and defaults to \c 0.
200 /// @param sensitivity Determines if the comparison of \p{path} with a source file's path
201 /// is performed case-sensitive or not.
202 /// Optional and defaults to \b Case::Ignore.
203 /// @param trimReplacement Replacement string for trimmed portion of the path.
204 /// Optional and defaults to \b %NULL_STRING.
205 /// @param reach Denotes whether the rule is applied locally (to this \b %Lox only)
206 /// or applies to all instances of class \b %Lox.
207 /// Defaults to \b %Reach::Global.
208 /// @param priority The priority of the setting. Defaults to
209 /// \alib{variables;Priority;Standard}.
212 int trimOffset = 0,
213 lang::Case sensitivity = lang::Case::Ignore,
214 const NString& trimReplacement = NULL_NSTRING,
216 Priority priority = Priority::Standard ) {
217 detail::LI::SetSourcePathTrimRule( impl, path, includeString, trimOffset, sensitivity,
218 trimReplacement, reach, priority );
219 }
220
221
222 /// Removes all local trimming rules set with #SetSourcePathTrimRule.
223 /// If parameter \p{global} is set to \b Inclusion::Include, the global rules are cleared
224 /// in addition.
225 ///
226 /// Setting parameter \p{allowAutoRule} to \c false, allows suppressing the creation of an
227 /// automatic rule based on the executables path.
228 ///
229 /// \see Chapter \ref alib_mod_alox_trim_source_path for more information.
230 ///
231 /// @param reach Denotes whether only local rules are cleared or also global ones.
232 /// Defaults to \b %Reach::Global.
233 /// @param allowAutoRule Determines if an auto rule should be tried to be detected next
234 /// no appropriate rule is found.
236 bool allowAutoRule = true ) {
239 999999, // code for clearing
240 lang::Case::Ignore, NULL_NSTRING, reach, Priority::NONE );
241 }
242
243 /// This static method creates a console logger. To decide which logger type to choose,
244 /// configuration variable \ref alxcvALOX_CONSOLE_TYPE is checked. If this variable is not set,
245 /// then the decision is made as follows:
246 /// - On GNU/Linux OS, a
247 /// \ref alib::lox::loggers::AnsiConsoleLogger "AnsiConsoleLogger" is chosen.
248 /// - On Windows OS, if a console window is attached, type
249 /// \ref alib::lox::loggers::WindowsConsoleLogger "WindowsConsoleLogger" is chosen. If
250 /// no console is attached to the process, instead a
251 /// \ref alib::lox::loggers::ConsoleLogger "ConsoleLogger" is returned.
252 ///
253 ///
254 /// @param name The name of the \e Logger. Defaults to nullptr, which uses standard
255 /// names defined by derived \e Logger types.
256 ///
257 /// @return An instance of the chosen console type logger.
258 ALIB_DLL static
259 textlogger::TextLogger* CreateConsoleLogger( const NString& name= nullptr );
260
261 /// Retrieves an instance of a Logger by its name. This might be useful when access to a
262 /// \e %Logger is needed to change its configuration.
263 ///
264 /// @param loggerName The name of the \e Logger to search for (case-insensitive).
265 /// @return The logger, nullptr if not found.
266 detail::Logger* GetLogger( const NString& loggerName )
267 { return detail::LI::GetLogger(impl, loggerName); }
268
269 /// Removes a logger from this container.
270 /// \note
271 /// To (temporarily) disable a logger without removing it, a call to
272 /// \ref SetVerbosity(detail::Logger*,Verbosity,const NString&,Priority) "SetVerbosity(logger, Verbosity::Off)"
273 /// can be used.
274 ///
275 /// @param logger The logger to be removed.
276 /// @returns \c true, if the \e Logger was found and removed, \c false otherwise.
278 { return detail::LI::RemoveLogger(impl, logger); }
279
280 /// Removes logger named \p{loggerName} from this container.
281 /// \note
282 /// To (temporarily) disable a logger without removing it, a call to
283 /// \ref SetVerbosity(detail::Logger*,Verbosity,const NString&,Priority) "SetVerbosity(logger, Verbosity::Off)"
284 /// can be used.
285 ///
286 /// @param loggerName The name of the \e Logger(s) to be removed (case-insensitive).
287 /// @returns The logger that was removed, \c nullptr if not found.
288 detail::Logger* RemoveLogger( const NString& loggerName )
289 { return detail::LI::RemoveLogger(impl, loggerName); }
290
291 /// Sets the \e %Verbosity of the <em>Log Domain</em> which is evaluated from parameter
292 /// \p{domain} and applicable <em>Scope Domains</em>. The \p{verbosity} given is set
293 /// recursively for all Subdomains.
294 ///
295 /// With the first invocation of this method for a distinct \p{logger}, this \e %Logger
296 /// is registered with this \e %Lox. In this case, before setting the given \e Verbosity
297 /// for the evaluated subdomain, the \e Verbosity for all domains is set to
298 /// \b %Verbosity::Off.
299 ///
300 /// To deregister a \e Logger with a \b Lox, use method #RemoveLogger.
301 /// To 'disable' a \e Logger, invoke this method with parameters \p{verbosity} equaling to
302 /// \b %Verbosity::Off and \p{domain} to \c "/".
303 ///
304 /// Optional parameter \p{priority} defaults to
305 /// \alib{variables;Priority;Standard},
306 /// which is a lower priority than those of the standard plug-ins of external configuration
307 /// data. Therefore, external configuration by default 'overwrite' settings made from
308 /// 'within the source code', which simply means by invoking this method.<br>
309 /// The parameter can be provided for two main reasons:
310 /// - To 'lock' a verbosity setting against external manipulation.
311 /// - to 'break' the standard mechanism that an invocation of this method sets all
312 /// Subdomains recursively. If a subdomain was set with a higher priority
313 /// (e.g., <c>%Config::PriorityOf(Priority::Standard) + 1</c>, then this subdomain will
314 /// not be affected by future invocations of this method with standard-priority given.
315 ///
316 /// For more information on how to use external configuration variables with priority and
317 /// on protecting verbosity settings, consult the \ref alib_mod_alox.
318 ///
319 /// \attention
320 /// The same as with most interface methods of this class, the given \p{domain} parameter is
321 /// combined with <em>%Scope Domains</em> set for the caller's \e %Scope. In standard use
322 /// cases of %ALox, the \e %Verbosity of a \e Domain is set using absolute domain path
323 /// addressing. Therefore, it is recommended to have any domain path passed to this method
324 /// starting with <c> '/'</c>, which suppresses the concatenation of <em>%Scope Domains</em>.<br>
325 /// This is why this parameter with this method defaults to <c> '/'</c>, while with other
326 /// methods of this class, it defaults to an empty string.
327 /// <p>
328 /// \attention
329 /// Even when using an absolute domain path, <em>%Scope Domains</em> of
330 /// \e %Scope::ThreadInner, will still apply. This means that from within a thread that
331 /// has such <em>%Scope Domain</em> set, this method is (almost) not usable!
332 /// This all aligns with the concept (advice), that \e Loggers and their \e %Verbosity
333 /// are generally set outside of such scopes, hence in configuration sections of a
334 /// process.<p>
335 /// \attention
336 /// Consequently, this method may be (mis-) used to modify the 'actual' (default) scope
337 /// when explicitly giving an empty string with parameter \p{domain}. This is useful, to
338 /// temporarily adjust a scope. But remember: \alox was designed to avoid temporary
339 /// code lines...
340 ///
341 /// @param logger The logger to be to be affected (case-insensitive).
342 /// @param verbosity The 'level of verboseness' to be set.
343 /// @param domain The parent (start) domain to be set. The use of absolute paths
344 /// starting with <c> '/'</c> are recommended.
345 /// Defaults to root domain \"/\".
346 /// @param priority The priority of the setting. Defaults to
347 /// \alib{variables;Priority;Standard}.
349 Verbosity verbosity,
350 const NString& domain = "/",
351 Priority priority = Priority::Standard )
352 { detail::LI::SetVerbosity(impl, logger, verbosity, domain, priority); }
353
354 /// Same as
355 /// \ref #SetVerbosity(detail::Logger*,Verbosity,const NString&,Priority) "SetVerbosity"
356 /// but addressing the \e %Logger to manipulate by its name.<br>
357 /// This method may only be used after a \e %Logger was once 'registered' with this \b %Lox
358 /// using
359 /// \ref #SetVerbosity(detail::Logger*,Verbosity,const NString&,Priority) "SetVerbosity".
360 ///
361 /// @param loggerName The logger to be to be affected, identified by its name (case
362 /// insensitive).
363 /// @param verbosity The 'level of verboseness' to be set.
364 /// @param domain The parent (start) domain to be set. The use of absolute paths
365 /// starting with <c> '/'</c> are recommended.
366 /// Defaults to root domain \"/\".
367 /// @param priority The priority of the setting. Defaults to
368 /// \alib{variables;Priority;Standard}.
369 void SetVerbosity( const NString& loggerName,
370 Verbosity verbosity,
371 const NString& domain = "/",
372 Priority priority = Priority::Standard )
373 { detail::LI::SetVerbosity(impl, loggerName, verbosity, domain, priority); }
374
375 /// The given \p{scopeDomain} becomes the default domain path for given \p{scope}.
376 /// This means, that any subsequent log invocations (from within this same scope) can omit
377 /// the domain parameter, or if they provide one, this Scope Domain path is prepended.
378 /// If subsequent log calls specify a domain name with a leading '/' character,
379 /// then the Scope Domain of the scope is ignored.<br>
380 /// Furthermore, if the given scope is an inner scope, outer scopes are prepended to the
381 /// given \p{scopeDomain} when the resulting domain of a log invocation is evaluated.
382 /// Again, this behavior can be overruled by prepending a leading '/' character to
383 /// \p{scopeDomain}.
384 ///
385 /// To remove a previously set Scope Domain a \e nulled or empty string has to be passed with
386 /// parameter \p{scopeDomain}.
387 /// For \e %Scope::ThreadOuter and \e %Scope::ThreadInner, passing an empty or \e nulled
388 /// string removes the most recently added domain path. For removing an explicitly named
389 /// domain path of \e %Scope::ThreadOuter and \e %Scope::ThreadInner use method
390 /// #RemoveThreadDomain.
391 ///
392 /// \note
393 /// The C++ version of \alox implements scope mechanisms using scope information generated
394 /// by the preprocessor. By default, debug logging supports such caller information,
395 /// release logging does not. This can be changed.<br>
396 /// For more information on how to change such defaults, see documentation of preprocessor
397 /// symbols \ref ALOX_DBG_LOG_CI and \ref ALOX_REL_LOG_CI.
398 ///
399 /// @param scopeDomain The domain path to register.
400 /// @param scope The scope that should the given \p{domain} be registered for.
401 /// Available Scope definitions are platform/language dependent.
402 void SetDomain( const NString& scopeDomain, Scope scope )
403 { detail::LI::setDomain(impl, scopeDomain, scope, false, nullptr ); }
404
405 /// This overloaded version of
406 /// \ref SetDomain(const NString&,Scope) "SetDomain" is applicable only for
407 /// \e %Scope::ThreadOuter and \e %Scope::ThreadInner and allows specifying the thread that
408 /// the setting should be associated with.
409 ///
410 /// If \p{scopeDomain} is nullptr or empty, the most recently added domain path is removed.
411 /// For removing an explicitly named domain associated with a thread use method
412 /// #RemoveThreadDomain.
413 ///
414 /// @param scopeDomain The domain path to register.
415 /// @param scope Either \e %Scope::ThreadOuter or \e %Scope::ThreadInner. With other
416 /// values, an internal error is logged.
417 /// @param thread The thread to set/unset a thread-related Scope Domains for.
418 void SetDomain( const NString& scopeDomain, Scope scope, threads::Thread* thread )
419 { detail::LI::setDomain( impl, scopeDomain, scope, false, thread ); }
420
421 /// Adds a <em>Domain Substitution Rule</em>.
422 /// <em>Domain Substitution</em> is performed as a last step when evaluating the domain path
423 /// of a <em>Log Statement</em>, taking <em>Scope Domains</em> and the optional parameter
424 /// \p{domain} of the statement into account.<br>
425 ///
426 /// <b>Wildcards</b><br>
427 /// Parameter \p{domainPath} supports \b 'wildcard' character <c> '*'</c> at its beginning
428 /// and at its end (or both). This allows having four types of rules:
429 /// - Exact match
430 /// - Prefix match (\c * at the end of \p{domainPath})
431 /// - Suffix match (\c * at the start of \p{domainPath})
432 /// - Substring match (\c * at both, start and the end of \p{domainPath})
433 ///
434 /// Only minimal checks are performed, e.g., if an exact match is requested, but \p{domainPath}
435 /// does not start with character <c> '/'</c>. In this and some other cases, the rule is not
436 /// stored and an internal warning is logged. Further checks, for example, for illegal
437 /// domain path characters, are not performed.
438 /// (Illegal domain path characters will be eliminated when the resulting domain path is to
439 /// be created internally).
440 ///
441 /// <b>Circular Dependencies</b><br>
442 /// If the given rules have circular dependencies, only a limited number (ten) replacements
443 /// are performed. If this number of replacements for one <em>Log Statement</em> is exceeded,
444 /// an internal warning message is logged. This is done only \e once over the life-time of
445 /// a \e Logger.
446 ///
447 /// <b>Application of Rules</b><br>
448 /// Rules are applied in the order of their definition. After all rules have been applied,
449 /// this is repeated as long as at least one rule matches (up to ten times).
450 ///
451 /// <b>Deletion of Rules</b>
452 /// To delete a rule, invoke the method with the same parameter \p{domainPath} but with
453 /// a \e 'nulled' or empty string for parameter \p{replacement}.
454 /// To delete all rules, invoke the method with parameter \p{domainPath} \e 'nulled'
455 /// or empty.
456 ///
457 /// <b>Final remarks</b>
458 /// Domain substitution is useful to permanently change ('redirect') domain paths of
459 /// 3rd party code (e.g., libraries using \alox) or log statements that must not be changed
460 /// for other reasons. It is advised to not 'overuse' this feature, as side effects
461 /// are inherent to the concept of <em>Domain Substitution</em>. For example, an unwanted
462 /// side effect might be that <em>Prefix Logables</em> are not applicable to the substituted
463 /// domain, while other <em>Prefix Logables</em> are bound to the resulting domain.
464 ///
465 /// For \b %Lox objects that should be protected of external manipulation, it is advisable
466 /// to remove all <em>Domain Substitution Rules</em> right after the \b %Lox was created by
467 /// invoking this method with a \e nulled value for parameter \p{domainPath}.
468 /// The reason is that otherwise, through configuration files or command line parameters,
469 /// domains of the \b %Lox can be substituted and then the resulting domains \e Verbosities
470 /// be \e overwritten using further configuration variables.
471 /// Any prioritized \e 'internal' setting of \e Verbosities this way could be circumvented!
472 ///
473 /// For more information, consult the chapter \ref alib_mod_alox_domain_substitution of the
474 /// Programmer's Manual.
475 ///
476 /// @param domainPath The path to search. Has to start with either <c>'/'</c> or <c>'*'</c>.
477 /// @param replacement The replacement path.
478 void SetDomainSubstitutionRule( const NString& domainPath, const NString& replacement )
479 { detail::LI::SetDomainSubstitutionRule(impl, domainPath, replacement); }
480
481 /// This method is used to remove an <em>explicitly given</em> domain path from the list
482 /// of domain paths set for \e %Scope::ThreadOuter or \e %Scope::ThreadInner.
483 ///
484 /// To remove the most recently added domain path from such thread-related \e %Scope,
485 /// use one of the overloaded methods #SetDomain and provide an empty or \e nulled
486 /// value for parameter \p{scopeDomain} (the same as how domain paths of other \e %Scopes
487 /// are removed).
488 ///
489 /// \note
490 /// The long name of the method already indicates that this method is a little special.
491 /// Only seldom, more than one <em>%Scope Domain</em> is needed to be added. And if this
492 /// is needed, then such <em>%Scope Domains</em> usually get removed in reverse order of
493 /// their definition, with is performed using the standard interface that allows 'removing'
494 /// any other <em>%Scope Domain</em>. (Passing an empty or \e nulled domain
495 /// path to method #SetDomain.)
496 ///
497 /// @param scopeDomain The domain path to register.
498 /// @param scope Either \e %Scope::ThreadOuter or \e %Scope::ThreadInner. With other
499 /// values, an internal error is logged.
500 /// @param thread The thread to set/unset a thread-related Scope Domains for.
501 /// Defaults to the current thread.
502 void RemoveThreadDomain( const NString& scopeDomain, Scope scope,
503 threads::Thread* thread= nullptr )
504 { detail::LI::RemoveThreadDomain(impl, scopeDomain, scope, thread); }
505
506 /// The given \p{prefix} becomes a <em>Prefix Logable</em> provided to loggers with each log
507 /// statement executed within the given \p{scope}.
508 /// The list of objects received by a logger is sorted from outer scope to inner scope.
509 /// The logable of the <em>%Log Statement</em> itself, is the last in the list, except one
510 /// or more <em>Prefix Logables</em> of \e %Scope::ThreadInner are set. Those are (similar
511 /// to how this \e %Scope is used with <em>%Scope Domains</em>) appended to the end of the
512 /// list.
513 ///
514 /// To remove a previously set <em>Prefix Logable</em>, \c nullptr has to be passed with
515 /// parameter \p{prefix}.
516 /// For \e %Scope::ThreadOuter and \e %Scope::ThreadInner, passing \c nullptr (respectively
517 /// with the overloaded method accepting string messages, a \e nulled string)
518 /// removes the most recently added <em>Prefix Logable</em>.
519 ///
520 ///
521 /// \note
522 /// \e Logables of boxed character array types are duplicated internally by \alox when
523 /// setting as <em>Prefix Logables</em>.
524 /// This means, in contrast to other types, for string-type <em>Prefix Logables</em>
525 /// the life-cycle of the object passed in parameter \p{prefix} is allowed to end
526 /// right after the invocation of this method. This is a convenience feature of \alox.
527 /// However, this also means, that changes of the strings that occur after the string
528 /// objects got set as a <em>Prefix Logable</em>, are \b not reflected.<br>
529 /// To implement a "variable" <em>Prefix Logable</em> of string-type, an object of type
530 /// \b %AString might be passed wrapped in class \c std::reference_wrapper<AString>.<br>
531 /// For more information, consult manual chapter
532 /// \ref alib_mod_alox_prefix_logables_lifecycle
533 /// as well as chapter \ref alib_boxing_customizing_identity of the Programmer's Manual
534 /// of module \alib_boxing.
535 ///<p>
536 /// \note
537 /// Unlike other methods of this class which accept an arbitrary amount of logables, this
538 /// method and its overloaded variants accept only one logable (the prefix).
539 /// To supply several objects to be prefix logables at once, a container of type
540 /// \alib{boxing;TBoxes} may be passed with parameter \p{logables}, like
541 /// in the following sample:
542 /// \snippet "ut_alox_log_scopes.cpp" DOX_ALOX_LOX_SETPREFIX
543 /// The provided container as well as the prefixes themselves have to be kept in memory
544 /// until they are unset.
545 ///
546 ///<p>
547 /// \note
548 /// The C++ version of \alox implements scope mechanisms using scope information
549 /// generated by the preprocessor. By default, debug logging supports such caller
550 /// information, release logging does not. Both defaults can be changed with preprocessor
551 /// symbols \ref ALOX_DBG_LOG_CI and \ref ALOX_REL_LOG_CI.
552 ///
553 ///<p>
554 /// \note
555 /// The word 'prefix' in this method's name and in the name of \alox feature
556 /// <em>Prefix Logables</em> is chosen for the fact that with text loggers (which is the
557 /// most widely applied use case for \alox) such objects are prefixes to the log
558 /// message. Of course, with using \e %Scope::ThreadInner, this turns into a suffix!<br>
559 /// When using \alox to process arbitrary objects instead of text messages, the concept of
560 /// <em>Prefix Logables</em> is still very useful. Just the name does not fit so well
561 /// anymore. Think of 'SetContext' and <em>Context Objects</em> instead.
562 ///
563 /// @param prefix The <em>Prefix Logable</em> to set.
564 /// @param scope The scope that should the given \p{domain} be registered for.
565 /// Available Scope definitions are platform/language dependent.
566 void SetPrefix( const Box& prefix, Scope scope )
567 { detail::LI::setPrefix( impl, prefix, scope, nullptr ); }
568
569 /// This overloaded version of
570 /// \ref SetPrefix(const Box&,Scope) "SetPrefix" is applicable only for
571 /// \b %Scope::ThreadOuter and \b %Scope::ThreadInner and allows specifying the thread that
572 /// the setting should be associated with.
573 ///
574 /// If \p{scopeDomain} is nullptr or empty, the most recently added <em>Prefix Logable</em>
575 /// is removed.
576 ///
577 /// @param prefix The <em>Prefix Logable</em> to set.
578 /// @param scope Either \e %Scope::ThreadOuter or \e %Scope::ThreadInner. With other
579 /// values, an internal error is logged.
580 /// @param thread The thread to set/unset a thread-related Scope Domains for.
581 void SetPrefix( const Box& prefix, Scope scope, threads::Thread* thread )
582 { detail::LI::setPrefix( impl, prefix, scope, thread ); }
583
584 /// The given \p{prefix} becomes a <em>Prefix Logable</em> associated to the given
585 /// <em>Log Domain</em>.
586 /// <em>Prefix Logables</em> associated with the <em>Log Domain</em> are added to the
587 /// list of \e Logables right
588 /// before the main \e Logable of the <em>Log Statement</em> itself.
589 /// Multiple <em>Prefix Logables</em> can be added per <em>Log Domain</em>.
590 ///
591 /// To remove the most recently added <em>Prefix Logable</em> associated with a
592 /// <em>Log Domain</em>, \c nullptr has to be passed with parameter \p{prefix}.
593 ///
594 /// \note
595 /// String-type \e Logables are duplicated internally by \alox when setting as
596 /// <em>Prefix Logables</em>.
597 /// This means, different to <em>Prefix Logables</em> of type \b %AString or custom types,
598 /// the life-cycle of the object passed in parameter \p{prefix} is allowed to end
599 /// right after the invocation of this method. For more information, consult manual
600 /// chapter \ref alib_mod_alox_prefix_logables_lifecycle as well as chapter
601 /// \ref alib_boxing_customizing_identity of the Programmer's Manual of module
602 /// \alib_boxing.
603 ///
604 /// \attention
605 /// The same as with most interface methods of this class, the given \p{domain} parameter
606 /// is combined with <em>%Scope Domains</em> set for the caller's \e %Scope.
607 /// To suppress this, an absolute domain path can be used. (Still any
608 /// <em>Scope Domain</em> of \e %Scope::Thread::Inner will be applied).
609 /// The default value of parameter \p{domain} is \c "" which addresses the domain
610 /// evaluated for the current scope.
611 ///
612 /// @param prefix The <em>Prefix Logable</em> to set.
613 /// @param domain The domain path. Defaults to \c nullptr, resulting in
614 /// evaluated <em>Scope Domain</em> path.
615 /// @param otherPLs If set to \c Inclusion::Exclude, scope-related
616 /// <em>Prefix Logables</em> are ignored and only domain-related
617 /// <em>Prefix Logables</em> are passed to the \e Loggers.<br>
618 /// Defaults to \c Inclusion::Include.
619 void SetPrefix( const Box& prefix, const NString& domain= nullptr,
621 { detail::LI::SetPrefix(impl, prefix, domain, otherPLs); }
622
623 /// This method is used reset (or to explicitly set) the start time of one or all logger(s).
624 /// The only impact is the output of time differences in the log lines. Hence, this method
625 /// is useful to reset them and see some absolute time values when doing basic performance
626 /// tests using the \e Logger.
627 ///
628 /// \note This affects loggers that are registered for at least one standard domain.
629 /// In other words, loggers that are exclusively attached to the internal domain,
630 /// will not be affected.
631 ///
632 /// @param startTime Optional parameter with the new start time. Defaults
633 /// to current time if omitted.
634 /// @param loggerName The name of the \e Logger(s) whose start time is to be set
635 /// (case-insensitive).
636 /// Defaults to nullptr, which indicates that all loggers are to
637 /// be affected.
638 void SetStartTime( Ticks startTime = time::Ticks (),
639 const NString& loggerName = nullptr )
640 { detail::LI::SetStartTime(impl, startTime, loggerName); }
641
642 #if defined (__GLIBCXX__) || defined(_LIBCPP_VERSION) || defined(__APPLE__)
643 /// Converts the given \p{startTime} and invokes #SetStartTime(Ticks,const NString&).
644 /// \note GLib specific.
645 ///
646 /// @param startTime The new start time in system-specific time unit.
647 /// @param loggerName The name of the \e Logger whose start time is to be set (case
648 /// insensitive).
649 /// Defaults to empty string, which indicates that all loggers are to
650 /// be affected.
651 void SetStartTime( time_t startTime, const NString& loggerName= nullptr )
652 { detail::LI::SetStartTime(impl, startTime, loggerName); }
653
654
655 #endif // no elif here, otherwise doxygen would ignore it!
656
657 #if defined( _MSC_VER )
658 //======================================================================================
659 /// Converts the given \p{startTime} and invokes#SetStartTime(Ticks,const NString&).
660 /// \note Microsoft Windows specific.
661 ///
662 /// @param startTime The new start time in system-specific time unit.
663 /// @param loggerName The name of the \e Logger whose start time is to be set (case
664 /// insensitive).
665 /// Defaults to empty string, which indicates that all loggers are to
666 /// be affected.
667 //======================================================================================
668 void SetStartTime( const FILETIME& startTime, const NString& loggerName= nullptr )
669 {
670 detail::LI::SetStartTime(impl, startTime, loggerName);
671 }
672
673 #endif
674
675 /// This method sets a human-readable name to the given thread ID (or current thread) which
676 /// is optionally included in each log line.
677 ///
678 /// @param threadName The name of the thread as it should be displayed in the logs.
679 /// @param id (Optional) Parameter providing the thread ID. If omitted, the
680 /// current thread's ID is used.<br>
681 /// If given, the associated object of \alib{threads;Thread} must not
682 /// be deleted until this method returns. This is a race condition
683 /// that a using code has do ensure.
684 void MapThreadName( const String& threadName, threads::ThreadID id= 0 )
685 { detail::LI::MapThreadName(impl, threadName, id); }
686
687 /// Stores data encapsulated in an object of class
688 /// \ref alib::boxing::Box "Box" which can be retrieved back by invoking
689 /// #Retrieve. Using the optional \p{key} and \p{scope} offer various possibilities to
690 /// reference this data later.
691 ///
692 /// To remove data from the store, pass \c nullptr with parameter \p{data}.
693 ///
694 /// \attention
695 /// When data objects are 'overwritten', previous objects will be deleted internally.
696 /// Hence, only pointers to heap-allocated objects (created with \c new) may be
697 /// passed!<br>
698 /// For more information, consult chapter \ref alib_mod_alox_log_data of the
699 /// Programmer's Manual.
700 ///
701 /// \note <em>Log Data</em> is a feature provided by \alox to support debug-logging.
702 /// It is not advised to use <em>Log Data</em> to implement application logic.
703 ///
704 /// @param data The data object to store.
705 /// If \c nullptr, currently stored data will be removed.
706 /// In C++, has to be heap allocated and will be deleted
707 /// by this \b %Lox when overwritten or this lox is deleted.
708 /// @param key The optional key to the data.
709 /// If omitted (or empty or nullptr), the data is bound to the \e %Scope
710 /// provided. If omitted and \p{scope} is Scope::Global, then the
711 /// data is unique to the \e Lox.
712 /// @param scope The \e %Scope that the data is bound to.
713 void Store( const Box& data, const NString& key, Scope scope= Scope::Global )
714 { detail::LI::store( impl, data, key, scope ); }
715
716 /// Overloaded version of
717 /// Store(const Box&,const String&,Scope,int) "Store" which omits parameter \p{key}.
718 /// @param data The data object to store.
719 /// In C++, has to be heap allocated and will be deleted
720 /// by this \b %Lox when overwritten or this lox is deleted.
721 /// @param scope The \e %Scope that the data is bound to.
722 void Store( const Box& data, Scope scope= Scope::Global )
723 { detail::LI::store( impl, data, nullptr, scope ); }
724
725 /// Retrieves \alox <em>Log Data</em>, an object type
726 /// \ref alib::boxing::Box "Box" which had been stored in a prior call to
727 /// #Store. Using the optional \p{key} and \p{scope} offer various possibilities to reference
728 /// such objects.<br>
729 ///
730 /// \note If no data is found, an \e nulled object is returned. This can be tested using method
731 /// \ref alib::boxing::Box::IsNull "Box::IsNull".
732 ///
733 /// <p>
734 /// \note <em>Log Data</em> is a feature provided by \alox to support debug-logging.
735 /// It is not advised to use <em>Log Data</em> to implement application logic.
736 ///
737 /// @param key The optional key to the data.
738 /// If omitted (or empty or nullptr), the data is bound to the \e %Scope
739 /// provided. If omitted and \p{scope} is Scope::Global, then the
740 /// data is unique to the \e Lox.
741 /// @param scope The \e %Scope that the data is bound to.
742 /// @return The data, a \e nulled box if no value was found.
744 Box Retrieve ( const NString& key, Scope scope= Scope::Global )
745 { return detail::LI::retrieve( impl, key, scope ); }
746
747 /// * Overloaded version of #Retrieve which omits parameter \p{key}.
748 ///
749 /// \note <em>Log Data</em> is a feature provided by \alox to support debug-logging.
750 /// It is not advised to use <em>Log Data</em> to implement application logic.
751 ///
752 /// @param scope The \e %Scope that the data is bound to.
753 /// @return The data, a \e nulled box if no value was found.
755 Box Retrieve ( Scope scope= Scope::Global )
756 { return detail::LI::retrieve( impl, nullptr, scope ); }
757
758 /// This method logs the current configuration of this Lox and its encapsulated objects.
759 /// It uses method #GetState to assemble the logable string.
760 ///
761 /// \note
762 /// As an alternative to (temporarily) adding an invocation of <b>%Lox.State</b> to
763 /// your code, \alox provides configuration variable\ref alxcvALOX_LOXNAME_DUMP_STATE_ON_EXIT.
764 /// This allows enabling an automatic invocation of this method using external
765 /// configuration data like command line parameters, environment variables or
766 /// INI files.
767 ///
768 /// @param domain Optional <em>Log Domain</em> which is combined with <em>%Scope Domains</em>
769 /// set for the \e %Scope of invocation.
770 /// @param verbosity The verbosity.
771 /// @param headLine If given, a separated headline will be logged at first place.
772 /// @param flags Flag bits that define which state information is logged.
773 void State ( const NString& domain,
774 Verbosity verbosity,
775 const String& headLine,
776 StateInfo flags = StateInfo::All )
777 { detail::LI::State(impl, domain, verbosity, headLine, flags); }
778
779 /// This method collects state information about this lox in a formatted multi-line AString.
780 /// Parameter \p{flags} is a bitwise enum type (operators on elements available).
781 ///
782 /// \note
783 /// As an alternative to (temporarily) adding an invocation of <b>%Lox.State</b> to
784 /// your code, \alox provides configuration variable \ref alxcvALOX_LOXNAME_DUMP_STATE_ON_EXIT.
785 /// This allows enabling an automatic invocation of this method using external
786 /// configuration data like command line parameters, environment variables or
787 /// INI files.
788 /// @param buf The target string.
789 /// @param flags Bits that define which state information is collected.
791 { detail::LI::GetState(impl, buf, flags); }
792
793
794 //################################################################################################
795 // Main logging methods
796 //################################################################################################
797 /// Returns a reference to a list of boxes to be used for logging. The list is recycled
798 /// from a previous log operation and cleared. The method may be used to retrieve
799 /// a container for logables that then are collected until finally logged.<br>
800 /// Note that the \b %Lox instance has to be acquired before invoking this method and
801 /// the container returned must be used only while the object is still acquired.
802 ///
803 /// With each recursive acquirement of this object, a different container is returned.
804 /// This is implemented to allow recursive log calls.
805 ///
806 /// @return An empty list of boxes.
808
809 /// Logs the current list of \e Logables that previously have been received using
810 /// #GetLogableContainer with the given \p{verbosity}.
811 ///
812 /// This method is usually \b not used directly. Instead, methods
813 /// #Info, #Verbose, #Warning and #Error provide simpler interfaces which take variadic
814 /// arguments that are collected in a list of boxed objects and then passed to
815 /// this methods.<br>
816 /// Note that the other interface methods accept an "external" list of boxes as a parameter.
817 /// as well. This means also with these methods it is allowed to collect the logables in
818 /// an user-specific list first and later pass them to these methods.
819 ///
820 /// Hence, the use of this method is recommended only if the verbosity of a log statement
821 /// is evaluated only at run-time.
822 ///
823 /// @param domain The domain.
824 /// @param verbosity The verbosity.
825 void Entry( const NString& domain, Verbosity verbosity )
826 { detail::LI::Entry(impl, domain, verbosity); }
827
828 /// Logs a list of \e Logables with the given \e %Verbosity.
829 ///
830 /// If more than one \e Logable is given and the first one is of string-type and comprises a
831 /// valid domain path, then this first argument is interpreted as the domain name!
832 /// Valid domain path are strings that consists only of characters of the following set:
833 /// - upper case letters,
834 /// - numbers,
835 /// - hyphen (\c '-'),
836 /// - underscore (\c '_') and
837 /// - forward slash (\c '/').
838 ///
839 /// If a first \e Logable could be misinterpreted as being a domain name, an empty string
840 /// (the "neutral" domain) has to be added as a first argument. Alternatively, a character
841 /// which is illegal in respect to domain names could be added to the first argument,
842 /// for example, a simple space at the end of an output string.
843 ///
844 /// \note
845 /// This method allows a consistent interface of overloaded methods \b %Info, \b Error,
846 /// etc, without introducing a separate version which excepts a - then mandatory - domain
847 /// parameter.
848 /// The little drawback of the auto detection is the possibility of ambiguous invocations.
849 ///
850 /// @param verbosity The verbosity.
851 /// @param logables The list of \e Logables, optionally including a domain name at the start.
852 template <typename... BoxedObjects>
853 void EntryDetectDomain( Verbosity verbosity, BoxedObjects&&... logables )
854 {
855 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
857 }
858
859 /// Logs given logables using \alib{lox;Verbosity;Verbosity::Verbose}.
860 ///
861 /// The first object provided may be a domain name. All values are passed to
862 /// #EntryDetectDomain. See documentation of this method for information on how to avoid
863 /// ambiguities in respect to domain names.
864 ///
865 /// If one of the arguments (or a single argument given) is of type
866 /// \alib{boxing,TBoxes}, then the contents of this list is inserted into
867 /// the list of logables. This allows collecting logables before invoking the method.
868 ///
869 /// @param logables The list of \e Logables, optionally including a domain name at the start.
870 template <typename... BoxedObjects>
871 void Verbose( BoxedObjects&&... logables )
872 {
873 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
874 detail::LI::entryDetectDomainImpl( impl, Verbosity::Verbose );
875 }
876
877 /// Logs given logables using \alib{lox;Verbosity;Verbosity::Info}.
878 ///
879 /// The first object provided may be a domain name. All values are passed to
880 /// #EntryDetectDomain. See documentation of this method for information on how to avoid
881 /// ambiguities in respect to domain names.
882 ///
883 /// If one of the arguments (or a single argument given) is of type
884 /// \alib{boxing,TBoxes}, then the contents of this list is inserted into
885 /// the list of logables. This allows collecting logables before invoking the method.
886 ///
887 /// @param logables The list of \e Logables, optionally including a domain name at the start.
888 template <typename... BoxedObjects>
889 void Info( BoxedObjects&&... logables )
890 {
891 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
892 detail::LI::entryDetectDomainImpl( impl, Verbosity::Info );
893 }
894
895 /// Logs given logables using \alib{lox;Verbosity;Verbosity::Warning}.
896 ///
897 /// The first object provided may be a domain name. All values are passed to
898 /// #EntryDetectDomain. See documentation of this method for information on how to avoid
899 /// ambiguities in respect to domain names.
900 ///
901 /// If one of the arguments (or a single argument given) is of type
902 /// \alib{boxing,TBoxes}, then the contents of this list is inserted into
903 /// the list of logables. This allows collecting logables before invoking the method.
904 ///
905 /// @param logables The list of \e Logables, optionally including a domain name at the start.
906 template <typename... BoxedObjects>
907 void Warning( BoxedObjects&&... logables )
908 {
909 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
910 detail::LI::entryDetectDomainImpl( impl, Verbosity::Warning );
911 }
912
913 /// Logs given logables using \alib{lox;Verbosity;Verbosity::Error}.
914 ///
915 /// The first object provided may be a domain name. All values are passed to
916 /// #EntryDetectDomain. See documentation of this method for information on how to avoid
917 /// ambiguities in respect to domain names.
918 ///
919 /// If one of the arguments (or a single argument given) is of type
920 /// \alib{boxing,TBoxes}, then the contents of this list is inserted into
921 /// the list of logables. This allows collecting logables before invoking the method.
922 ///
923 /// @param logables The list of \e Logables, optionally including a domain name at the start.
924 template <typename... BoxedObjects>
925 void Error( BoxedObjects&&... logables )
926 {
927 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
928 detail::LI::entryDetectDomainImpl( impl, Verbosity::Error );
929 }
930
931 /// Logs given logables only if the parameter \p{condition} is not \c true.
932 /// If executed, \alib{lox;Verbosity;Verbosity::Error} is used.
933 ///
934 /// The first object provided may be a domain name. All values are passed to
935 /// #EntryDetectDomain. See documentation of this method for information on how to avoid
936 /// ambiguities in respect to domain names.
937 ///
938 /// If one of the arguments (or a single argument given) is of type \alib{boxing,TBoxes},
939 /// then the contents of this list are inserted into the list of logables. This allows
940 /// collecting logables before invoking the method.
941 ///
942 /// @param condition If \c false, the <em>Log Statement</em> is executed.
943 /// @param logables The list of \e Logables, optionally including a domain name at the start.
944 template <typename... BoxedObjects>
945 void Assert( bool condition, BoxedObjects&&... logables ) {
946 if (!condition ) {
947 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
948 detail::LI::entryDetectDomainImpl( impl, Verbosity::Error );
949 }
950 else
952 }
953
954 /// Logs a list of \e Logables only if the parameter \p{condition} is \c true.
955 ///
956 /// \see Method #Assert.
957 ///
958 /// @param condition If \c false, the <em>Log Statement</em> is executed.
959 /// @param domain Optional <em>Log Domain</em> which is combined with <em>%Scope Domains</em>
960 /// set for the \e %Scope of invocation.
961 /// @param verbosity The verbosity.
962 /// @param logables The list of \e Logables.
963 template <typename... BoxedObjects>
964 void If( bool condition, const NString& domain, Verbosity verbosity,
965 BoxedObjects&&... logables ) {
966 if ( condition ) {
967 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
968 detail::LI::Entry( impl, domain, verbosity );
969 }
970 else
972 }
973
974 /// Logs a list of \e Logables only if the parameter \p{condition} is \c true.<br>
975 ///
976 /// This overloaded version omits parameter \p{domain}.
977 /// The first \e logable provided may be a domain name. All values are passed to
978 /// #EntryDetectDomain. See documentation of this method for information on how to avoid
979 /// ambiguities in respect to domain names.
980 ///
981 /// If one of the arguments (or a single argument given) is of type
982 /// \alib{boxing,TBoxes}, then the contents of this list is inserted into
983 /// the list of logables. This allows collecting logables before invoking the method.
984 ///
985 /// \see Method #Assert.
986 ///
987 /// @param condition If \c false, the <em>Log Statement</em> is executed.
988 /// @param verbosity The verbosity.
989 /// @param logables The list of \e Logables.
990 template <typename... BoxedObjects>
991 void If( bool condition, Verbosity verbosity, BoxedObjects&&... logables ) {
992 if ( condition ) {
993 detail::LI::GetLogableContainer(impl).Add( std::forward<BoxedObjects>(logables)... );
995 }
996 else
998 }
999
1000
1001 /// Logs given \e logables once, up to \p{quantity} times, or every n-th time.
1002 /// In its simplest overloaded version, the counter is bound to the source code line, hence,
1003 /// only the first execution of this exact <em>Log Statement</em> is executed.
1004 ///
1005 /// With parameter \p{group}, a set of <em>Log Statements</em> that share the same group key,
1006 /// can be grouped and of such set, only the one which is first executed actually logs.<br>
1007 /// Alternatively, when \p{key} is omitted (or nullptr or empty), but a
1008 /// \ref alib::lox::Scope "Scope" is given with parameter \p{scope}, then the
1009 /// counter is associated with the scope.<br>
1010 /// Finally, parameters \p{key} and \p{scope} can also be used in combination. The key is
1011 /// then unique in respect to the \ref alib::lox::Scope "Scope" provided.
1012 ///
1013 /// Using, none, one or both of the parameters \p{group} and \p{scope}, among others, the
1014 /// following use cases can be achieved.
1015 /// - %Log a specific statement up to n-times.
1016 /// - %Log only the first n of a group of statements.
1017 /// - %Log only the first n statements within a method.
1018 /// - %Log only the first n statements belonging to the same group and method .
1019 /// - %Log only the first n statements within any method of
1020 /// - a source file
1021 /// - a directory of source files
1022 /// - a parent directory of source files and all sources recursively
1023 /// - %Log only the first n statements which belong to the same group and are placed within
1024 /// any method of
1025 /// - a source file
1026 /// - a directory of source files
1027 /// - a parent directory of source files and all sources recursively
1028 /// - %Log a <em>Log Statement</em> n-times per new thread.
1029 /// - %Log only the first n statements of a group of statements executed by a specific thread.
1030 ///
1031 /// When parameter \p{quantity} is a negative value, the log statement is executed every n-th time
1032 /// instead n-times. E.g, if \p{quantity} is \c -5, the first statement is executed and afterwards
1033 /// every fifth invocation.
1034 ///
1035 /// \note
1036 /// Unlike other methods of this class which accept an arbitrary amount of logables, this
1037 /// method and its overloaded variants accept only one boxed object.
1038 /// To still be able to supply several objects at once, an array of boxes or a container
1039 /// of type \alib{boxing,TBoxes} may be passed with parameter
1040 /// \p{logables}, like in the following sample:
1041 /// \snippet "ut_alox_lox.cpp" DOX_ALOX_LOX_ONCE
1042 /// This is why the parameter name \p{logables} still uses the plural with its name!
1043 ///
1044 ///
1045 /// @param domain Optional <em>Log Domain</em> which is combined with <em>%Scope Domains</em>
1046 /// set for the \e %Scope of invocation.
1047 /// @param verbosity The verbosity of the <em>Log Statement</em> (if performed).
1048 /// @param logables The objects to log (Multiple objects may be provided within
1049 /// container class Boxes.)
1050 /// @param group The optional name of the statement group . If used, all statements that
1051 /// share the same group name are working on the same counter (according
1052 /// to the \p{scope}.)
1053 /// If omitted (or empty or nullptr), the counter is bound to the \e %Scope
1054 /// provided. If omitted and \p{scope} is Scope::Global, then the
1055 /// counter is associated exclusively with the single <em>Log Statement</em> itself.
1056 /// @param scope The \e %Scope that the group or counter is bound to.
1057 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1058 /// this defaults to \c 1.
1059 /// If negative, the first and every "-quantity-th" statement is executed.
1060 void Once( const NString& domain , Verbosity verbosity,
1061 const Box& logables,
1062 const String& group,
1063 Scope scope= Scope::Global,
1064 int quantity= 1)
1065 {
1066 detail::LI::once( impl, domain, verbosity, logables, group, scope, quantity );
1067 }
1068
1069 /// Overloaded version of
1070 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1071 ///
1072 /// @param verbosity The verbosity of the <em>Log Statement</em> (if performed).
1073 /// @param logables The objects to log (Multiple objects may be provided within
1074 /// container class Boxes.)
1075 /// @param group The optional name of the statement group . If used, all statements that
1076 /// share the same group name are working on the same counter (according
1077 /// to the \p{scope}.)
1078 /// If omitted (or empty or nullptr), the counter is bound to the \e %Scope
1079 /// provided. If omitted and \p{scope} is Scope::Global, then the
1080 /// counter is associated exclusively with the single <em>Log Statement</em> itself.
1081 /// @param scope The \e %Scope that the group or counter is bound to.
1082 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1083 /// this defaults to \c 1.
1084 void Once( Verbosity verbosity, const Box& logables,
1085 const String& group,
1086 Scope scope,
1087 int quantity= 1)
1088 { detail::LI::once( impl, nullptr, verbosity, logables, group, scope, quantity ); }
1089
1090 /// Overloaded version of
1091 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1092 ///
1093 /// @param verbosity The verbosity of the <em>Log Statement</em> (if performed).
1094 /// @param logables The objects to log (Multiple objects may be provided within
1095 /// container class Boxes.)
1096 /// @param group The optional name of the statement group . If used, all statements that
1097 /// share the same group name are working on the same counter (according
1098 /// to the \p{scope}.)
1099 /// If omitted (or empty or nullptr), the counter is bound to the \e %Scope
1100 /// provided. If omitted and \p{scope} is Scope::Global, then the
1101 /// counter is associated exclusively with the single <em>Log Statement</em> itself.
1102 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1103 /// this defaults to \c 1.
1104 void Once( Verbosity verbosity, const Box& logables,
1105 const String& group,
1106 int quantity= 1)
1107 { detail::LI::once( impl, nullptr, verbosity, logables, group, Scope::Global, quantity ); }
1108
1109 /// Overloaded version of
1110 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1111 ///
1112 /// @param verbosity The verbosity of the <em>Log Statement</em> (if performed).
1113 /// @param logables The objects to log (Multiple objects may be provided within
1114 /// container class Boxes.)
1115 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1116 /// this defaults to \c 1.
1117 void Once( Verbosity verbosity, const Box& logables,
1118 int quantity= 1)
1119 { detail::LI::once( impl, nullptr, verbosity, logables, nullptr, Scope::Global, quantity); }
1120
1121 /// Overloaded version of
1122 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1123 ///
1124 /// @param logables The objects to log (Multiple objects may be provided within
1125 /// container class Boxes.)
1126 /// @param group The optional name of the statement group . If used, all statements that
1127 /// share the same group name are working on the same counter (according
1128 /// to the \p{scope}.)
1129 /// If omitted (or empty or nullptr), the counter is bound to the \e %Scope
1130 /// provided. If omitted and \p{scope} is Scope::Global, then the
1131 /// counter is associated exclusively with the single <em>Log Statement</em> itself.
1132 /// @param scope The \e %Scope that the group or counter is bound to.
1133 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1134 /// this defaults to \c 1.
1135 void Once( const Box& logables,
1136 const String& group,
1137 Scope scope,
1138 int quantity= 1)
1139 { detail::LI::once( impl, nullptr, Verbosity::Info, logables, group, scope, quantity ); }
1140
1141 /// Overloaded version of
1142 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1143 ///
1144 /// @param domain Optional <em>Log Domain</em> which is combined with <em>%Scope Domains</em>
1145 /// set for the \e %Scope of invocation.
1146 /// @param verbosity The verbosity of the <em>Log Statement</em> (if performed).
1147 /// @param logables The objects to log (Multiple objects may be provided within
1148 /// container class Boxes.)
1149 /// @param scope The \e %Scope that the group or counter is bound to.
1150 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1151 /// this defaults to \c 1.
1152 void Once( const NString& domain, Verbosity verbosity, const Box& logables,
1153 Scope scope= Scope::Global ,
1154 int quantity= 1)
1155 { detail::LI::once( impl, domain, verbosity, logables, nullptr, scope, quantity ); }
1156
1157 /// Overloaded version of
1158 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1159 ///
1160 /// @param verbosity The verbosity of the <em>Log Statement</em> (if performed).
1161 /// @param logables The objects to log (Multiple objects may be provided within
1162 /// container class Boxes.)
1163 /// @param scope The \e %Scope that the group or counter is bound to.
1164 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1165 /// this defaults to \c 1.
1166 void Once( Verbosity verbosity, const Box& logables,
1167 Scope scope,
1168 int quantity= 1)
1169 { detail::LI::once( impl, nullptr, verbosity, logables, nullptr, scope, quantity ); }
1170
1171 /// Overloaded version of
1172 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1173 ///
1174 /// @param logables The objects to log (Multiple objects may be provided within
1175 /// container class Boxes.)
1176 /// @param scope The \e %Scope that the group or counter is bound to.
1177 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1178 /// this defaults to \c 1.
1179 void Once( const Box& logables,
1180 Scope scope,
1181 int quantity= 1)
1182 { detail::LI::once( impl, nullptr, Verbosity::Info, logables, nullptr, scope, quantity ); }
1183
1184 /// Overloaded version of
1185 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1186 ///
1187 /// @param logables The objects to log (Multiple objects may be provided within
1188 /// container class Boxes.)
1189 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1190 /// this defaults to \c 1.
1191 void Once( const Box& logables,
1192 int quantity= 1) {
1193 detail::LI::once( impl, nullptr, Verbosity::Info, logables, nullptr, Scope::Global,
1194 quantity );
1195 }
1196
1197 /// Overloaded version of
1198 /// \ref Once(const NString&,Verbosity,const Box&,const String&,Scope,int) "Once".
1199 ///
1200 /// @param logables The objects to log (Multiple objects may be provided within
1201 /// container class Boxes.)
1202 /// @param group The optional name of the statement group . If used, all statements that
1203 /// share the same group name are working on the same counter (according
1204 /// to the \p{scope}.)
1205 /// If omitted (or empty or nullptr), the counter is bound to the \e %Scope
1206 /// provided. If omitted and \p{scope} is Scope::Global, then the
1207 /// counter is associated exclusively with the single <em>Log Statement</em>
1208 /// itself.
1209 /// @param quantity The number of logs to be performed. As the name of the method indicates,
1210 /// this defaults to \c 1.
1211 void Once( const Box& logables,
1212 const String& group, int quantity= 1 ) {
1213 detail::LI::once( impl, nullptr, Verbosity::Info, logables, group, Scope::Global,
1214 quantity );
1215 }
1216
1217 /// Returns the number of loggers attached, which are active in respect to the given
1218 /// combination of verbosity and log domain.
1219 ///
1220 /// This method may be used to avoid the execution of more complex logging code when such
1221 /// logging would not result in log activity due to the current log level settings.
1222 ///
1223 /// @param verbosity The verbosity to query for activity.
1224 /// @param domain The log domain. All rules for resolving the effective log
1225 /// domain apply as with normal log statements.<br>
1226 /// Defaults to \b NULL_NSTRING.
1227 /// @param[out] resultDomain If given, the resulting domain is copied to this string.
1228 /// The resulting domain is that domain which is evaluated by
1229 /// \alox from the optional \p{domain} and all rules that apply
1230 /// at the place of invocation.
1231 /// @return The number of active loggers.
1232 int IsActive( Verbosity verbosity, const NString& domain = NULL_NSTRING,
1233 NAString* resultDomain= nullptr )
1234 { return detail::LI::IsActive( impl, verbosity, domain, resultDomain ); }
1235
1236 //################################################################################################
1237 // Debug methods
1238 //################################################################################################
1239 #if ALIB_DEBUG_MEMORY
1240 //==========================================================================================
1241 /// Returns the internal \b MonoAllocator used for storing permanent data.
1242 ///
1243 /// \par Availability
1244 /// This method is available only with debug-builds with \ref ALIB_DEBUG_MEMORY set.
1245 ///
1246 /// @return The monotonic allocator of this \b Lox.
1247 //==========================================================================================
1252 #endif
1253
1254}; // class Lox
1255
1256namespace detail {
1257/// Internal lox management.
1258/// @return The current number of loxes
1260
1261/// Internal lox management.
1263}
1264
1265} // namespace alib[::lox]
1266
1267/// Type alias in namespace \b alib.
1269
1270} // namespace [alib]
1271
TBoxes & Add()
Definition boxes.inl:55
This class acts as a container for Loggers and provides a convenient interface to logging.
Definition lox.inl:14
void Once(Verbosity verbosity, const Box &logables, const String &group, Scope scope, int quantity=1)
Definition lox.inl:1084
void SetPrefix(const Box &prefix, const NString &domain=nullptr, lang::Inclusion otherPLs=lang::Inclusion::Include)
Definition lox.inl:619
detail::Logger * GetLogger(const NString &loggerName)
Definition lox.inl:266
void EntryDetectDomain(Verbosity verbosity, BoxedObjects &&... logables)
Definition lox.inl:853
void Once(Verbosity verbosity, const Box &logables, Scope scope, int quantity=1)
Definition lox.inl:1166
void Entry(const NString &domain, Verbosity verbosity)
Definition lox.inl:825
ALIB_DLL ~Lox()
Destructs a lox.
Definition alox.cpp:136
void SetVerbosity(detail::Logger *logger, Verbosity verbosity, const NString &domain="/", Priority priority=Priority::Standard)
Definition lox.inl:348
integer & GetLogCounter()
Definition lox.inl:130
void Verbose(BoxedObjects &&... logables)
Definition lox.inl:871
void MapThreadName(const String &threadName, threads::ThreadID id=0)
Definition lox.inl:684
ALIB_DLL Lox(const NString &name, bool doRegister=true)
Definition alox.cpp:129
void Once(const Box &logables, Scope scope, int quantity=1)
Definition lox.inl:1179
void ClearSourcePathTrimRules(lang::Reach reach=lang::Reach::Global, bool allowAutoRule=true)
Definition lox.inl:235
void Once(const NString &domain, Verbosity verbosity, const Box &logables, Scope scope=Scope::Global, int quantity=1)
Definition lox.inl:1152
void SetDomainSubstitutionRule(const NString &domainPath, const NString &replacement)
Definition lox.inl:478
void Once(const Box &logables, const String &group, Scope scope, int quantity=1)
Definition lox.inl:1135
void RemoveThreadDomain(const NString &scopeDomain, Scope scope, threads::Thread *thread=nullptr)
Definition lox.inl:502
void Error(BoxedObjects &&... logables)
Definition lox.inl:925
void If(bool condition, const NString &domain, Verbosity verbosity, BoxedObjects &&... logables)
Definition lox.inl:964
detail::LoxImpl * impl
The implementation.
Definition lox.inl:22
static ALIB_DLL textlogger::TextLogger * CreateConsoleLogger(const NString &name=nullptr)
Definition alox.cpp:147
void Reset()
Definition lox.inl:147
static constexpr NString InternalDomains
Definition lox.inl:46
void If(bool condition, Verbosity verbosity, BoxedObjects &&... logables)
Definition lox.inl:991
void Once(Verbosity verbosity, const Box &logables, const String &group, int quantity=1)
Definition lox.inl:1104
void SetDomain(const NString &scopeDomain, Scope scope, threads::Thread *thread)
Definition lox.inl:418
void Acquire(const lang::CallerInfo &ci)
Definition lox.inl:134
void Warning(BoxedObjects &&... logables)
Definition lox.inl:907
void Once(const Box &logables, const String &group, int quantity=1)
Definition lox.inl:1211
void Store(const Box &data, const NString &key, Scope scope=Scope::Global)
Definition lox.inl:713
void SetSourcePathTrimRule(const NCString &path, lang::Inclusion includeString=lang::Inclusion::Exclude, int trimOffset=0, lang::Case sensitivity=lang::Case::Ignore, const NString &trimReplacement=NULL_NSTRING, lang::Reach reach=lang::Reach::Global, Priority priority=Priority::Standard)
Definition lox.inl:210
ALIB_DLL Box Retrieve(Scope scope=Scope::Global)
Definition lox.inl:755
void SetStartTime(const FILETIME &startTime, const NString &loggerName=nullptr)
Definition lox.inl:668
const NString & GetName()
Definition lox.inl:119
void SetPrefix(const Box &prefix, Scope scope)
Definition lox.inl:566
void Info(BoxedObjects &&... logables)
Definition lox.inl:889
void GetState(NAString &buf, StateInfo flags=StateInfo::All)
Definition lox.inl:790
void Once(const Box &logables, int quantity=1)
Definition lox.inl:1191
int IsActive(Verbosity verbosity, const NString &domain=NULL_NSTRING, NAString *resultDomain=nullptr)
Definition lox.inl:1232
static ALIB_DLL void Register(Lox *lox, lang::ContainerOp operation)
Definition alox.cpp:97
void SetDomain(const NString &scopeDomain, Scope scope)
Definition lox.inl:402
detail::Logger * RemoveLogger(const NString &loggerName)
Definition lox.inl:288
void SetStartTime(time_t startTime, const NString &loggerName=nullptr)
Definition lox.inl:651
void SetVerbosity(const NString &loggerName, Verbosity verbosity, const NString &domain="/", Priority priority=Priority::Standard)
Definition lox.inl:369
void State(const NString &domain, Verbosity verbosity, const String &headLine, StateInfo flags=StateInfo::All)
Definition lox.inl:773
BoxesMA & GetLogableContainer()
Definition lox.inl:807
void Assert(bool condition, BoxedObjects &&... logables)
Definition lox.inl:945
void Once(const NString &domain, Verbosity verbosity, const Box &logables, const String &group, Scope scope=Scope::Global, int quantity=1)
Definition lox.inl:1060
ALIB_DLL Box Retrieve(const NString &key, Scope scope=Scope::Global)
Definition lox.inl:744
void SetFileNameCacheCapacity(integer numberOfLists, integer entriesPerList)
Definition lox.inl:153
MonoAllocator & DbgGetMonoAllocator()
Definition lox.inl:1248
void Release()
Definition lox.inl:138
void Store(const Box &data, Scope scope=Scope::Global)
Definition lox.inl:722
static ALIB_DLL Lox * Get(const NString &name, lang::CreateIfNotExists create=lang::CreateIfNotExists::No)
Definition alox.cpp:77
void Once(Verbosity verbosity, const Box &logables, int quantity=1)
Definition lox.inl:1117
void SetStartTime(Ticks startTime=time::Ticks(), const NString &loggerName=nullptr)
Definition lox.inl:638
void SetPrefix(const Box &prefix, Scope scope, threads::Thread *thread)
Definition lox.inl:581
bool RemoveLogger(detail::Logger *logger)
Definition lox.inl:277
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
#define ALIB_EXPORT
Definition alib.inl:497
Reach
Denotes the reach of something.
@ Global
Denotes global reach.
ContainerOp
Denotes standard container operations.
CreateIfNotExists
Denotes whether something should be created if it does not exist.
Case
Denotes upper and lower case character treatment.
Inclusion
Denotes how members of a set something should be taken into account.
@ Exclude
Chooses exclusion.
@ Include
Chooses inclusion.
void shutdownLoxes()
Internal lox management.
integer dbgCountLoxes()
@ All
All flags set.
integer ThreadID
The ALib thread identifier type.
Definition thread.inl:23
constexpr NString NULL_NSTRING
A nulled string of the narrow character type.
Definition string.inl:2280
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2198
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
strings::TCString< nchar > NCString
Type alias in namespace alib.
Definition cstring.inl:484
alib::variables::Priority Priority
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1149
lox::Lox Lox
Type alias in namespace alib.
Definition lox.inl:1268
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace alib.
Definition boxes.inl:193
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
time::Ticks Ticks
Type alias in namespace alib.
Definition ticks.inl:79
static ALIB_DLL void SetFileNameCacheCapacity(LoxImpl *impl, integer numberOfLists, integer entriesPerList)
static ALIB_DLL void entryDetectDomainImpl(LoxImpl *impl, Verbosity verbosity)
static ALIB_DLL void MapThreadName(LoxImpl *impl, const String &threadName, threads::ThreadID id)
static ALIB_DLL void once(LoxImpl *impl, const NString &domain, Verbosity verbosity, const Box &logables, const String &pGroup, Scope scope, int quantity)
static ALIB_DLL const NString & GetName(LoxImpl *impl)
static ALIB_DLL void Release(LoxImpl *impl)
static ALIB_DLL void SetSourcePathTrimRule(LoxImpl *impl, const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priority priority)
static ALIB_DLL void GetState(LoxImpl *impl, NAString &buf, StateInfo flags)
static ALIB_DLL void IncreaseLogCounter(LoxImpl *impl)
static ALIB_DLL integer & GetLogCounter(LoxImpl *impl)
static ALIB_DLL BoxesMA & GetLogableContainer(LoxImpl *impl)
static ALIB_DLL void Acquire(LoxImpl *impl, const lang::CallerInfo &ci)
static ALIB_DLL void SetVerbosity(LoxImpl *impl, detail::Logger *logger, Verbosity verbosity, const NString &domain, Priority priority)
static ALIB_DLL void SetPrefix(LoxImpl *impl, const Box &prefix, const NString &domain, lang::Inclusion otherPLs)
static ALIB_DLL Box retrieve(LoxImpl *impl, const NString &pKey, Scope scope)
static ALIB_DLL void setPrefix(LoxImpl *impl, const Box &prefix, Scope scope, threads::Thread *thread)
static ALIB_DLL void store(LoxImpl *impl, const Box &data, const NString &pKey, Scope scope)
static ALIB_DLL bool RemoveLogger(LoxImpl *impl, detail::Logger *logger)
static ALIB_DLL void SetStartTime(LoxImpl *impl, Ticks startTime, const NString &loggerName)
ALIB_DLL void Reset()
static ALIB_DLL void setDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, bool removeNTRSD, threads::Thread *thread)
static ALIB_DLL int IsActive(LoxImpl *impl, Verbosity verbosity, const NString &domain, NAString *resultDomain)
static ALIB_DLL void Entry(LoxImpl *impl, const NString &domain, Verbosity verbosity)
static ALIB_DLL void RemoveThreadDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, threads::Thread *thread)
static ALIB_DLL void State(LoxImpl *impl, const NString &domain, Verbosity verbosity, const String &headLine, StateInfo flags)
static ALIB_DLL void SetDomainSubstitutionRule(LoxImpl *impl, const NString &domainPath, const NString &replacement)
static ALIB_DLL MonoAllocator & DbgGetMonoAllocator(LoxImpl *impl)
static ALIB_DLL detail::Logger * GetLogger(LoxImpl *impl, const NString &loggerName)