ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
textlogger.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 namespaces defines class \b TextLogger and its helpers.
12//==================================================================================================
13namespace textlogger {
14
15//==================================================================================================
16/// This abstract class represents a plug-in for the TextLogger class which converts the list
17/// of logables into a textual representation.
18/// \see StandardConverter for further information.
19//==================================================================================================
21{
22 public:
23 //==========================================================================================
24 /// Destructs an object of this class.
25 //==========================================================================================
26 virtual ~ObjectConverter() {}
27
28 //==========================================================================================
29 /// The conversion method.
30 /// @param target An AString that takes the result.
31 /// @param logables The objects to convert.
32 //==========================================================================================
33 virtual void ConvertObjects( AString& target, BoxesMA& logables ) =0;
34
35 //==========================================================================================
36 /// If this converter uses an \alib{strings::util;AutoSizes} object, this method passes
37 /// an external object to use.
38 /// @param autoSizes The instance to use.
39 //==========================================================================================
41 virtual void SetAutoSizes( AutoSizes* autoSizes ) =0;
42
43 //==========================================================================================
44 /// If this converter uses an \alib{strings::util;AutoSizes} object, this method returns
45 /// such object.
46 /// @return The auto sizes used, \c nullptr if not applicable.
47 //==========================================================================================
48 virtual AutoSizes* GetAutoSizes() =0;
49
50 //==========================================================================================
51 /// If this converter uses an \alib{strings::util;AutoSizes} object, values of this field
52 /// are reset.
53 //==========================================================================================
54 virtual void ResetAutoSizes() =0;
55};
56
57//==================================================================================================
58/// Implements the interface
59/// \ref alib::lox::textlogger::ObjectConverter "ObjectConverter". Class
60/// \ref alib::lox::textlogger::TextLogger "TextLogger" creates an instance of this type in
61/// the moment no other (custom) type was set before the first log statement.
62///
63/// This implementation uses
64/// two specialisations of class
65/// \alib{format;Formatter} to format the given logables to a textual
66/// representation. The formatters (and their sequence!) are:
67///
68/// 1. \alib{format;FormatterPythonStyle;FormatterPythonStyle}
69/// 2. \alib{format;FormatterJavaStyle;FormatterJavaStyle}
70///
71/// This way, standard text logging supports format strings in Python style as well as in Java style.
72//==================================================================================================
74{
75 public:
76 /// A list of formatters used to "convert" logables to strings.
77 /// By default, each entry contains a concatenated pair of formatters of types
78 /// \alib{format;FormatterPythonStyle;FormatterPythonStyle} and
79 /// \alib{format;FormatterJavaStyle;FormatterJavaStyle} are added in the
80 /// constructor of this class.
81 ///
82 /// A vector of formatters is needed to support recursive log calls.
83 /// If recursion occurs during logging (aka the conversion of a logable triggers another
84 /// logging operation), necessary formatters are created on the fly, respectively re-used
85 /// from previous recursions.
86 /// Their settings are cloned to those of the main formatters
87 /// using \alib{format;Formatter::CloneSettings}.
88 ///
89 /// To use different formatters, it is recommended to implement a different converter
90 /// type, instead of "patching" the linked and recursive formatters found in this vector.
91 std::vector<Formatter*> Formatters;
92
93 protected:
94 /// A counter to detect recursive calls.
96
97 public:
98
99 //==========================================================================================
100 /// Constructor.
101 //==========================================================================================
104
105 //==========================================================================================
106 /// Virtual destructor.
107 //==========================================================================================
109 virtual ~StandardConverter() override;
110
111 //==========================================================================================
112 /// The conversion method.
113 /// Passes \p{target} and \p{logables} to the #Formatters.
114 /// @param target An AString that takes the result.
115 /// @param logables The objects to convert.
116 //==========================================================================================
118 virtual void ConvertObjects( AString& target, BoxesMA& logables ) override;
119
120 //==========================================================================================
121 /// Checks if the first formatter in #Formatters is of type
122 /// \alib{format;FormatterPythonStyle}. If so, its \b AutoSizes member is set to
123 /// the given external instance. Otherwise the call is ignored.
124 /// @param autoSizes The instance to use.
125 //==========================================================================================
127 virtual void SetAutoSizes( AutoSizes* autoSizes ) override;
128
129 //==========================================================================================
130 /// Checks if the first formatter in #Formatters is of type
131 /// \alib{format;FormatterPythonStyle}. If so, its \b AutoSizes member is returned.
132 /// If not, the method returns \c nullptr.
133 /// @return The auto sizes object of the main formatter.
134 //==========================================================================================
136 virtual AutoSizes* GetAutoSizes() override;
137
138 //==========================================================================================
139 /// Resets automatically widened tab stops and field widths of this converter.
140 //==========================================================================================
142 virtual void ResetAutoSizes() override;
143}; //class StandardConverter
144
145
146//==================================================================================================
147/// This class is a still abstract implementation of class Logger which is used as a base
148/// for all textual Logger implementations within \alox, e.g., \b %ConsoleLogger.
149///
150/// One main purpose of the class is to generate the textual representation of the meta-information
151/// of a log call. The final log message is then passed to the abstract method #logText.
152/// Hence, types that inherited from this class instead of directly from class
153/// \alib{lox;detail::Logger}, need to implement #logText instead of implementing #Log.
154///
155/// Class \b %TextLogger supports multi line log outputs. Such multi line log outputs can be
156/// configured to be logged in different ways. See struct \alib{lox::textlogger;FormatMultiLine} for more
157/// information.
158//==================================================================================================
159class TextLogger : public Logger
160{
161
162 // ###############################################################################################
163 // Internal fields
164 // ###############################################################################################
165 protected:
166
167 /// The internal log Buffer.
169
170 /// The buffers for converting the logables.
172
173 /// Denotes whether this logger writes to the <em>standard output streams</em>. If so,
174 /// \alib{threads;STD_IOSTREAMS_LOCK} is acquired with writing.
176
177 /// Variable of type \alib{lox::textlogger;FormatMetaInfo} residing in the
178 /// \alib{variables;Configuration} of camp \alib_alox.
180
181 /// Variable of type \alib{lox::textlogger;FormatDateTime} residing in the
182 /// \alib{variables;Configuration} of camp \alib_alox.
184
185 /// Variable of type \alib{lox::textlogger;FormatTimeDiff} residing in the
186 /// \alib{variables;Configuration} of camp \alib_alox.
188
189 /// Variable of type \alib{lox::textlogger;FormatMultiLine} residing in the
190 /// \alib{variables;Configuration} of camp \alib_alox.
192
193 /// Variable of type \alib{lox::textlogger;FormatOther} residing in the
194 /// \alib{variables;Configuration} of camp \alib_alox.
196
197 /// Variable of type \alib{lox::textlogger;FormatAutoSizes}, which inherits class
198 /// \alib{strings::util;AutoSizes}.The sizes are used for auto tab positions and field sizes.
199 /// For each requested value, a corresponding array field is created on the fly.
200 /// If the format string get's changed and different (new) auto values should be used, then
201 /// this field should be reset after setting the new format string.
202 /// The other way round, it is also possible to preset set minimum values for tabs and field
203 /// sizes and hence avoid the columns growing during the lifetime of the Logger.
204 ///
205 /// The second member of type \b AutoSizes is attached to field #Converter
206 /// when this \b %TextLogger is attached to a \b %Lox.
207 ///
208 /// This field will be read from configuration variable \ref alxcvALOX_LOGGERNAME_AUTO_SIZES
210
211 /// A list of pairs of strings. Within each log message, the first string of a pair is
212 /// searched and replaced by the second string. Very simple, but useful in some cases.
214
215
216 /// A singleton calendar time object shared between different format variables during one
217 /// invocation.
219
220
221 // ###############################################################################################
222 // Public fields
223 // ###############################################################################################
224 public:
225 /// A helper object to get textual representation of logable objects.
226 /// If no converter is set when this logger is attached to a lox, a converter of type
227 /// \alib{lox::textlogger;StandardConverter} is created and used.
228 /// Custom loggers might create their own, custom converter objects here.
229 /// In the destructor of this class, the current object converter will be deleted.
230 ///
231 /// To extend class \b %TextLogger to support logging custom objects, custom converters can
232 /// set. The preferred alternative is however, to make custom types be formattable
233 /// by formatter classes used with \b %StandardConverter.
235
236 /// This field is used to convert the steady and monotonic clock values provided with
237 /// \alox{detail,ScopeInfo::GetTimeStamp} into human-readable, calendrical values in the case
238 /// that field #varFormatMetaInfo contains tokens <c>%%TD</c> and/or <c>%%TT</c>.
239 ///
240 /// This may become problematic and ambiguous if the system clock is changed during a
241 /// software run. Especially for long-running background software (daemons, servers, etc.),
242 /// the software that uses \alox needs to provide a strategy of synchronizing this converter
243 /// with the system clock.
244 ///
245 /// A simple strategy is to just periodically invoke \alib{time;TickConverter::SyncClocks},
246 /// for example once a second.
247 ///
248 /// For some explanation of the problem see details of namespace #alib::time.
250
251 /// If \c false, an one-time warning (using \ref ALIB_WARNING) will be issued if the format
252 /// string is illegal. With each warning, the flag is set to \c true to omit further
253 /// warnings.
254 bool FormatWarningOnce= false;
255
256 /// Provides access to the value of the internal configuration variable #varFormatMetaInfo.<br>
257 /// This variable is declared only after the logger was added to a \b %Lox.
258 /// @return The struct containing formatting information.
260
261 /// Provides access to the value of the internal configuration variable #varFormatDateTime.<br>
262 /// This variable is declared only after the logger was added to a \b %Lox.
263 /// @return The struct containing formatting information.
265
266 /// Provides access to the value of the internal configuration variable #varFormatTimeDiff.<br>
267 /// This variable is declared only after the logger was added to a \b %Lox.
268 /// @return The struct containing formatting information.
270
271 /// Provides access to the value of the internal configuration variable #varFormatMultiLine.<br>
272 /// This variable is declared only after the logger was added to a \b %Lox.
273 /// @return The struct containing formatting information.
275
276 /// Provides access to the value of the internal configuration variable #varFormatOther.<br>
277 /// This variable is declared only after the logger was added to a \b %Lox.
278 /// @return The struct containing formatting information.
280
281 /// Provides access to the value of the internal configuration variable #varFormatAutoSizes.<br>
282 /// This variable is declared only after the logger was added to a \b %Lox.
283 /// @return The struct containing the \alib{strings::util;AutoSizes} instances for the
284 /// meta-information of the log message and for the log message itself.
286
287 /// Provides access to the value of the internal configuration variable #varReplacements.<br>
288 /// This variable is declared only after the logger was added to a \b %Lox.
289 /// @return The \alib{lox::textlogger;Replacements} instance for the logger in question.
291
292
293 // ###############################################################################################
294 // protected Constructor/ public destructor
295 // ###############################################################################################
296 protected:
297 //==============================================================================================
298 /// Constructs a TextLogger.
299 /// @param pName The name of the \e Logger.
300 /// @param typeName The type of the \e Logger.
301 /// @param pUsesStdStreams Denotes whether this logger writes to the
302 /// <em>standard output streams</em>.
303 //==============================================================================================
304 ALIB_DLL explicit TextLogger( const NString& pName, const NString& typeName,
305 bool pUsesStdStreams );
306
307 // ###############################################################################################
308 // protected methods
309 // ###############################################################################################
310 //==============================================================================================
311 /// Parses the format string in the field #varFormatMetaInfo and logs meta-information into
312 /// the log buffer.
313 /// For each variable found, the method #processVariable is invoked.
314 /// Hence, to add new variables, the latter method can be overwritten by descendants.
315 /// Overwriting this method is recommended for formatter classes that do not rely on format
316 /// strings.
317 /// @param buffer The buffer to write meta-information into.
318 /// @param domain The <em>Log Domain</em>.
319 /// @param verbosity The verbosity.
320 /// @param scope Information about the scope of the <em>Log Statement</em>..
321 //==============================================================================================
323 virtual void writeMetaInfo( AString& buffer,
324 detail::Domain& domain,
325 Verbosity verbosity,
326 detail::ScopeInfo& scope );
327
328 //==============================================================================================
329 /// Processes the next command found in the format string, by writing formatted information
330 /// into the given buffer.
331 /// The given
332 /// \alib{strings;TSubstring;Substring} holds the next command.
333 /// When the method returns, the command is cut from the front.
334 ///
335 /// @param domainPath The <em>Log Domain</em> full path.
336 /// @param verbosity The verbosity. This has been checked to be active already on this
337 /// stage and is provided to be able to be logged out only.
338 /// @param scope Information about the scope of the <em>Log Statement</em>..
339 /// @param dest The buffer to write meta-information into.
340 /// @param variable The variable to read (may have more characters appended)
341 //==============================================================================================
343 virtual void processVariable( const NString& domainPath,
344 Verbosity verbosity,
345 detail::ScopeInfo& scope,
346 AString& dest,
347 Substring& variable );
348
349 //==============================================================================================
350 /// Helper function that logs a time given difference into the given buffer in a human-readable
351 /// format. Works from nanoseconds seconds to days.
352 ///
353 /// @param buffer The buffer to write the time difference representation into.
354 /// @param diffNanos The time difference to write in nanoseconds.
355 //==============================================================================================
357 virtual void writeTimeDiff ( AString& buffer, int64_t diffNanos );
358
359
360 public:
361 //==============================================================================================
362 /// Destructs a TextLogger.
363 //==============================================================================================
364 ALIB_DLL virtual ~TextLogger() override;
365
366 // ###############################################################################################
367 // Overriding parent's virtual, empty method AcknowledgeLox()
368 // ###############################################################################################
369
370 //==============================================================================================
371 /// Configuration variables are read within this method and created with
372 /// default values, in the case they do not exist, yet. The variables read are:
373 /// - \b alxcvALOX_LOGGERNAME_AUTO_SIZES
374 /// - \b alxcvALOX_LOGGERNAME_FORMAT
375 /// - \b alxcvALOX_LOGGERNAME_FORMAT_DATE_TIME
376 /// - \b alxcvALOX_LOGGERNAME_FORMAT_TIME_DIFF
377 /// - \b alxcvALOX_LOGGERNAME_FORMAT_MULTILINE
378 /// - \b alxcvALOX_LOGGERNAME_FORMAT_OTHER
379 /// - \b alxcvALOX_LOGGERNAME_REPLACEMENTS
380 ///
381 /// Configuration variables are \ref alib_alox_cfgvars "documented here".
382 ///
383 /// @param lox The \b %Lox to acknowledge insertion or removal
384 /// @param op The operation. Either \b ContainerOp::Insert or \b ContainerOp::Remove.
385 //==============================================================================================
387 virtual void AcknowledgeLox( detail::LoxImpl* lox, lang::ContainerOp op ) override;
388
389
390 // ###############################################################################################
391 // Abstract methods introduced
392 // ###############################################################################################
393 protected:
394 //==============================================================================================
395 /// This abstract method introduced by this class "replaces" the abstract method #Log
396 /// of parent class Logger which this class implements. In other words, descendants of this
397 /// class need to override this method instead of \b %Log. This class %TextLogger is
398 /// responsible for generating meta-information, doing text replacements, handle multi-line
399 /// messages, etc. and provides the textual representation of the whole log contents
400 /// to descendants using this method.
401 ///
402 /// @param domain The <em>Log Domain</em>.
403 /// @param verbosity The verbosity. This has been checked to be active already on this
404 /// stage and is provided to be able to be logged out only.
405 /// @param msg The log message.
406 /// @param scope Information about the scope of the <em>Log Statement</em>.
407 /// @param lineNumber The line number of a multi-line message, starting with 0.
408 /// For single line messages this is -1.
409 //==============================================================================================
410 virtual void logText( detail::Domain& domain,
411 Verbosity verbosity,
412 AString& msg,
413 detail::ScopeInfo& scope,
414 int lineNumber ) =0;
415
416 //==============================================================================================
417 /// Abstract method to be implemented by descendants. This message is called only when
418 /// multi-line messages are logged. It is called exactly once before a series of #logText
419 /// calls of a multi-line message and exactly once after such series.<br>
420 /// This is useful if the writing of text includes the acquisition of system resources
421 /// (e.g., opening a file).
422 ///
423 /// @param phase Indicates the beginning or end of a multi-line operation.
424 //==============================================================================================
425 virtual void notifyMultiLineOp( lang::Phase phase ) =0;
426
427 // ###############################################################################################
428 // Abstract method implementations
429 // ###############################################################################################
430 public:
431 //==============================================================================================
432 /// This is the implementation of the abstract method inherited from class Logger
433 /// that executes a log.<br>
434 /// This class implements this method and but exposes the new abstract method #logText.
435 /// This mechanism allows this class to do various things that are standard to Loggers
436 /// of type TextLogger. For example, meta-information of the log invocation is formatted
437 /// and string replacements are performed. This way, descendants of this class will consume
438 /// a ready to use log buffer with all meta-information and contents of all objects to be
439 /// included and their primary obligation is to copy the content into a corresponding
440 /// output stream.
441 ///
442 /// @param domain The <em>Log Domain</em>.
443 /// @param verbosity The verbosity.
444 /// @param logables The list of objects to log.
445 /// @param scope Information about the scope of the <em>Log Statement</em>..
446 //==============================================================================================
448 virtual void Log( detail::Domain& domain, Verbosity verbosity, BoxesMA& logables,
449 detail::ScopeInfo& scope) override;
450
451 // ###############################################################################################
452 // Public interface
453 // ###############################################################################################
454 public:
455 //==============================================================================================
456 /// Adds the given pair of replacement strings. If searched string already exists, the
457 /// current replacement string gets replaced. If the replacement string is \c nullptr,
458 /// nothing is set and a previously set replacement definition becomes unset.
459 /// @param searched The string to be searched.
460 /// @param replacement The replacement string. If this equals 'nullptr' a previously set
461 /// replacement will be unset.
462 //==============================================================================================
464 virtual void SetReplacement( const String& searched, const String& replacement );
465
466 //==============================================================================================
467 /// Removes all pairs of searched strings and their replacement value.
468 //==============================================================================================
470 virtual void ClearReplacements();
471
472 //==============================================================================================
473 /// Resets automatically widened tab stops and field widths of this logger by calling
474 /// \alib{lox::textlogger::StandardConverter;ResetAutoSizes} on field #Converter.
475 ///
476 /// \note The sizes affected are the ones used to format the custom log output, not
477 /// the ones uses for the meta-information. To reset the auto-sizes of the meta
478 /// information, invoke \alib{strings::util;AutoSizes::Reset} on field #AutoSizes.
479 //==============================================================================================
481 virtual void ResetAutoSizes();
482}; // class TextLogger
483
484}} // namespace alib[::lox::textlogger]
485
486/// Type alias in namespace \b alib.
488
489} // namespace [alib]
490
Logger(const NString &name, const NString &typeName)
Definition logger.inl:103
virtual void ConvertObjects(AString &target, BoxesMA &logables)=0
virtual ~ObjectConverter()
Destructs an object of this class.
virtual ALIB_DLL void SetAutoSizes(AutoSizes *autoSizes)=0
virtual AutoSizes * GetAutoSizes()=0
virtual ALIB_DLL void SetAutoSizes(AutoSizes *autoSizes) override
ALIB_DLL StandardConverter()
Constructor.
virtual ALIB_DLL void ConvertObjects(AString &target, BoxesMA &logables) override
virtual ALIB_DLL void ResetAutoSizes() override
Resets automatically widened tab stops and field widths of this converter.
virtual ALIB_DLL ~StandardConverter() override
Virtual destructor.
virtual ALIB_DLL AutoSizes * GetAutoSizes() override
std::vector< Formatter * > Formatters
int cntRecursion
A counter to detect recursive calls.
virtual ALIB_DLL void writeMetaInfo(AString &buffer, detail::Domain &domain, Verbosity verbosity, detail::ScopeInfo &scope)
virtual ALIB_DLL void AcknowledgeLox(detail::LoxImpl *lox, lang::ContainerOp op) override
FormatMultiLine & GetFormatMultiLine()
FormatTimeDiff & GetFormatTimeDiff()
virtual ALIB_DLL void SetReplacement(const String &searched, const String &replacement)
virtual ALIB_DLL ~TextLogger() override
Destructs a TextLogger.
virtual ALIB_DLL void processVariable(const NString &domainPath, Verbosity verbosity, detail::ScopeInfo &scope, AString &dest, Substring &variable)
virtual ALIB_DLL void ResetAutoSizes()
AString logBuf
The internal log Buffer.
virtual ALIB_DLL void writeTimeDiff(AString &buffer, int64_t diffNanos)
FormatMetaInfo & GetFormatMetaInfo()
AString msgBuf
The buffers for converting the logables.
virtual void logText(detail::Domain &domain, Verbosity verbosity, AString &msg, detail::ScopeInfo &scope, int lineNumber)=0
ALIB_DLL TextLogger(const NString &pName, const NString &typeName, bool pUsesStdStreams)
virtual ALIB_DLL void ClearReplacements()
Removes all pairs of searched strings and their replacement value.
strings::util::CalendarDateTime callerDateTime
virtual void notifyMultiLineOp(lang::Phase phase)=0
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_EXPORT
Definition alib.inl:488
ContainerOp
Denotes standard container operations.
Phase
Denotes a phase, e.g.,of a transaction.
This namespaces defines class TextLogger and its helpers.
Definition loxpimpl.inl:13
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
variables::Variable Variable
Type alias in namespace alib.
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2390
strings::util::AutoSizes AutoSizes
Type alias in namespace alib.
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace alib.
Definition boxes.inl:245
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
time::TickConverter TickConverter
Type alias in namespace alib.
strings::TSubstring< character > Substring
Type alias in namespace alib.
lox::textlogger::TextLogger TextLogger
Type alias in namespace alib.
lox::Log Log
Type alias in namespace alib.
Definition log.inl:118