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