EZLog
Loading...
Searching...
No Matches
Logger.h
Go to the documentation of this file.
1/****************************************************************************
2** 本库是为了更方便地使用 spdlog 日志系统,参考了 QDebug 的日志打印代码实现。
3**
4** 通过 lDebug 宏,你可以像用 qDebug 一样使用流式输入,与 qDebug 不同的是,
5** lDebug 除了会在控制台输出你要打印的内容外,也会在日志文件中记录相同的信息。
6**
7** lDebug 本质上只是调用了 Debug().output 方法,记录的是 Log_Debug 等级的信息,
8** 你可以根据你的需要创建其他宏来更方便地调用其他日志创建方法。
9**
10** 如果你想要禁用 lDebug 输出,可以在配置文件中添加 LOGGER_NO_DEBUG_OUTPUT 定义,
11** 例如 CONFIG (release, debug | release) {DEFINES += LOGGER_NO_DEBUG_OUTPUT}。
12**
13** -------------------------------------------------------------------------
14** This library is designed to facilitate the usage of the spdlog logging system,
15** taking inspiration from the logging implementation of QDebug.
16**
17** With the lDebug macro, you can use it similarly to qDebug for streaming input.
18** The difference is that lDebug not only outputs the desired content to the console
19** but also records the same information in the log file.
20**
21** In essence, lDebug simply calls the Debug().output method, logging information
22** at the Log_Debug level. You can create other macros based on your needs to
23** conveniently invoke other logging methods.
24**
25** If you want to disable lDebug output, you can add the LOGGER_NO_DEBUG_OUTPUT
26** definition in the configuration file.
27** e.g. CONFIG (release, debug | release) {DEFINES += LOGGER_NO_DEBUG_OUTPUT}.
28**
29****************************************************************************/
30
31#ifndef LOGGER_H
32#define LOGGER_H
33
34#if defined(LOGGER_LIBRARY)
35# define LOGGER_EXPORT __declspec(dllexport)
36#else
37# define LOGGER_EXPORT __declspec(dllimport)
38#endif
39
40#include <QDebug>
41#include <QString>
42#include <QSettings>
43#include <QTextStream>
44#include <QDateTime>
45
46#include <iostream>
47#include <memory>
48#include <atomic>
49#include <mutex>
50#include <functional>
51
52#ifdef __DOXYGEN__
61#define LOGGER_SINGLE_THREAD
62
70#define LOGGER_NO_DEBUG_OUTPUT
71#endif
72
80namespace spdlog {
88class logger;
89}
90
98namespace EZLog {
107 Lib() = default;
108 ~Lib() = default;
109
110 static Lib& instance();
111 std::shared_ptr<spdlog::logger> logger_;
112 QString errmsg_;
113
114public:
132 static bool Initialize(const QString& project = "Project",
133 const QString& prefix = "log",
134 const QString& dir = "Logs/",
135 bool multi_thread = true);
136
146 static QString errmsg();
147
157 static void Debug(const QString& msg);
167 static void Info(const QString& msg);
177 static void Warn(const QString& msg);
187 static void Error(const QString& msg);
197 static void Critical(const QString& msg);
198};
199
215 void lock() const {}
223 void unlock() const {}
231 bool try_lock() const { return true; }
232};
233
241template <typename T>
251
269 explicit null_atomic(T new_value) : value(new_value) {}
270
280 T load(std::memory_order = std::memory_order_relaxed) const
281 { return value; }
291 void store(T new_value, std::memory_order = std::memory_order_relaxed)
292 { value = new_value; }
293};
294
302extern LOGGER_EXPORT std::mutex real_mutex;
311
312#if !defined(LOGGER_SINGLE_THREAD)
320template <typename T> using Atomic = std::atomic<T>;
328using Mutex = std::mutex;
336static Mutex& mutex(real_mutex);
337#else
345template <typename T> using Atomic = null_atomic<T>;
361static Mutex& mutex(fake_mutex);
362#endif
363
373#define LOG_INIT(name) Logger::Initialize(#name)
374
382#define TAKE_OVER_QDEBUG Logger::InstallMessageHandler()
383
392#define lDebug Logger::Debug().output
393
401#define LogDebug Logger::Debug()
402
410#define LogInfo Logger::Info()
411
419#define LogWarn Logger::Warn()
420
428#define LogError Logger::Error()
429
437#define LogCritical Logger::Critical()
438
446class Logger final {
447public:
455 using Callback = std::function<void(const QString&)>;
456
467 enum Level {
485 Log_Off
486 };
487
503 static bool Initialize(const QString& projectName = "Project",
504 const QString& logPrefix = "log",
505 const QString& logDir = "Logs/");
506
516 static QString errMsg();
517
525 static void InstallMessageHandler();
533 static void UninstallMessageHandler();
534
546 static void SetLogLevel(int level);
556 static Level logLevel();
557
570 static void ReadConfig(const QString& filePath);
571
581 static void SetShowTimeStamp(bool set);
591 static void SetTimeStampFormat(const QString& format);
592
602 static void SetShowLevelTag(bool set);
612 static void SetDebugTag(const QString& tag);
622 static void SetInfoTag(const QString& tag);
632 static void SetWarnTag(const QString& tag);
642 static void SetErrorTag(const QString& tag);
652 static void SetCriticalTag(const QString& tag);
653
663 static void SetNeedOutput(bool set);
664
674 static void SetUnifiedCallback(const Callback& callback);
684 static void SetDebugCallback(const Callback& callback);
694 static void SetInfoCallback(const Callback& callback);
704 static void SetWarnCallback(const Callback& callback);
714 static void SetErrorCallback(const Callback& callback);
724 static void SetCriticalCallback(const Callback& callback);
725
735 static Logger Debug();
745 static Logger Info();
755 static Logger Warn();
765 static Logger Error();
775 static Logger Critical();
776
796 Logger& timestamp();
797
817 Logger& leveltag();
818
828 Logger& nooutput();
838 Logger& output();
839
840public: // Obsolete
852 static Logger Debug(const QString& msg);
864 static Logger Info(const QString& msg);
876 static Logger Warn(const QString& msg);
888 static Logger Error(const QString& msg);
900 static Logger Critical(const QString& msg);
901
902public: // Implementation
911 if (!--stream->ref) {
912 if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
913 stream->buffer.chop(1);
914 if (stream->level >= logLevel()) {
915 const QString& msg = stream->buffer;
916 switch (stream->level) {
917 case Log_Debug:
918 WriteLog<Log_Debug>(msg);
919#if !defined(LOGGER_NO_DEBUG_OUTPUT)
920 if (stream->output) HandleOutput<Log_Debug>(stream->timestamp, stream->level_tag, msg);
921#endif
922 HandleCallback<Log_Debug>(stream->timestamp, stream->level_tag, msg);
923 break;
924 case Log_Info:
925 WriteLog<Log_Info>(msg);
926 if (stream->output) HandleOutput<Log_Info>(stream->timestamp, stream->level_tag, msg);
927 HandleCallback<Log_Info>(stream->timestamp, stream->level_tag, msg);
928 break;
929 case Log_Warn:
930 WriteLog<Log_Warn>(msg);
931 if (stream->output) HandleOutput<Log_Warn>(stream->timestamp, stream->level_tag, msg);
932 HandleCallback<Log_Warn>(stream->timestamp, stream->level_tag, msg);
933 break;
934 case Log_Error:
935 WriteLog<Log_Error>(msg);
936 if (stream->output) HandleOutput<Log_Error>(stream->timestamp, stream->level_tag, msg);
937 HandleCallback<Log_Error>(stream->timestamp, stream->level_tag, msg);
938 break;
939 case Log_Critical:
940 WriteLog<Log_Critical>(msg);
941 if (stream->output) HandleOutput<Log_Critical>(stream->timestamp, stream->level_tag, msg);
942 HandleCallback<Log_Critical>(stream->timestamp, stream->level_tag, msg);
943 break;
944 default: break;
945 }
946 }
947
948 delete stream;
949 }
950 }
951
963 inline Logger& operator<<(QChar t) { putUcs4(t.unicode()); return maybeSpace(); }
975 inline Logger& operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
987 inline Logger& operator<<(char t) { stream->ts << t; return maybeSpace(); }
999 inline Logger& operator<<(signed short t) { stream->ts << t; return maybeSpace(); }
1011 inline Logger& operator<<(unsigned short t) { stream->ts << t; return maybeSpace(); }
1012#ifdef Q_COMPILER_UNICODE_STRINGS
1024 inline Logger& operator<<(char16_t t) { return *this << QChar(ushort(t)); }
1036 inline Logger& operator<<(char32_t t) { putUcs4(t); return maybeSpace(); }
1037#endif
1049 inline Logger& operator<<(signed int t) { stream->ts << t; return maybeSpace(); }
1061 inline Logger& operator<<(unsigned int t) { stream->ts << t; return maybeSpace(); }
1073 inline Logger& operator<<(signed long t) { stream->ts << t; return maybeSpace(); }
1085 inline Logger& operator<<(unsigned long t) { stream->ts << t; return maybeSpace(); }
1097 inline Logger& operator<<(qint64 t) { stream->ts << t; return maybeSpace(); }
1109 inline Logger& operator<<(quint64 t) { stream->ts << t; return maybeSpace(); }
1121 inline Logger& operator<<(float t) { stream->ts << t; return maybeSpace(); }
1133 inline Logger& operator<<(double t) { stream->ts << t; return maybeSpace(); }
1145 inline Logger& operator<<(const char* t) { stream->ts << QString::fromUtf8(t); return maybeSpace(); }
1146#if QT_STRINGVIEW_LEVEL < 2
1158 inline Logger& operator<<(const QString & t) { stream->ts << t; return maybeSpace(); }
1170 inline Logger& operator<<(const QStringRef & t) { stream->ts << t; return maybeSpace(); }
1171#endif
1172#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
1184 inline Logger& operator<<(QStringView s) { stream->ts << s; return maybeSpace(); }
1185#endif
1197 inline Logger& operator<<(QLatin1String t) { stream->ts << t; return maybeSpace(); }
1209 inline Logger& operator<<(const QByteArray & t) { stream->ts << t; return maybeSpace(); }
1221 inline Logger& operator<<(const void* t) { stream->ts << t; return maybeSpace(); }
1222#ifdef Q_COMPILER_NULLPTR
1234 inline Logger& operator<<(std::nullptr_t) { stream->ts << "(nullptr)"; return maybeSpace(); }
1235#endif
1247 inline Logger& operator<<(QTextStreamFunction f) { stream->ts << f; return *this; }
1259 inline Logger& operator<<(QTextStreamManipulator m) { stream->ts << m; return *this; }
1260
1276 template <typename SequentialContainer>
1277 inline Logger& printSequentialContainer(Logger& logger, const char* which, const SequentialContainer& c)
1278 {
1279 const bool oldSetting = logger.autoInsertSpaces();
1280 logger.nospace() << which << '(';
1281 typename SequentialContainer::const_iterator it = c.begin(), end = c.end();
1282 if (it != end) {
1283 logger << *it;
1284 ++it;
1285 }
1286 while (it != end) {
1287 logger << ", " << *it;
1288 ++it;
1289 }
1290 logger << ')';
1291 logger.setAutoInsertSpaces(oldSetting);
1292 return logger.maybeSpace();
1293 }
1294
1306 template <typename T>
1307 inline Logger& operator<<(const QList<T> &list) {
1308 return printSequentialContainer(*this, "", list);
1309 }
1310
1322 template <typename T>
1323 inline Logger& operator<<(const QVector<T> &vec)
1324 {
1325 return printSequentialContainer(*this, "QVector", vec);
1326 }
1327
1339 template <typename T, typename Alloc>
1340 inline Logger& operator<<(const std::vector<T, Alloc> &vec)
1341 {
1342 return printSequentialContainer(*this, "std::vector", vec);
1343 }
1344
1356 template <typename T, typename Alloc>
1357 inline Logger& operator<<(const std::list<T, Alloc> &list)
1358 {
1359 return printSequentialContainer(*this, "std::list", list);
1360 }
1361
1373 template <typename Key, typename T, typename Compare, typename Alloc>
1374 inline Logger& operator<<(const std::map<Key, T, Compare, Alloc> &map)
1375 {
1376 return printSequentialContainer(*this, "std::map", map);
1377 }
1378
1390 template <typename Key, typename T, typename Compare, typename Alloc>
1391 inline Logger& operator<<(const std::multimap<Key, T, Compare, Alloc> &map)
1392 {
1393 return printSequentialContainer(*this, "std::multimap", map);
1394 }
1395
1407 template <class Key, class T>
1408 inline Logger& operator<<(const QMap<Key, T> &map)
1409 {
1410 const bool oldSetting = this->autoInsertSpaces();
1411 this->nospace() << "QMap(";
1412 for (typename QMap<Key, T>::const_iterator it = map.constBegin();
1413 it != map.constEnd(); ++it) {
1414 (*this) << '(' << it.key() << ", " << it.value() << ')';
1415 }
1416 (*this) << ')';
1417 this->setAutoInsertSpaces(oldSetting);
1418 return this->maybeSpace();
1419 }
1420
1432 template <class Key, class T>
1433 inline Logger& operator<<(const QHash<Key, T> &hash)
1434 {
1435 const bool oldSetting = this->autoInsertSpaces();
1436 this->nospace() << "QHash(";
1437 for (typename QHash<Key, T>::const_iterator it = hash.constBegin();
1438 it != hash.constEnd(); ++it)
1439 (*this) << '(' << it.key() << ", " << it.value() << ')';
1440 (*this) << ')';
1441 this->setAutoInsertSpaces(oldSetting);
1442 return this->maybeSpace();
1443 }
1444
1456 template <class T1, class T2>
1457 inline Logger& operator<<(const QPair<T1, T2> &pair)
1458 {
1459 const bool oldSetting = this->autoInsertSpaces();
1460 this->nospace() << "QPair(" << pair.first << ',' << pair.second << ')';
1461 this->setAutoInsertSpaces(oldSetting);
1462 return this->maybeSpace();
1463 }
1464
1476 template <class T1, class T2>
1477 inline Logger& operator<<(const std::pair<T1, T2> &pair)
1478 {
1479 const bool oldSetting = this->autoInsertSpaces();
1480 this->nospace() << "std::pair(" << pair.first << ',' << pair.second << ')';
1481 this->setAutoInsertSpaces(oldSetting);
1482 return this->maybeSpace();
1483 }
1484
1496 template <typename T>
1497 inline Logger& operator<<(const QSet<T> &set)
1498 {
1499 return printSequentialContainer((*this), "QSet", set);
1500 }
1501
1513 template <typename T>
1514 inline Logger& operator<<(const QContiguousCache<T> &cache)
1515 {
1516 const bool oldSetting = this->autoInsertSpaces();
1517 this->nospace() << "QContiguousCache(";
1518 for (int i = cache.firstIndex(); i <= cache.lastIndex(); ++i) {
1519 (*this) << cache[i];
1520 if (i != cache.lastIndex())
1521 (*this) << ", ";
1522 }
1523 (*this) << ')';
1524 this->setAutoInsertSpaces(oldSetting);
1525 return this->maybeSpace();
1526 }
1527
1537 inline explicit Logger(Level level) : stream(new LogStream(level)) {}
1547 inline Logger(const Logger& other) : stream(other.stream) { ++stream->ref; }
1559 inline Logger& operator=(const Logger& other) {
1560 if (this != &other) {
1561 Logger copy(other);
1562 std::swap(stream, copy.stream);
1563 }
1564 return *this;
1565 }
1566
1577 inline Logger& space() { stream->space = true; stream->ts << ' '; return *this; }
1578
1588 inline Logger& nospace() { stream->space = false; return *this; }
1589
1600 inline Logger& maybeSpace() { if (stream->space) stream->ts << ' '; return *this; }
1601
1611 bool autoInsertSpaces() const { return stream->space; }
1612
1622 void setAutoInsertSpaces(bool set) { stream->space = set; }
1623
1624private:
1625 struct LogStream {
1626 explicit LogStream(Level l)
1627 : ts(&buffer, QIODevice::WriteOnly), ref(1), level(l), space(true),
1628 timestamp(stamp().show_time.load(std::memory_order_relaxed)),
1629 level_tag(stamp().show_tag.load(std::memory_order_relaxed)),
1630 output(need_output().load(std::memory_order_relaxed)) {}
1631
1632 QTextStream ts;
1633 QString buffer;
1634 int ref;
1635 Level level;
1636 bool space;
1637 bool timestamp;
1638 bool level_tag;
1639 bool output;
1640 } *stream;
1641
1642 static Atomic<Level>& log_level() {
1643 static Atomic<Level> _log_level(Log_Debug);
1644 return _log_level;
1645 };
1646
1647 static Atomic<bool>& need_output() {
1648 static Atomic<bool> _need_output(false);
1649 return _need_output;
1650 }
1651
1652 static Atomic<bool>& qDebug_is_handled() {
1653 static Atomic<bool> _qDebug_is_handled(false);
1654 return _qDebug_is_handled;
1655 }
1656
1657 struct Stamp {
1658 Stamp()
1659 : show_time(false)
1660 , show_tag(true)
1661 , time_format("[HH:mm:ss]")
1662 , debug_tag("[debug]")
1663 , info_tag("[info]")
1664 , warn_tag("[warning]")
1665 , err_tag("[error]")
1666 , crit_tag("[critical]")
1667 {}
1668
1669 Atomic<bool> show_time;
1670 Atomic<bool> show_tag;
1671 QString time_format;
1672 QString debug_tag;
1673 QString info_tag;
1674 QString warn_tag;
1675 QString err_tag;
1676 QString crit_tag;
1677 };
1678
1679 static Stamp& stamp() {
1680 static Stamp _stamp;
1681 return _stamp;
1682 }
1683
1684 struct Callbacks {
1685 Callbacks()
1686 : debug_callback(nullptr)
1687 , info_callback(nullptr)
1688 , warn_callback(nullptr)
1689 , err_callback(nullptr)
1690 , crit_callback(nullptr)
1691 {}
1692
1693 Callback debug_callback;
1694 Callback info_callback;
1695 Callback warn_callback;
1696 Callback err_callback;
1697 Callback crit_callback;
1698 };
1699
1700 static Callbacks& callbacks() {
1701 static Callbacks _callbacks;
1702 return _callbacks;
1703 }
1704
1705 void putUcs4(uint ucs4) {
1706 if (ucs4 < 0x20) {
1707 stream->ts << "\\x" << hex << ucs4 << reset;
1708 } else if (ucs4 < 0x80) {
1709 stream->ts << char(ucs4);
1710 } else {
1711 if (ucs4 < 0x10000)
1712 stream->ts << "\\u" << qSetFieldWidth(4);
1713 else
1714 stream->ts << "\\U" << qSetFieldWidth(8);
1715 stream->ts << hex << qSetPadChar(QLatin1Char('0')) << ucs4 << reset;
1716 }
1717 }
1718
1719 template<Level> QString tag();
1720 template<Level> void log(const QString&);
1721 template<Level> void callback(const QString&);
1722 template<Level> bool callback();
1723
1724 template<Level level>
1725 inline void WriteLog(const QString& msg) {
1726 log<level>(msg);
1727 }
1728
1729 template<Level level>
1730 inline void HandleOutput(bool showTime, bool showTag, const QString& msg) {
1731 std::lock_guard<Mutex> lock(mutex);
1732 if (qDebug_is_handled().load(std::memory_order_acquire)) {
1733 auto& out = std::cout;
1734 if (showTime && !stamp().time_format.isNull())
1735 out << QDateTime::currentDateTime().toString(stamp().time_format).toLocal8Bit().constData() << ' ';
1736 if (showTag && !tag<level>().isNull())
1737 out << tag<level>().toLocal8Bit().constData() << ' ';
1738 out << msg.toLocal8Bit().constData() << std::endl;
1739 } else {
1740#if !defined(QT_NO_DEBUG_OUTPUT)
1741 auto out = qDebug().noquote();
1742 if (showTime && !stamp().time_format.isNull())
1743 out << QDateTime::currentDateTime().toString(stamp().time_format);
1744 if (showTag && !tag<level>().isNull())
1745 out << tag<level>();
1746 out << msg;
1747#endif
1748 }
1749 }
1750
1751 template<Level level>
1752 inline void HandleCallback(bool showTime, bool showTag, const QString& msg) {
1753 std::lock_guard<Mutex> lock(mutex);
1754 if (callback<level>()) {
1755 QString str;
1756 QTextStream out(&str);
1757 if (showTime && !stamp().time_format.isNull())
1758 out << QDateTime::currentDateTime().toString(stamp().time_format) << ' ';
1759 if (showTag && !tag<level>().isNull())
1760 out << tag<level>() << ' ';
1761 out << msg;
1762 callback<level>(str);
1763 }
1764 }
1765};
1766
1768template<> inline QString Logger::tag<Logger::Log_Debug>() { return stamp().debug_tag; };
1769template<> inline QString Logger::tag<Logger::Log_Info>() { return stamp().info_tag; };
1770template<> inline QString Logger::tag<Logger::Log_Warn>() { return stamp().warn_tag; };
1771template<> inline QString Logger::tag<Logger::Log_Error>() { return stamp().err_tag; };
1772template<> inline QString Logger::tag<Logger::Log_Critical>() { return stamp().crit_tag; };
1773
1774template<> inline void Logger::log<Logger::Log_Debug>(const QString& msg) { Lib::Debug(msg); };
1775template<> inline void Logger::log<Logger::Log_Info>(const QString& msg) { Lib::Info(msg); };
1776template<> inline void Logger::log<Logger::Log_Warn>(const QString& msg) { Lib::Warn(msg); };
1777template<> inline void Logger::log<Logger::Log_Error>(const QString& msg) { Lib::Error(msg); };
1778template<> inline void Logger::log<Logger::Log_Critical>(const QString& msg) { Lib::Critical(msg); };
1779
1780template<> inline void Logger::callback<Logger::Log_Debug>(const QString& msg) { callbacks().debug_callback(msg); };
1781template<> inline void Logger::callback<Logger::Log_Info>(const QString& msg) { callbacks().info_callback(msg); };
1782template<> inline void Logger::callback<Logger::Log_Warn>(const QString& msg) { callbacks().warn_callback(msg); };
1783template<> inline void Logger::callback<Logger::Log_Error>(const QString& msg) { callbacks().err_callback(msg); };
1784template<> inline void Logger::callback<Logger::Log_Critical>(const QString& msg) { callbacks().crit_callback(msg); };
1785
1786template<> inline bool Logger::callback<Logger::Log_Debug>() { return callbacks().debug_callback.operator bool(); };
1787template<> inline bool Logger::callback<Logger::Log_Info>() { return callbacks().info_callback.operator bool(); };
1788template<> inline bool Logger::callback<Logger::Log_Warn>() { return callbacks().warn_callback.operator bool(); };
1789template<> inline bool Logger::callback<Logger::Log_Error>() { return callbacks().err_callback.operator bool(); };
1790template<> inline bool Logger::callback<Logger::Log_Critical>() { return callbacks().crit_callback.operator bool(); };
1792
1793inline bool Logger::Initialize(const QString &projectName, const QString &logPrefix, const QString &logDir)
1794{
1795 std::lock_guard<Mutex> lock(mutex);
1796#if !defined(LOGGER_SINGLE_THREAD)
1797 return Lib::Initialize(projectName, logPrefix, logDir, true);
1798#else
1799 return Lib::Initialize(projectName, logPrefix, logDir, false);
1800#endif
1801}
1802
1803inline QString Logger::errMsg()
1804{
1805 return Lib::errmsg();
1806}
1807
1809{
1810 qInstallMessageHandler([](QtMsgType t, const QMessageLogContext&, const QString& str) {
1811 switch (t) {
1812 case QtDebugMsg: Debug().output() << str; break;
1813 case QtWarningMsg: Warn().output() << str; break;
1814 case QtCriticalMsg: Critical().output() << str; break;
1815 case QtFatalMsg: Critical().output() << str; break;
1816 case QtInfoMsg: Info().output() << str; break;
1817 default: break;
1818 }
1819 });
1820 qDebug_is_handled().store(true, std::memory_order_release);
1821}
1822
1824{
1825 qInstallMessageHandler(0);
1826 qDebug_is_handled().store(false, std::memory_order_release);
1827}
1828
1829inline void Logger::SetLogLevel(int level) { if (level >= Log_Debug && level <= Log_Off) { log_level().store((Level)level); }}
1830
1831inline Logger::Level Logger::logLevel() { return log_level().load(std::memory_order_relaxed); }
1832
1833inline void Logger::ReadConfig(const QString &filePath)
1834{
1835 QSettings config(filePath, QSettings::IniFormat);
1836 auto logLevelVar = config.value("logLevel");
1837 if (logLevelVar.isValid()) {
1838 SetLogLevel(logLevelVar.toInt());
1839 } else {
1841 }
1842}
1843
1844inline void Logger::SetShowTimeStamp(bool set)
1845{
1846 stamp().show_time.store(set);
1847}
1848
1849inline void Logger::SetTimeStampFormat(const QString &format)
1850{
1851 std::lock_guard<Mutex> lock(mutex);
1852 stamp().time_format = format;
1853}
1854
1855inline void Logger::SetShowLevelTag(bool set)
1856{
1857 stamp().show_tag.store(set);
1858}
1859
1860inline void Logger::SetDebugTag(const QString &tag)
1861{
1862 std::lock_guard<Mutex> lock(mutex);
1863 stamp().debug_tag = tag;
1864}
1865
1866inline void Logger::SetInfoTag(const QString &tag)
1867{
1868 std::lock_guard<Mutex> lock(mutex);
1869 stamp().info_tag = tag;
1870}
1871
1872inline void Logger::SetWarnTag(const QString &tag)
1873{
1874 std::lock_guard<Mutex> lock(mutex);
1875 stamp().warn_tag = tag;
1876}
1877
1878inline void Logger::SetErrorTag(const QString &tag)
1879{
1880 std::lock_guard<Mutex> lock(mutex);
1881 stamp().err_tag = tag;
1882}
1883
1884inline void Logger::SetCriticalTag(const QString &tag)
1885{
1886 std::lock_guard<Mutex> lock(mutex);
1887 stamp().crit_tag = tag;
1888}
1889
1890inline void Logger::SetNeedOutput(bool set)
1891{
1892 need_output().store(set);
1893}
1894
1895inline void Logger::SetUnifiedCallback(const Callback &callback)
1896{
1897 std::lock_guard<Mutex> lock(mutex);
1898 callbacks().debug_callback = callback;
1899 callbacks().info_callback = callback;
1900 callbacks().warn_callback = callback;
1901 callbacks().err_callback = callback;
1902 callbacks().crit_callback = callback;
1903}
1904
1905inline void Logger::SetDebugCallback(const Callback &callback)
1906{
1907 std::lock_guard<Mutex> lock(mutex);
1908 callbacks().debug_callback = callback;
1909}
1910
1911inline void Logger::SetInfoCallback(const Callback &callback)
1912{
1913 std::lock_guard<Mutex> lock(mutex);
1914 callbacks().info_callback = callback;
1915}
1916
1917inline void Logger::SetWarnCallback(const Callback &callback)
1918{
1919 std::lock_guard<Mutex> lock(mutex);
1920 callbacks().warn_callback = callback;
1921}
1922
1923inline void Logger::SetErrorCallback(const Callback &callback)
1924{
1925 std::lock_guard<Mutex> lock(mutex);
1926 callbacks().err_callback = callback;
1927}
1928
1929inline void Logger::SetCriticalCallback(const Callback &callback)
1930{
1931 std::lock_guard<Mutex> lock(mutex);
1932 callbacks().crit_callback = callback;
1933}
1934
1936
1938
1939inline Logger Logger::Warn() { return Logger(Log_Warn); }
1940
1942
1944
1945inline Logger &Logger::notimestamp() { stream->timestamp = false; return *this; }
1946
1947inline Logger &Logger::timestamp() { stream->timestamp = true; return *this; }
1948
1949inline Logger &Logger::noleveltag() { stream->level_tag = false; return *this; }
1950
1951inline Logger &Logger::leveltag() { stream->level_tag = true; return *this; }
1952
1953inline Logger &Logger::nooutput() { stream->output = false; return *this; }
1954
1955inline Logger &Logger::output() { stream->output = true; return *this; }
1956
1957inline Logger Logger::Debug(const QString &msg) { return Logger(Log_Debug) << msg; }
1958
1959inline Logger Logger::Info(const QString &msg) { return Logger(Log_Info) << msg; }
1960
1961inline Logger Logger::Warn(const QString &msg) { return Logger(Log_Warn) << msg; }
1962
1963inline Logger Logger::Error(const QString &msg) { return Logger(Log_Error) << msg; }
1964
1965inline Logger Logger::Critical(const QString &msg) { return Logger(Log_Critical) << msg; }
1966}
1967
1968using namespace EZLog;
1969
1970#endif // LOGGER_H
#define LOGGER_EXPORT
Definition Logger.h:37
logger lib
Definition Logger.h:106
static QString errmsg()
Error message. Used to retrieve error information when the log library fails to initialize.
static void Warn(const QString &msg)
Record warn-level information in the log.
static void Debug(const QString &msg)
Record debug-level information in the log.
static void Info(const QString &msg)
Record info-level information in the log.
static void Critical(const QString &msg)
Record critical-level information in the log.
static bool Initialize(const QString &project="Project", const QString &prefix="log", const QString &dir="Logs/", bool multi_thread=true)
Initialize Initialize log library.
static void Error(const QString &msg)
Record error-level information in the log.
logger class
Definition Logger.h:446
static void SetDebugCallback(const Callback &callback)
Set debug-level callback, triggered when logging debug-level logs.
Definition Logger.h:1905
Logger & nooutput()
Return version without output.
Definition Logger.h:1953
static Logger Warn()
Create warn-level logger.
Definition Logger.h:1939
std::function< void(const QString &)> Callback
Callback function type.
Definition Logger.h:455
Logger & operator<<(const QPair< T1, T2 > &pair)
Stream input of QPair type data.
Definition Logger.h:1457
static void SetLogLevel(int level)
Set the log level, only logs with a level higher than the set level will be processed....
Definition Logger.h:1829
Logger & operator<<(const QByteArray &t)
Stream input of QByteArray type data.
Definition Logger.h:1209
Logger & operator<<(char t)
Stream input of char type data.
Definition Logger.h:987
static void SetDebugTag(const QString &tag)
Set debug-level tag.
Definition Logger.h:1860
bool autoInsertSpaces() const
Return current setting for automatic space insertion.
Definition Logger.h:1611
Logger & operator<<(const std::pair< T1, T2 > &pair)
Stream input of std::pair type data.
Definition Logger.h:1477
static void SetCriticalTag(const QString &tag)
Set critical-level tag.
Definition Logger.h:1884
static void SetErrorCallback(const Callback &callback)
Set error-level callback, triggered when logging error-level logs.
Definition Logger.h:1923
static void SetTimeStampFormat(const QString &format)
Set timestamp format.
Definition Logger.h:1849
static Logger Debug()
Create debug-level logger.
Definition Logger.h:1935
Logger & leveltag()
Return version with level tag.
Definition Logger.h:1951
Logger & operator=(const Logger &other)
Logger assignment operator.
Definition Logger.h:1559
Logger & operator<<(qint64 t)
Stream input of qint64 type data.
Definition Logger.h:1097
Logger & timestamp()
Return version with timestamp.
Definition Logger.h:1947
static void SetInfoTag(const QString &tag)
Set info-level tag.
Definition Logger.h:1866
Logger(const Logger &other)
Logger copy constructor.
Definition Logger.h:1547
Logger & operator<<(const QVector< T > &vec)
Stream input of QVector type data.
Definition Logger.h:1323
static void ReadConfig(const QString &filePath)
Read log level config file. The file should be in INI format, and this method will read the configura...
Definition Logger.h:1833
static Logger Error()
Create error-level logger.
Definition Logger.h:1941
Logger & output()
Return version with output.
Definition Logger.h:1955
Level
Log levels, divided into 6 levels, in ascending order. Only logs with a level higher than the setting...
Definition Logger.h:467
@ Log_Warn
Definition Logger.h:476
@ Log_Off
Definition Logger.h:485
@ Log_Error
Definition Logger.h:479
@ Log_Debug
Definition Logger.h:470
@ Log_Info
Definition Logger.h:473
@ Log_Critical
Definition Logger.h:482
Logger & maybeSpace()
Write a space character to the stream, depending on the current setting for automatic insertion of sp...
Definition Logger.h:1600
Logger & operator<<(const std::vector< T, Alloc > &vec)
Stream input of std::vector type data.
Definition Logger.h:1340
Logger & operator<<(QTextStreamManipulator m)
Stream input of QTextStreamManipulator type data.
Definition Logger.h:1259
Logger & space()
Write a space character to the message stream and return logger. Subsequent write operations will aut...
Definition Logger.h:1577
Logger & operator<<(const QSet< T > &set)
Stream input of QSet type data.
Definition Logger.h:1497
Logger & notimestamp()
Return version without timestamp.
Definition Logger.h:1945
Logger & operator<<(const QStringRef &t)
Stream input of QStringRef type data.
Definition Logger.h:1170
Logger & operator<<(signed int t)
Stream input of signed int type data.
Definition Logger.h:1049
static Logger Critical()
Create critical-level logger.
Definition Logger.h:1943
Logger & operator<<(const QString &t)
Stream input of QString type data.
Definition Logger.h:1158
Logger & nospace()
Disable automatic space insertion and return logger.
Definition Logger.h:1588
Logger & operator<<(QLatin1String t)
Stream input of QLatin1String type data.
Definition Logger.h:1197
Logger & operator<<(const void *t)
Stream input of void* type data.
Definition Logger.h:1221
Logger(Level level)
Logger constructor.
Definition Logger.h:1537
Logger & operator<<(double t)
Stream input of double type data.
Definition Logger.h:1133
Logger & operator<<(const QContiguousCache< T > &cache)
Stream input of QContiguousCache type data.
Definition Logger.h:1514
static void UninstallMessageHandler()
Cancel taking over qDebug output.
Definition Logger.h:1823
~Logger()
Destruct and handle log information.
Definition Logger.h:910
static void SetUnifiedCallback(const Callback &callback)
Set unified callback, triggered when logging any-level logs.
Definition Logger.h:1895
static void SetShowLevelTag(bool set)
Set whether to show level tag by default.
Definition Logger.h:1855
static void SetNeedOutput(bool set)
Set whether to output log by default.
Definition Logger.h:1890
Logger & operator<<(const std::map< Key, T, Compare, Alloc > &map)
Stream input of std::map type data.
Definition Logger.h:1374
Logger & operator<<(signed long t)
Stream input of signed long type data.
Definition Logger.h:1073
Logger & operator<<(signed short t)
Stream input of signed short type data.
Definition Logger.h:999
Logger & operator<<(const QHash< Key, T > &hash)
Stream input of QHash type data.
Definition Logger.h:1433
Logger & operator<<(const QMap< Key, T > &map)
Stream input of QMap type data.
Definition Logger.h:1408
static void SetShowTimeStamp(bool set)
Set whether to show timestamps by default.
Definition Logger.h:1844
Logger & printSequentialContainer(Logger &logger, const char *which, const SequentialContainer &c)
Print sequential container message.
Definition Logger.h:1277
Logger & operator<<(const char *t)
Stream input of char* type data.
Definition Logger.h:1145
static void SetCriticalCallback(const Callback &callback)
Set critical-level callback, triggered when logging critical-level logs.
Definition Logger.h:1929
static QString errMsg()
Error message. Used to retrieve error information when the logging system fails to initialize.
Definition Logger.h:1803
Logger & operator<<(unsigned long t)
Stream input of unsigned long type data.
Definition Logger.h:1085
Logger & operator<<(quint64 t)
Stream input of quint64 type data.
Definition Logger.h:1109
static void SetWarnCallback(const Callback &callback)
Set warn-level callback, triggered when logging warn-level logs.
Definition Logger.h:1917
Logger & operator<<(const std::multimap< Key, T, Compare, Alloc > &map)
Stream input of std::multimap type data.
Definition Logger.h:1391
Logger & operator<<(const QList< T > &list)
Stream input of QList type data.
Definition Logger.h:1307
static bool Initialize(const QString &projectName="Project", const QString &logPrefix="log", const QString &logDir="Logs/")
Initialize the logging system.
Definition Logger.h:1793
static void SetInfoCallback(const Callback &callback)
Set info-level callback, triggered when logging info-level logs.
Definition Logger.h:1911
Logger & operator<<(QChar t)
Stream input of QChar type data.
Definition Logger.h:963
static void InstallMessageHandler()
Take over qDebug output.
Definition Logger.h:1808
Logger & operator<<(QTextStreamFunction f)
Stream input of QTextStreamFunction type data.
Definition Logger.h:1247
Logger & operator<<(unsigned int t)
Stream input of unsigned int type data.
Definition Logger.h:1061
static Logger Info()
Create info-level logger.
Definition Logger.h:1937
static void SetErrorTag(const QString &tag)
Set error-level tag.
Definition Logger.h:1878
static Level logLevel()
Return current log level.
Definition Logger.h:1831
Logger & operator<<(const std::list< T, Alloc > &list)
Stream input of std::list type data.
Definition Logger.h:1357
Logger & operator<<(QStringView s)
Stream input of QStringView type data.
Definition Logger.h:1184
Logger & operator<<(bool t)
Stream input of bool type data.
Definition Logger.h:975
void setAutoInsertSpaces(bool set)
Set whether to automatically insert spaces.
Definition Logger.h:1622
Logger & noleveltag()
Return version without level tag.
Definition Logger.h:1949
static void SetWarnTag(const QString &tag)
Set warn-level tag.
Definition Logger.h:1872
Logger & operator<<(float t)
Stream input of float type data.
Definition Logger.h:1121
Logger & operator<<(unsigned short t)
Stream input of unsigned short type data.
Definition Logger.h:1011
EZlog namespace, avoiding naming conflicts.
Definition Logger.h:98
LOGGER_EXPORT null_mutex fake_mutex
mutex of type null_mutex, used for simulating mutex operations in single-threaded mode
LOGGER_EXPORT std::mutex real_mutex
mutex of type std::mutex, used for synchronization in multi-threaded mode
spdlog forward declaration
Definition Logger.h:80
null atomic
Definition Logger.h:242
T value
stored value
Definition Logger.h:250
null_atomic()
value default initialization.
Definition Logger.h:259
null_atomic(T new_value)
use new_value to initialize value.
Definition Logger.h:269
T load(std::memory_order=std::memory_order_relaxed) const
Simulate atomic load and directly return the stored value.
Definition Logger.h:280
void store(T new_value, std::memory_order=std::memory_order_relaxed)
Simulate atomic store and assign the value directly.
Definition Logger.h:291
null mutex
Definition Logger.h:207
void lock() const
Empty lock operation.
Definition Logger.h:215
void unlock() const
Empty unlock operation.
Definition Logger.h:223
bool try_lock() const
Empty try-lock operation.
Definition Logger.h:231