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
日志库
Definition Logger.h:106
static QString errmsg()
错误信息。当日志库初始化失败时用于获取错误信息。
static void Warn(const QString &msg)
在日志中记录warn等级的信息。
static void Debug(const QString &msg)
在日志中记录debug等级的信息。
static void Info(const QString &msg)
在日志中记录info等级的信息。
static void Critical(const QString &msg)
在日志中记录critical等级的信息。
static bool Initialize(const QString &project="Project", const QString &prefix="log", const QString &dir="Logs/", bool multi_thread=true)
日志库初始化。
static void Error(const QString &msg)
在日志中记录error等级的信息。
日志类
Definition Logger.h:446
static void SetDebugCallback(const Callback &callback)
设置debug等级回调,在记录debug等级的log时触发
Definition Logger.h:1905
Logger & nooutput()
返回不带输出的版本。
Definition Logger.h:1953
static Logger Warn()
创建warn等级日志实例。
Definition Logger.h:1939
std::function< void(const QString &)> Callback
回调函数类型
Definition Logger.h:455
Logger & operator<<(const QPair< T1, T2 > &pair)
流式输入QPair类型数据。
Definition Logger.h:1457
static void SetLogLevel(int level)
设置日志等级,只有等级高于设定的日志才会被处理。 当日志等级设置为 Log_Off 时,log关闭。
Definition Logger.h:1829
Logger & operator<<(const QByteArray &t)
流式输入QByteArray类型数据。
Definition Logger.h:1209
Logger & operator<<(char t)
流式输入char类型数据。
Definition Logger.h:987
static void SetDebugTag(const QString &tag)
设置debug等级标签。
Definition Logger.h:1860
bool autoInsertSpaces() const
返回当前自动插入空格的设定。
Definition Logger.h:1611
Logger & operator<<(const std::pair< T1, T2 > &pair)
流式输入std::pair类型数据。
Definition Logger.h:1477
static void SetCriticalTag(const QString &tag)
设置critical等级标签。
Definition Logger.h:1884
static void SetErrorCallback(const Callback &callback)
设置error等级回调,在记录info等级的log时触发
Definition Logger.h:1923
static void SetTimeStampFormat(const QString &format)
设置时间戳格式
Definition Logger.h:1849
static Logger Debug()
创建debug等级日志实例。
Definition Logger.h:1935
Logger & leveltag()
返回带等级标签的版本。
Definition Logger.h:1951
Logger & operator=(const Logger &other)
Logger赋值运算符。
Definition Logger.h:1559
Logger & operator<<(qint64 t)
流式输入qint64类型数据。
Definition Logger.h:1097
Logger & timestamp()
返回带时间戳的版本。
Definition Logger.h:1947
static void SetInfoTag(const QString &tag)
设置info等级标签。
Definition Logger.h:1866
Logger(const Logger &other)
Logger拷贝构造函数。
Definition Logger.h:1547
Logger & operator<<(const QVector< T > &vec)
流式输入QVector类型数据。
Definition Logger.h:1323
static void ReadConfig(const QString &filePath)
读取日志等级配置文件。配置文件应为ini格式, 该方法会读取键为"logLevel"的配置并应用。
Definition Logger.h:1833
static Logger Error()
创建error等级日志实例。
Definition Logger.h:1941
Logger & output()
返回带输出的版本。
Definition Logger.h:1955
Level
日志等级,分为6等,依次递增。只有等级高于设定的日志才会被输出。 默认为最低等级Log_Debug_Info,即打印全部等级的日志。
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()
根据当前的设置插入空格并返回日志实例。
Definition Logger.h:1600
Logger & operator<<(const std::vector< T, Alloc > &vec)
流式输入std::vector类型数据。
Definition Logger.h:1340
Logger & operator<<(QTextStreamManipulator m)
流式输入QTextStreamManipulator类型数据。
Definition Logger.h:1259
Logger & space()
向消息流中写入一个空格并返回日志实例,后续的写入操作会自动插入空格。
Definition Logger.h:1577
Logger & operator<<(const QSet< T > &set)
流式输入QSet类型数据。
Definition Logger.h:1497
Logger & notimestamp()
返回不带时间戳的版本。
Definition Logger.h:1945
Logger & operator<<(const QStringRef &t)
流式输入QStringRef类型数据。
Definition Logger.h:1170
Logger & operator<<(signed int t)
流式输入signed int类型数据。
Definition Logger.h:1049
static Logger Critical()
创建critical等级日志实例。
Definition Logger.h:1943
Logger & operator<<(const QString &t)
流式输入QString类型数据。
Definition Logger.h:1158
Logger & nospace()
关闭自动插入空格并返回日志实例。
Definition Logger.h:1588
Logger & operator<<(QLatin1String t)
流式输入QLatin1String类型数据。
Definition Logger.h:1197
Logger & operator<<(const void *t)
流式输入void*类型数据。
Definition Logger.h:1221
Logger(Level level)
Logger构造函数。
Definition Logger.h:1537
Logger & operator<<(double t)
流式输入double类型数据。
Definition Logger.h:1133
Logger & operator<<(const QContiguousCache< T > &cache)
流式输入QContiguousCache类型数据。
Definition Logger.h:1514
static void UninstallMessageHandler()
取消接管qDebug输出。
Definition Logger.h:1823
~Logger()
析构并处理log信息。
Definition Logger.h:910
static void SetUnifiedCallback(const Callback &callback)
设置统一回调,在记录任意等级的log时触发
Definition Logger.h:1895
static void SetShowLevelTag(bool set)
设置默认是否显示等级标签。
Definition Logger.h:1855
static void SetNeedOutput(bool set)
设置默认是否输出log信息。
Definition Logger.h:1890
Logger & operator<<(const std::map< Key, T, Compare, Alloc > &map)
流式输入std::map类型数据。
Definition Logger.h:1374
Logger & operator<<(signed long t)
流式输入signed long类型数据。
Definition Logger.h:1073
Logger & operator<<(signed short t)
流式输入signed short类型数据。
Definition Logger.h:999
Logger & operator<<(const QHash< Key, T > &hash)
流式输入QHash类型数据。
Definition Logger.h:1433
Logger & operator<<(const QMap< Key, T > &map)
流式输入QMap类型数据。
Definition Logger.h:1408
static void SetShowTimeStamp(bool set)
设置默认是否显示时间戳。
Definition Logger.h:1844
Logger & printSequentialContainer(Logger &logger, const char *which, const SequentialContainer &c)
打印顺序容器信息。
Definition Logger.h:1277
Logger & operator<<(const char *t)
流式输入char*类型数据。
Definition Logger.h:1145
static void SetCriticalCallback(const Callback &callback)
设置critical等级回调,在记录critical等级的log时触发
Definition Logger.h:1929
static QString errMsg()
错误信息。当日志系统初始化失败时用于获取错误信息。
Definition Logger.h:1803
Logger & operator<<(unsigned long t)
流式输入unsigned long类型数据。
Definition Logger.h:1085
Logger & operator<<(quint64 t)
流式输入quint64类型数据。
Definition Logger.h:1109
static void SetWarnCallback(const Callback &callback)
设置warn等级回调,在记录warn等级的log时触发
Definition Logger.h:1917
Logger & operator<<(const std::multimap< Key, T, Compare, Alloc > &map)
流式输入std::multimap类型数据。
Definition Logger.h:1391
Logger & operator<<(const QList< T > &list)
流式输入QList类型数据。
Definition Logger.h:1307
static bool Initialize(const QString &projectName="Project", const QString &logPrefix="log", const QString &logDir="Logs/")
初始化日志系统。
Definition Logger.h:1793
static void SetInfoCallback(const Callback &callback)
设置info等级回调,在记录info等级的log时触发
Definition Logger.h:1911
Logger & operator<<(QChar t)
流式输入QChar类型数据。
Definition Logger.h:963
static void InstallMessageHandler()
接管qDebug输出。
Definition Logger.h:1808
Logger & operator<<(QTextStreamFunction f)
流式输入QTextStreamFunction类型数据。
Definition Logger.h:1247
Logger & operator<<(unsigned int t)
流式输入unsigned int类型数据。
Definition Logger.h:1061
static Logger Info()
创建info等级日志实例。
Definition Logger.h:1937
static void SetErrorTag(const QString &tag)
设置error等级标签。
Definition Logger.h:1878
static Level logLevel()
返回当前日志等级。
Definition Logger.h:1831
Logger & operator<<(const std::list< T, Alloc > &list)
流式输入std::list类型数据。
Definition Logger.h:1357
Logger & operator<<(QStringView s)
流式输入QStringView类型数据。
Definition Logger.h:1184
Logger & operator<<(bool t)
流式输入bool类型数据。
Definition Logger.h:975
void setAutoInsertSpaces(bool set)
设置是否自动插入空格。
Definition Logger.h:1622
Logger & noleveltag()
返回不带等级标签的版本。
Definition Logger.h:1949
static void SetWarnTag(const QString &tag)
设置warn等级标签。
Definition Logger.h:1872
Logger & operator<<(float t)
流式输入float类型数据。
Definition Logger.h:1121
Logger & operator<<(unsigned short t)
流式输入unsigned short类型数据。
Definition Logger.h:1011
EZlog命名空间,避免命名冲突
Definition Logger.h:98
LOGGER_EXPORT null_mutex fake_mutex
null_mutex类型的mutex,在单线程模式中用于模拟mutex操作
LOGGER_EXPORT std::mutex real_mutex
std::mutex类型的mutex,在多线程模式中用于同步
spdlog前向声明
Definition Logger.h:80
空atomic
Definition Logger.h:242
T value
存储的值
Definition Logger.h:250
null_atomic()
value默认初始化。
Definition Logger.h:259
null_atomic(T new_value)
value用new_value初始化。
Definition Logger.h:269
T load(std::memory_order=std::memory_order_relaxed) const
模拟atomic load,直接返回存储值。
Definition Logger.h:280
void store(T new_value, std::memory_order=std::memory_order_relaxed)
模拟atomic store,直接赋值。
Definition Logger.h:291
空mutex
Definition Logger.h:207
void lock() const
空lock操作。
Definition Logger.h:215
void unlock() const
空unlock操作。
Definition Logger.h:223
bool try_lock() const
空try-lock操作。
Definition Logger.h:231