-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial implementation of spdlog library with compatibility heade…
…rs and configuration helpers Signed-off-by: xiaoming <[email protected]>
- Loading branch information
1 parent
af64018
commit ba2e10a
Showing
120 changed files
with
27,631 additions
and
277 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
SOURCES += \ | ||
$$PWD/spdlog/src/async.cpp \ | ||
$$PWD/spdlog/src/bundled_fmtlib_format.cpp \ | ||
$$PWD/spdlog/src/cfg.cpp \ | ||
$$PWD/spdlog/src/color_sinks.cpp \ | ||
$$PWD/spdlog/src/file_sinks.cpp \ | ||
$$PWD/spdlog/src/spdlog.cpp \ | ||
$$PWD/spdlog/src/stdout_sinks.cpp \ | ||
$$PWD/qspdlogger.cpp | ||
|
||
HEADERS += \ | ||
$$PWD/qspdlogger.h | ||
|
||
INCLUDEPATH += \ | ||
$$PWD/spdlog/include \ | ||
$$PWD | ||
|
||
DEFINES += SPDLOG_COMPILED_LIB |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,329 @@ | ||
/* | ||
* This file is part of the https://github.com/QQxiaoming/quardCRT.git | ||
* project. | ||
* | ||
* Copyright (C) 2025 Quard <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
#include "qspdlogger.h" | ||
#include "spdlog/async.h" | ||
#include "spdlog/sinks/stdout_color_sinks.h" | ||
#include "spdlog/sinks/rotating_file_sink.h" | ||
#include "spdlog/sinks/basic_file_sink.h" | ||
#include "spdlog/sinks/udp_sink.h" | ||
#include "spdlog/sinks/tcp_sink.h" | ||
#include "spdlog/sinks/dist_sink.h" | ||
#include <QMutex> | ||
#include <QCoreApplication> | ||
#include <QMap> | ||
#include <QMessageLogContext> | ||
|
||
static const QMap<QtMsgType, spdlog::level::level_enum> level_map = { | ||
{QtDebugMsg, spdlog::level::debug}, | ||
{QtInfoMsg, spdlog::level::info}, | ||
{QtWarningMsg, spdlog::level::warn}, | ||
{QtFatalMsg, spdlog::level::err}, | ||
{QtCriticalMsg, spdlog::level::critical}, | ||
}; | ||
|
||
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) { | ||
spdlog::level::level_enum spd_level = spdlog::level::info; | ||
if(level_map.contains(type)) { | ||
spd_level = level_map[type]; | ||
} | ||
if(context.file == nullptr) { | ||
spdlog::source_loc loc = {"UnKnow", 0, "UnKnow"}; | ||
spdlog::log(loc, spd_level, msg.toStdString()); | ||
} else { | ||
spdlog::source_loc loc = {context.file, context.line, context.function}; | ||
spdlog::log(loc, spd_level, msg.toStdString()); | ||
} | ||
} | ||
|
||
QSpdLogger* QSpdLogger::self = nullptr; | ||
|
||
QSpdLogger* QSpdLogger::Instance() { | ||
if(!self) { | ||
QMutex muter; | ||
QMutexLocker clocker(&muter); | ||
|
||
if(!self) { | ||
self = new QSpdLogger(); | ||
} | ||
} | ||
return self; | ||
} | ||
|
||
void QSpdLogger::installMessageHandler() { | ||
try { | ||
spdlog::init_thread_pool(8192, 1); | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::make_shared<spdlog::sinks::dist_sink_mt>(); | ||
std::vector<spdlog::sink_ptr> sinks = {dist_sink}; | ||
std::shared_ptr<spdlog::logger> logger = std::make_shared<spdlog::async_logger>("QSpdLogger", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block); | ||
std::shared_ptr<spdlog::sinks::stdout_color_sink_mt> console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); | ||
dist_sink->add_sink(console_sink); | ||
spdlog::set_default_logger(logger); | ||
spdlog::set_level(spdlog::level::trace); | ||
setGlobalLogPattern(logPattern); | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
setGlobalLogPattern(logPattern); | ||
spdlog::log(spdlog::level::err, "TySpdLog initialization failed\n"); | ||
} | ||
qInstallMessageHandler(outputMessage); | ||
} | ||
|
||
void QSpdLogger::uninstallMessageHandler() { | ||
qInstallMessageHandler(nullptr); | ||
spdlog::drop_all(); | ||
} | ||
|
||
int QSpdLogger::addFileSink(QString filename, uint32_t max_size, uint32_t max_files) { | ||
try { | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto file_sink = std::dynamic_pointer_cast<spdlog::sinks::rotating_file_sink_mt>(*it)) { | ||
if (file_sink->filename() == filename.toStdString()) { | ||
return -1; | ||
} | ||
} | ||
if (auto file_sink = std::dynamic_pointer_cast<spdlog::sinks::basic_file_sink_mt>(*it)) { | ||
if (file_sink->filename() == filename.toStdString()) { | ||
return -1; | ||
} | ||
} | ||
} | ||
if(max_size == 0 || max_files == 0) { | ||
std::shared_ptr<spdlog::sinks::basic_file_sink_mt> file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename.toStdString()); | ||
file_sink->set_pattern(logPattern.toStdString()); | ||
dist_sink->add_sink(file_sink); | ||
} else { | ||
std::shared_ptr<spdlog::sinks::rotating_file_sink_mt> file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename.toStdString(), max_size, max_files); | ||
file_sink->set_pattern(logPattern.toStdString()); | ||
dist_sink->add_sink(file_sink); | ||
} | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
int QSpdLogger::removeFileSink(QString filename) { | ||
try { | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto file_sink = std::dynamic_pointer_cast<spdlog::sinks::rotating_file_sink_mt>(*it)) { | ||
if (file_sink->filename() == filename.toStdString()) { | ||
dist_sink->remove_sink(file_sink); | ||
return 0; | ||
} | ||
} | ||
if(auto file_sink = std::dynamic_pointer_cast<spdlog::sinks::basic_file_sink_mt>(*it)) { | ||
if (file_sink->filename() == filename.toStdString()) { | ||
dist_sink->remove_sink(file_sink); | ||
return 0; | ||
} | ||
} | ||
} | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
return -1; | ||
} | ||
return -1; | ||
} | ||
|
||
int QSpdLogger::addUdpSink(QString ip, uint16_t port) { | ||
try { | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto udp_sink = std::dynamic_pointer_cast<spdlog::sinks::udp_sink_mt>(*it)) { | ||
const spdlog::sinks::udp_sink_config config = udp_sink->config(); | ||
if (config.server_host == ip.toStdString() && config.server_port == port) { | ||
return -1; | ||
} | ||
} | ||
} | ||
std::shared_ptr<spdlog::sinks::udp_sink_mt> udp_sink = std::make_shared<spdlog::sinks::udp_sink_mt>(spdlog::sinks::udp_sink_config(ip.toStdString(), port)); | ||
udp_sink->set_pattern(logPattern.toStdString()); | ||
dist_sink->add_sink(udp_sink); | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
int QSpdLogger::removeUdpSink(QString ip, uint16_t port) { | ||
try { | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto udp_sink = std::dynamic_pointer_cast<spdlog::sinks::udp_sink_mt>(*it)) { | ||
const spdlog::sinks::udp_sink_config config = udp_sink->config(); | ||
if (config.server_host == ip.toStdString() && config.server_port == port) { | ||
dist_sink->remove_sink(udp_sink); | ||
return 0; | ||
} | ||
} | ||
} | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
return -1; | ||
} | ||
return -1; | ||
} | ||
|
||
int QSpdLogger::addTcpSink(QString ip, uint16_t port) { | ||
try { | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto tcp_sink = std::dynamic_pointer_cast<spdlog::sinks::tcp_sink_mt>(*it)) { | ||
const spdlog::sinks::tcp_sink_config config = tcp_sink->config(); | ||
if (config.server_host == ip.toStdString() && config.server_port == port) { | ||
return -1; | ||
} | ||
} | ||
} | ||
std::shared_ptr<spdlog::sinks::tcp_sink_mt> tcp_sink = std::make_shared<spdlog::sinks::tcp_sink_mt>(spdlog::sinks::tcp_sink_config(ip.toStdString(), port)); | ||
tcp_sink->set_pattern(logPattern.toStdString()); | ||
dist_sink->add_sink(tcp_sink); | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
int QSpdLogger::removeTcpSink(QString ip, uint16_t port) { | ||
try { | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto tcp_sink = std::dynamic_pointer_cast<spdlog::sinks::tcp_sink_mt>(*it)) { | ||
const spdlog::sinks::tcp_sink_config config = tcp_sink->config(); | ||
if (config.server_host == ip.toStdString() && config.server_port == port) { | ||
dist_sink->remove_sink(tcp_sink); | ||
return 0; | ||
} | ||
} | ||
} | ||
} catch (const spdlog::spdlog_ex &ex) { | ||
return -1; | ||
} | ||
return -1; | ||
} | ||
|
||
int QSpdLogger::setGlobalLogPattern(const QString &format) { | ||
logPattern = format; | ||
spdlog::set_pattern(logPattern.toStdString()); | ||
return 0; | ||
} | ||
|
||
void QSpdLogger::clearGlobalLogPattern(void) { | ||
spdlog::set_pattern("%v"); | ||
} | ||
|
||
void QSpdLogger::setLogLevel(QtMsgType level) { | ||
spdlog::level::level_enum spd_level = spdlog::level::info; | ||
if(level_map.contains(level)) { | ||
spd_level = level_map[level]; | ||
} | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
(*it)->set_level(spd_level); | ||
} | ||
} | ||
|
||
void QSpdLogger::setStdLogLevel(QtMsgType level) { | ||
spdlog::level::level_enum spd_level = spdlog::level::info; | ||
if(level_map.contains(level)) { | ||
spd_level = level_map[level]; | ||
} | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto console_sink = std::dynamic_pointer_cast<spdlog::sinks::stdout_color_sink_mt>(*it)) { | ||
console_sink->set_level(spd_level); | ||
} | ||
} | ||
} | ||
|
||
void QSpdLogger::setFileSinkLogLevel(QString filename, QtMsgType level) { | ||
spdlog::level::level_enum spd_level = spdlog::level::info; | ||
if(level_map.contains(level)) { | ||
spd_level = level_map[level]; | ||
} | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto file_sink = std::dynamic_pointer_cast<spdlog::sinks::rotating_file_sink_mt>(*it)) { | ||
if (file_sink->filename() == filename) { | ||
file_sink->set_level(spd_level); | ||
} | ||
} | ||
if (auto file_sink = std::dynamic_pointer_cast<spdlog::sinks::basic_file_sink_mt>(*it)) { | ||
if (file_sink->filename() == filename) { | ||
file_sink->set_level(spd_level); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void QSpdLogger::setUdpSinkLogLevel(QString ip, uint16_t port, QtMsgType level) { | ||
spdlog::level::level_enum spd_level = spdlog::level::info; | ||
if(level_map.contains(level)) { | ||
spd_level = level_map[level]; | ||
} | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto udp_sink = std::dynamic_pointer_cast<spdlog::sinks::udp_sink_mt>(*it)) { | ||
const spdlog::sinks::udp_sink_config config = udp_sink->config(); | ||
if (config.server_host == ip.toStdString() && config.server_port == port) { | ||
udp_sink->set_level(spd_level); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void QSpdLogger::setTcpSinkLogLevel(QString ip, uint16_t port, QtMsgType level) { | ||
spdlog::level::level_enum spd_level = spdlog::level::info; | ||
if(level_map.contains(level)) { | ||
spd_level = level_map[level]; | ||
} | ||
std::shared_ptr<spdlog::sinks::dist_sink_mt> dist_sink = std::dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(spdlog::default_logger()->sinks().front()); | ||
std::vector<spdlog::sink_ptr> sinks = dist_sink->sinks(); | ||
for (auto it = sinks.begin(); it != sinks.end(); ++it) { | ||
if (auto tcp_sink = std::dynamic_pointer_cast<spdlog::sinks::tcp_sink_mt>(*it)) { | ||
const spdlog::sinks::tcp_sink_config config = tcp_sink->config(); | ||
if (config.server_host == ip.toStdString() && config.server_port == port) { | ||
tcp_sink->set_level(spd_level); | ||
} | ||
} | ||
} | ||
} | ||
|
||
QSpdLogger::QSpdLogger(QObject *parent) : QObject(parent) { | ||
static QSpdLogger::GC gc; | ||
} | ||
|
||
QSpdLogger::~QSpdLogger() { } | ||
|
||
QSpdLogger::GC::~GC() { | ||
if (self != nullptr) { | ||
delete self; | ||
self = nullptr; | ||
} | ||
} |
Oops, something went wrong.