KanoopCommonQt 2.1.1
Kanoop foundational Qt utility library
Loading...
Searching...
No Matches
log.h
1/******************************************************************************************
2**
3** log.h
4**
5** Consistent formatted logging with syslog integration.
6**
7** Moved from my Tesseract Engineering repo to open-source
8**
9** Author: Stephen Punak
10** Created: Wed Oct 4 13:25:38 2023
11**
12******************************************************************************************/
13#ifndef LOG_H
14#define LOG_H
15#include <QFile>
16#include <QMap>
17#include <QMutex>
18#include <QString>
19#include <QTextStream>
20#include "loggingtypes.h"
21#include <Kanoop/kanoopcommon.h>
22
23/** @brief Logging macro helpers — expand to file, line, and level arguments. */
24#define LVL_EMERGENCY __FILE__,__LINE__,Log::LogLevel::Emergency
25#define LVL_ALERT __FILE__,__LINE__,Log::LogLevel::Alert
26#define LVL_CRITICAL __FILE__,__LINE__,Log::LogLevel::Critical
27#define LVL_ERROR __FILE__,__LINE__,Log::LogLevel::Error
28#define LVL_WARNING __FILE__,__LINE__,Log::LogLevel::Warning
29#define LVL_NOTICE __FILE__,__LINE__,Log::LogLevel::Notice
30#define LVL_INFO __FILE__,__LINE__,Log::LogLevel::Info
31#define LVL_DEBUG __FILE__,__LINE__,Log::LogLevel::Debug
32
33
34class LogConsumer;
35
36/**
37 * @brief Logging subsystem providing categorized, level-filtered output.
38 */
39namespace Log
40{
41
42class LogCategoryPrivate;
43
44class LogCategory;
45
46/**
47 * @brief Core logger class supporting console, file, syslog, and consumer outputs.
48 *
49 * Logger is typically accessed through the module-level free functions (Log::logText, etc.)
50 * which delegate to a process-wide singleton returned by Log::systemLog().
51 */
52class KANOOP_EXPORT Logger
53{
54public:
55 /** @brief Default constructor — initializes an unopened logger at Debug level. */
57
58 /** @brief Open the log file or syslog connection as configured. */
59 void openLog();
60
61 /**
62 * @brief Rotate the log to a new file path.
63 * @param newFileName Path to the new log file
64 */
65 void rotateLog(const QString &newFileName);
66
67 /**
68 * @brief Write a text message to the log.
69 * @param file Source filename (use __FILE__)
70 * @param lineNumber Source line number (use __LINE__)
71 * @param level Severity level of this message
72 * @param text Message text to log
73 */
74 void logText(const char* file, int lineNumber, LogLevel level, const QString& text);
75
76 /**
77 * @brief Write a categorized text message to the log.
78 * @param file Source filename (use __FILE__)
79 * @param lineNumber Source line number (use __LINE__)
80 * @param level Severity level of this message
81 * @param category Log category for filtering
82 * @param text Message text to log
83 */
84 void logText(const char* file, int lineNumber, LogLevel level, const LogCategory& category, const QString& text);
85
86 /**
87 * @brief Write a hex dump of a byte array to the log.
88 * @param file Source filename (use __FILE__)
89 * @param lineNumber Source line number (use __LINE__)
90 * @param level Severity level of this message
91 * @param data Bytes to dump
92 * @param tag Optional label prepended to the dump
93 */
94 void logHex(const char* file, int lineNumber, LogLevel level, const QByteArray& data, const QString& tag = QString());
95
96 /**
97 * @brief Write a categorized hex dump to the log.
98 * @param file Source filename (use __FILE__)
99 * @param lineNumber Source line number (use __LINE__)
100 * @param level Severity level of this message
101 * @param category Log category for filtering
102 * @param data Bytes to dump
103 * @param tag Optional label prepended to the dump
104 */
105 void logHex(const char* file, int lineNumber, LogLevel level, const LogCategory& category, const QByteArray& data, const QString& tag = QString());
106
107 /**
108 * @brief Return the current minimum log level.
109 * @return Active LogLevel threshold
110 */
111 LogLevel level() const { return _level; }
112
113 /**
114 * @brief Set the minimum log level; messages below this level are discarded.
115 * @param value New LogLevel threshold
116 */
117 void setLevel(LogLevel value) { _level = value; }
118
119 /**
120 * @brief Return the active output flags.
121 * @return Bitmask of OutputFlags
122 */
123 OutputFlags flags() const { return _flags; }
124
125 /**
126 * @brief Set the output flags, replacing any existing flags.
127 * @param flags New OutputFlags bitmask
128 */
129 void setFlags(OutputFlags flags) { _flags = flags; }
130
131 /**
132 * @brief Enable additional output flags without clearing existing ones.
133 * @param flags Flags to enable
134 */
136
137 /**
138 * @brief Disable specific output flags without affecting others.
139 * @param flags Flags to disable
140 */
142
143 /**
144 * @brief Return the log file path.
145 * @return Path to the output log file
146 */
147 QString filename() const { return _filename; }
148
149 /**
150 * @brief Set the log file path and reopen the file.
151 * @param filename Path to the output log file
152 */
153 void setFilename(const QString& filename);
154
155 /**
156 * @brief Return the syslog identity string.
157 * @return Identity string used in syslog output
158 */
159 QString identity() const { return _identity; }
160
161 /**
162 * @brief Set the syslog identity string.
163 * @param value Identity string used in syslog output
164 */
165 void setIdentity(const QString& value);
166
167 /**
168 * @brief Register a new log category by name.
169 * @param name Category name string
170 * @return Registered LogCategory object
171 */
172 LogCategory registerCategory(const QString& name);
173
174 /**
175 * @brief Register an existing LogCategory object.
176 * @param category Category to register
177 * @return Registered LogCategory object
178 */
180
181 /**
182 * @brief Return all registered log categories.
183 * @return List of LogCategory objects
184 */
185 QList<LogCategory> categories() const;
186
187 /**
188 * @brief Override the log level for a specific category.
189 * @param name Category name
190 * @param level Level to apply to this category
191 */
192 void setCategoryLevel(const QString& name, LogLevel level);
193
194 /**
195 * @brief Add an external log consumer to receive log entries.
196 * @param consumer Consumer to add
197 */
198 void addConsumer(LogConsumer* consumer);
199
200 /**
201 * @brief Remove a previously added log consumer.
202 * @param consumer Consumer to remove
203 */
205
206 /**
207 * @brief Test whether the log is open and ready to write.
208 * @return true if the log is open
209 */
210 bool isLogOpen() const { return _logOpen; }
211
212private:
213 class CategoryIndex : public QMap<QString, LogCategoryPrivate*>
214 {
215 };
216
217 /** @brief Open the log file on disk. */
218 void openFile();
219 /** @brief Close the log file. */
220 void closeFile();
221
222 /** @brief Open the syslog connection. */
223 void openSyslog();
224 /** @brief Close the syslog connection. */
225 void closeSyslog();
226
227 /** @brief Route a formatted log message to all enabled output destinations. */
228 void outputToDestinations(LogLevel level, const LogCategory& category, const QDateTime& timestamp, const QString& formattedText, const QString& unformattedText);
229
230 /** @brief Convert raw bytes to a formatted hex string. */
231 static QString bufferToHex(const QByteArray& buffer);
232
233 LogLevel _level;
234 OutputFlags _flags;
235 QString _filename;
236 char _identity[512];
237
238 bool _logOpen;
239
240 QTextStream _stdout;
241 QTextStream _stderr;
242
243 QList<LogConsumer*> _surplusConsumers;
244
245 QFile _file;
246 QMutex _writeLock;
247
248 CategoryIndex _categories;
249
250 static const QList<QString> _LevelStrings;
251};
252
253/**
254 * @brief Write a text message via the system logger.
255 * @param file Source filename
256 * @param lineNumber Source line number
257 * @param level Severity level
258 * @param text Message text
259 */
260KANOOP_EXPORT void logText(const char* file, int lineNumber, LogLevel level, const QString& text);
261
262/**
263 * @brief Write a categorized text message via the system logger.
264 * @param file Source filename
265 * @param lineNumber Source line number
266 * @param level Severity level
267 * @param category Log category
268 * @param text Message text
269 */
270KANOOP_EXPORT void logText(const char* file, int lineNumber, LogLevel level, const LogCategory& category, const QString& text);
271
272/**
273 * @brief Write a categorized hex dump via the system logger.
274 * @param file Source filename
275 * @param lineNumber Source line number
276 * @param level Severity level
277 * @param category Log category
278 * @param data Bytes to dump
279 * @param tag Optional label
280 */
281KANOOP_EXPORT void logHex(const char* file, int lineNumber, LogLevel level, const LogCategory& category, const QByteArray& data, const QString& tag = QString());
282
283/**
284 * @brief Write a hex dump via the system logger.
285 * @param file Source filename
286 * @param lineNumber Source line number
287 * @param level Severity level
288 * @param data Bytes to dump
289 * @param tag Optional label
290 */
291KANOOP_EXPORT void logHex(const char* file, int lineNumber, LogLevel level, const QByteArray& data, const QString& tag = QString());
292
293/**
294 * @brief Return the process-wide Logger singleton.
295 * @return Pointer to the global Logger instance
296 */
297KANOOP_EXPORT Logger* systemLog();
298
299/**
300 * @brief Return the current minimum log level of the system logger.
301 * @return Active LogLevel threshold
302 */
303KANOOP_EXPORT LogLevel level();
304
305/**
306 * @brief Set the minimum log level of the system logger.
307 * @param value New LogLevel threshold
308 */
309KANOOP_EXPORT void setLevel(LogLevel value);
310
311/**
312 * @brief Return the output flags of the system logger.
313 * @return Active OutputFlags bitmask
314 */
315KANOOP_EXPORT OutputFlags flags();
316
317/**
318 * @brief Set the output flags of the system logger.
319 * @param flags New OutputFlags bitmask
320 */
321KANOOP_EXPORT void setFlags(OutputFlags flags);
322
323/**
324 * @brief Return the log file path of the system logger.
325 * @return Log file path string
326 */
327KANOOP_EXPORT QString filename();
328
329/**
330 * @brief Set the log file path of the system logger.
331 * @param filename Path to the log file
332 */
333KANOOP_EXPORT void setFilename(const QString& filename);
334
335/**
336 * @brief Return the syslog identity of the system logger.
337 * @return Syslog identity string
338 */
339KANOOP_EXPORT QString identity();
340
341/**
342 * @brief Set the syslog identity of the system logger.
343 * @param value Identity string
344 */
345KANOOP_EXPORT void setIdentity(const QString& value);
346
347/**
348 * @brief Enable additional output flags on the system logger.
349 * @param flags Flags to enable
350 */
352
353/**
354 * @brief Disable specific output flags on the system logger.
355 * @param flags Flags to disable
356 */
358
359/**
360 * @brief Register a log category by name with the system logger.
361 * @param name Category name
362 * @return Registered LogCategory
363 */
364KANOOP_EXPORT LogCategory registerCategory(const QString& name);
365
366/**
367 * @brief Register a log category by name and level with the system logger.
368 * @param name Category name
369 * @param level Level override for this category
370 * @return Registered LogCategory
371 */
372KANOOP_EXPORT LogCategory registerCategory(const QString &name, LogLevel level);
373
374/**
375 * @brief Return all categories registered with the system logger.
376 * @return List of LogCategory objects
377 */
378KANOOP_EXPORT QList<LogCategory> categories();
379
380/**
381 * @brief Override the log level for a named category on the system logger.
382 * @param name Category name
383 * @param level Level to apply
384 */
385KANOOP_EXPORT void setCategoryLevel(const QString& name, LogLevel level);
386
387/**
388 * @brief Add an external log consumer to the system logger.
389 * @param consumer Consumer to add
390 */
391KANOOP_EXPORT void addConsumer(LogConsumer* consumer);
392
393/**
394 * @brief Remove an external log consumer from the system logger.
395 * @param consumer Consumer to remove
396 */
397KANOOP_EXPORT void removeConsumer(LogConsumer* consumer);
398
399/**
400 * @brief Parse a log level name string into a LogLevel enum value.
401 * @param value String name (e.g. "debug", "error")
402 * @param parsed Optional output set to true if parsing succeeded
403 * @return Parsed LogLevel, or Debug as default on failure
404 */
405KANOOP_EXPORT LogLevel parseLevel(const QString& value, bool* parsed = nullptr);
406
407/**
408 * @brief Read the start timestamp from an existing log file.
409 * @param filename Path to the log file
410 * @return QDateTime of the first log entry, or invalid QDateTime on error
411 */
412KANOOP_EXPORT QDateTime getLogStartTime(const QString& filename);
413
414/**
415 * @brief Read the end timestamp from an existing log file.
416 * @param filename Path to the log file
417 * @return QDateTime of the last log entry, or invalid QDateTime on error
418 */
419KANOOP_EXPORT QDateTime getLogEndTime(const QString& filename);
420
421
422} // namespace log
423
424#endif // LOG_H
A QObject-based sink that receives log entries from the logging system.
Definition logconsumer.h:21
A named logging category with an associated minimum log level.
Definition logcategory.h:34
Core logger class supporting console, file, syslog, and consumer outputs.
Definition log.h:53
void logText(const char *file, int lineNumber, LogLevel level, const LogCategory &category, const QString &text)
Write a categorized text message to the log.
void openLog()
Open the log file or syslog connection as configured.
LogCategory registerCategory(const QString &name)
Register a new log category by name.
void disableOutputFlags(OutputFlags flags)
Disable specific output flags without affecting others.
void logHex(const char *file, int lineNumber, LogLevel level, const QByteArray &data, const QString &tag=QString())
Write a hex dump of a byte array to the log.
void enableOutputFlags(OutputFlags flags)
Enable additional output flags without clearing existing ones.
void setIdentity(const QString &value)
Set the syslog identity string.
void setFlags(OutputFlags flags)
Set the output flags, replacing any existing flags.
Definition log.h:129
OutputFlags flags() const
Return the active output flags.
Definition log.h:123
void setLevel(LogLevel value)
Set the minimum log level; messages below this level are discarded.
Definition log.h:117
QString filename() const
Return the log file path.
Definition log.h:147
void removeConsumer(LogConsumer *consumer)
Remove a previously added log consumer.
LogLevel level() const
Return the current minimum log level.
Definition log.h:111
QString identity() const
Return the syslog identity string.
Definition log.h:159
Logger()
Default constructor — initializes an unopened logger at Debug level.
void logHex(const char *file, int lineNumber, LogLevel level, const LogCategory &category, const QByteArray &data, const QString &tag=QString())
Write a categorized hex dump to the log.
LogCategory registerCategory(const LogCategory &category)
Register an existing LogCategory object.
bool isLogOpen() const
Test whether the log is open and ready to write.
Definition log.h:210
void addConsumer(LogConsumer *consumer)
Add an external log consumer to receive log entries.
void setFilename(const QString &filename)
Set the log file path and reopen the file.
void rotateLog(const QString &newFileName)
Rotate the log to a new file path.
QList< LogCategory > categories() const
Return all registered log categories.
void logText(const char *file, int lineNumber, LogLevel level, const QString &text)
Write a text message to the log.
void setCategoryLevel(const QString &name, LogLevel level)
Override the log level for a specific category.
Logging subsystem providing categorized, level-filtered output.
Definition log.h:40
KANOOP_EXPORT void setFilename(const QString &filename)
Set the log file path of the system logger.
KANOOP_EXPORT void logHex(const char *file, int lineNumber, LogLevel level, const LogCategory &category, const QByteArray &data, const QString &tag=QString())
Write a categorized hex dump via the system logger.
KANOOP_EXPORT LogCategory registerCategory(const QString &name)
Register a log category by name with the system logger.
KANOOP_EXPORT QList< LogCategory > categories()
Return all categories registered with the system logger.
LogLevel
Severity levels for log messages, ordered from most to least critical.
KANOOP_EXPORT OutputFlags flags()
Return the output flags of the system logger.
KANOOP_EXPORT void setCategoryLevel(const QString &name, LogLevel level)
Override the log level for a named category on the system logger.
KANOOP_EXPORT void logText(const char *file, int lineNumber, LogLevel level, const QString &text)
Write a text message via the system logger.
KANOOP_EXPORT void setIdentity(const QString &value)
Set the syslog identity of the system logger.
KANOOP_EXPORT void setLevel(LogLevel value)
Set the minimum log level of the system logger.
KANOOP_EXPORT void disableOutputFlags(OutputFlags flags)
Disable specific output flags on the system logger.
KANOOP_EXPORT LogLevel parseLevel(const QString &value, bool *parsed=nullptr)
Parse a log level name string into a LogLevel enum value.
KANOOP_EXPORT void addConsumer(LogConsumer *consumer)
Add an external log consumer to the system logger.
KANOOP_EXPORT QString identity()
Return the syslog identity of the system logger.
KANOOP_EXPORT QString filename()
Return the log file path of the system logger.
KANOOP_EXPORT void setFlags(OutputFlags flags)
Set the output flags of the system logger.
KANOOP_EXPORT LogLevel level()
Return the current minimum log level of the system logger.
KANOOP_EXPORT void enableOutputFlags(OutputFlags flags)
Enable additional output flags on the system logger.
KANOOP_EXPORT void removeConsumer(LogConsumer *consumer)
Remove an external log consumer from the system logger.
KANOOP_EXPORT Logger * systemLog()
Return the process-wide Logger singleton.
OutputFlags
Bitmask flags controlling where log output is sent.
KANOOP_EXPORT QDateTime getLogStartTime(const QString &filename)
Read the start timestamp from an existing log file.
KANOOP_EXPORT QDateTime getLogEndTime(const QString &filename)
Read the end timestamp from an existing log file.