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