34#if defined(LOGGER_LIBRARY)
35# define LOGGER_EXPORT __declspec(dllexport)
37# define LOGGER_EXPORT __declspec(dllimport)
61#define LOGGER_SINGLE_THREAD
70#define LOGGER_NO_DEBUG_OUTPUT
110 static Lib& instance();
111 std::shared_ptr<spdlog::logger> logger_;
133 const QString& prefix =
"log",
134 const QString& dir =
"Logs/",
135 bool multi_thread =
true);
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);
280 T
load(std::memory_order = std::memory_order_relaxed)
const
291 void store(T new_value, std::memory_order = std::memory_order_relaxed)
292 {
value = new_value; }
312#if !defined(LOGGER_SINGLE_THREAD)
320template <
typename T>
using Atomic = std::atomic<T>;
328using Mutex = std::mutex;
373#define LOG_INIT(name) Logger::Initialize(#name)
382#define TAKE_OVER_QDEBUG Logger::InstallMessageHandler()
392#define lDebug Logger::Debug().output
401#define LogDebug Logger::Debug()
410#define LogInfo Logger::Info()
419#define LogWarn Logger::Warn()
428#define LogError Logger::Error()
437#define LogCritical Logger::Critical()
455 using Callback = std::function<void(
const QString&)>;
503 static bool Initialize(
const QString& projectName =
"Project",
504 const QString& logPrefix =
"log",
505 const QString& logDir =
"Logs/");
570 static void ReadConfig(
const QString& filePath);
911 if (!--stream->ref) {
912 if (stream->space && stream->buffer.endsWith(QLatin1Char(
' ')))
913 stream->buffer.chop(1);
915 const QString& msg = stream->buffer;
916 switch (stream->level) {
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);
922 HandleCallback<Log_Debug>(stream->timestamp, stream->level_tag, msg);
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);
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);
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);
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);
1012#ifdef Q_COMPILER_UNICODE_STRINGS
1024 inline Logger&
operator<<(
char16_t t) {
return *
this << QChar(ushort(t)); }
1146#if QT_STRINGVIEW_LEVEL < 2
1172#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
1222#ifdef Q_COMPILER_NULLPTR
1276 template <
typename SequentialContainer>
1280 logger.
nospace() << which <<
'(';
1281 typename SequentialContainer::const_iterator it = c.begin(), end = c.end();
1287 logger <<
", " << *it;
1306 template <
typename T>
1322 template <
typename T>
1339 template <
typename T,
typename Alloc>
1356 template <
typename T,
typename Alloc>
1373 template <
typename Key,
typename T,
typename Compare,
typename Alloc>
1390 template <
typename Key,
typename T,
typename Compare,
typename Alloc>
1407 template <
class Key,
class T>
1412 for (
typename QMap<Key, T>::const_iterator it = map.constBegin();
1413 it != map.constEnd(); ++it) {
1414 (*this) <<
'(' << it.key() <<
", " << it.value() <<
')';
1432 template <
class Key,
class T>
1437 for (
typename QHash<Key, T>::const_iterator it = hash.constBegin();
1438 it != hash.constEnd(); ++it)
1439 (*
this) <<
'(' << it.key() <<
", " << it.value() <<
')';
1456 template <
class T1,
class T2>
1460 this->
nospace() <<
"QPair(" << pair.first <<
',' << pair.second <<
')';
1476 template <
class T1,
class T2>
1480 this->
nospace() <<
"std::pair(" << pair.first <<
',' << pair.second <<
')';
1496 template <
typename T>
1513 template <
typename T>
1517 this->
nospace() <<
"QContiguousCache(";
1518 for (
int i = cache.firstIndex(); i <= cache.lastIndex(); ++i) {
1519 (*this) << cache[i];
1520 if (i != cache.lastIndex())
1547 inline Logger(
const Logger& other) : stream(other.stream) { ++stream->ref; }
1560 if (
this != &other) {
1562 std::swap(stream, copy.stream);
1577 inline Logger&
space() { stream->space =
true; stream->ts <<
' ';
return *
this; }
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)) {}
1649 return _need_output;
1654 return _qDebug_is_handled;
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]")
1671 QString time_format;
1679 static Stamp& stamp() {
1680 static Stamp _stamp;
1686 : debug_callback(nullptr)
1687 , info_callback(nullptr)
1688 , warn_callback(nullptr)
1689 , err_callback(nullptr)
1690 , crit_callback(nullptr)
1700 static Callbacks& callbacks() {
1701 static Callbacks _callbacks;
1705 void putUcs4(uint ucs4) {
1707 stream->ts <<
"\\x" << hex << ucs4 << reset;
1708 }
else if (ucs4 < 0x80) {
1709 stream->ts << char(ucs4);
1712 stream->ts <<
"\\u" << qSetFieldWidth(4);
1714 stream->ts <<
"\\U" << qSetFieldWidth(8);
1715 stream->ts << hex << qSetPadChar(QLatin1Char(
'0')) << ucs4 << reset;
1719 template<Level> QString tag();
1720 template<Level>
void log(
const QString&);
1721 template<Level>
void callback(
const QString&);
1722 template<Level>
bool callback();
1724 template<Level level>
1725 inline void WriteLog(
const QString& msg) {
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;
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>();
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>()) {
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>() <<
' ';
1762 callback<level>(str);
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; };
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); };
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); };
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(); };
1793inline bool Logger::Initialize(
const QString &projectName,
const QString &logPrefix,
const QString &logDir)
1795 std::lock_guard<Mutex> lock(mutex);
1796#if !defined(LOGGER_SINGLE_THREAD)
1810 qInstallMessageHandler([](QtMsgType t,
const QMessageLogContext&,
const QString& str) {
1813 case QtWarningMsg:
Warn().
output() << str;
break;
1816 case QtInfoMsg:
Info().
output() << str;
break;
1820 qDebug_is_handled().store(
true, std::memory_order_release);
1825 qInstallMessageHandler(0);
1826 qDebug_is_handled().store(
false, std::memory_order_release);
1835 QSettings config(filePath, QSettings::IniFormat);
1836 auto logLevelVar = config.value(
"logLevel");
1837 if (logLevelVar.isValid()) {
1846 stamp().show_time.store(set);
1851 std::lock_guard<Mutex> lock(mutex);
1852 stamp().time_format = format;
1857 stamp().show_tag.store(set);
1862 std::lock_guard<Mutex> lock(mutex);
1863 stamp().debug_tag = tag;
1868 std::lock_guard<Mutex> lock(mutex);
1869 stamp().info_tag = tag;
1874 std::lock_guard<Mutex> lock(mutex);
1875 stamp().warn_tag = tag;
1880 std::lock_guard<Mutex> lock(mutex);
1881 stamp().err_tag = tag;
1886 std::lock_guard<Mutex> lock(mutex);
1887 stamp().crit_tag = tag;
1892 need_output().store(set);
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;
1907 std::lock_guard<Mutex> lock(mutex);
1908 callbacks().debug_callback = callback;
1913 std::lock_guard<Mutex> lock(mutex);
1914 callbacks().info_callback = callback;
1919 std::lock_guard<Mutex> lock(mutex);
1920 callbacks().warn_callback = callback;
1925 std::lock_guard<Mutex> lock(mutex);
1926 callbacks().err_callback = callback;
1931 std::lock_guard<Mutex> lock(mutex);
1932 callbacks().crit_callback = callback;
1968using namespace EZLog;
#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