Commit 7aea2be1 by 刘航

【CHG】不再按照日期创建文件夹。

【CHG】增加动态变更日志等级函数SLog::change_level
【CHG】spdlog_sample.cpp增加一些说明
1 parent 49db7b53
...@@ -34,4 +34,5 @@ ...@@ -34,4 +34,5 @@
.idea .idea
build build
build_mac
cmake-build-debug cmake-build-debug
cmake_minimum_required(VERSION 2.7) cmake_minimum_required(VERSION 2.7)
set(CMAKE_VERBOSE_MAKEFILE on) set(CMAKE_VERBOSE_MAKEFILE on)
project(clock_gettime_testor) project(spdlog_sample)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g ")
include_directories(.) include_directories(.)
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
......
...@@ -14,11 +14,24 @@ ...@@ -14,11 +14,24 @@
#include <spdlog/logger.h> #include <spdlog/logger.h>
#include <spdlog/fmt/fmt.h> #include <spdlog/fmt/fmt.h>
#include <spdlog/sinks/rotating_file_sink.h> #include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/daily_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h> #include <spdlog/sinks/stdout_color_sinks.h>
#include <map> #include <map>
#include <atomic> #include <atomic>
/*********************配置类宏,根据自己需求修改**********************************/
#define IS_ROTATING_MODE
#if defined(IS_ROTATING_MODE) // 循环模式,每个logger对应的文件大小LOG_SIZE MB,最多50个文件,循环利用,不需要清理
#define LOG_SIZE (1024*1024*10) #define LOG_SIZE (1024*1024*10)
#define MAX_FILES 50
#else // daily模式,每天每个logger生成一个新的文件。需要有清理逻辑
#define DAILY_HOUR 1
#define DAILY_MINUTE 0
#endif
/*****************************************************************************/
class SLog { class SLog {
public: public:
static void init(const std::string& logdir, const std::string& appname) ; static void init(const std::string& logdir, const std::string& appname) ;
...@@ -46,29 +59,28 @@ public: ...@@ -46,29 +59,28 @@ public:
} }
static void dump_trace(); static void dump_trace();
static void change_level(spdlog::level::level_enum log_level);
static void transto(std::string &x);
static void cleanup(); static void cleanup();
static void transto(std::string &x);
private: private:
static void monitor_thread(); static void monitor_thread();
static void makesure_dir(const std::string &path); static void makesure_dir(const std::string &path);
static std::string getymd(); static std::string getymd();
private:
static std::shared_ptr<spdlog::logger> m_globalLog; static std::shared_ptr<spdlog::logger> m_globalLog;
static std::map<std::string, std::shared_ptr<spdlog::logger>> m_trace; static std::map<std::string, std::shared_ptr<spdlog::logger>> m_trace;
static std::map<std::string, std::shared_ptr<spdlog::logger>> m_loggers; static std::map<std::string, std::shared_ptr<spdlog::logger>> m_loggers;
static std::string m_logdir; static std::string m_logdir;
static std::string m_appname; static std::string m_appname;
static std::string m_lastymd; static std::string m_lastymd;
static spdlog::level::level_enum m_sinkslevel;
static spdlog::level::level_enum m_level;
static std::atomic<int> m_state; static std::atomic<int> m_state;
static bool m_inited; static bool m_inited;
static std::mutex m_lock; static std::mutex m_lock;
}; };
//template <typename T, typename... Args>
//inline void cslog(const T &x, Args&&...args) throw()
template <typename... Args> template <typename... Args>
inline void cslog(std::string x, Args&&...args) throw() inline void cslog(std::string x, Args&&...args) throw()
{ {
......
...@@ -4,59 +4,53 @@ ...@@ -4,59 +4,53 @@
#include "spdlog/fmt/fmt.h" #include "spdlog/fmt/fmt.h"
#include "spdlog/fmt/bin_to_hex.h" #include "spdlog/fmt/bin_to_hex.h"
#define SLP_MS 1000
void thd() void thd()
{ {
// trace日志会缓存在内存 // trace日志会缓存在内存
while (1) { while (1) {
auto tr = SLog::get_trace("trace1"); auto tr = SLog::get_trace("trace1");
tr->trace("1"); tr->trace("1");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->trace("2"); tr->trace("2");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->trace("3"); tr->trace("3");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->trace("4"); tr->trace("4");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->trace("5"); tr->trace("5");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->trace("6"); tr->trace("6");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->trace("7"); tr->trace("7");
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
} }
} }
void thd2() void thd2()
{ {
while (1) { while (1) {
auto tr = SLog::get("log2"); auto tr = SLog::get("error_info");
tr->error("th2 1"); tr->error("th2 1");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->error("th2 2"); tr->error("th2 2");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->info("th2 3"); tr->info("th2 1");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->info("th2 4"); tr->info("th2 2");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
tr->info("th2 5");
std::this_thread::sleep_for(std::chrono::milliseconds(1));
tr->info("th2 6");
std::this_thread::sleep_for(std::chrono::milliseconds(1));
tr->info("th2 7");
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
} }
void thd3() void thd3()
{ {
while (1) { while (1) {
SLog::get("log2")->info("th3 1"); SLog::get("debuglog")->debug("th3 1");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
SLog::get("log2")->info("th3 2"); SLog::get("debuglog")->debug("th3 2");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
SLog::get("log2")->info("th3 3"); SLog::get("debuglog")->debug("th3 3");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
} }
} }
...@@ -64,11 +58,11 @@ void thd4() ...@@ -64,11 +58,11 @@ void thd4()
{ {
while (1) { while (1) {
SLog::global()->info("th4 1"); SLog::global()->info("th4 1");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
SLog::global()->info("th4 2"); SLog::global()->debug("th4 2");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
SLog::global()->info("th4 3"); SLog::global()->error("th4 3");
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(SLP_MS));
} }
} }
...@@ -81,19 +75,21 @@ int main() ...@@ -81,19 +75,21 @@ int main()
// 公共日志 // 公共日志
SLog::global()->info("I'm global {} {}", 1, "string"); SLog::global()->info("I'm global {} {}", 1, "string");
// 此函数是为了方便替换原有代码中的printf // 此函数是为了方便替换原有代码中的printf。会输出日志到[appname].log中
cslog("I'm global log too %d %s", 1, "string"); cslog("I'm global log too %d %s", 1, "string");
// 专属日志 // 专属日志,输出到subject.log
SLog::get("subject")->error("I'm {}", "subject"); SLog::get("subject")->error("I'm {}", "subject");
auto sublog = SLog::get("subject"); auto sublog = SLog::get("subject");
sublog->error("I'm {}", "subject"); sublog->error("I'm {}", "subject");
// 与sublog->info相比,写出的日志带行号文件名
SPDLOG_LOGGER_INFO(sublog, "with line filename");
SPDLOG_LOGGER_DEBUG(sublog, "with line filename");
// 专属日志,输出到./2222/subject.log
SLog::get("./2222/subject")->error("I'm {}", "2222"); SLog::get("./2222/subject")->error("I'm {}", "2222");
// 带行号文件名
SPDLOG_LOGGER_INFO(sublog, "with line filename");
// 额外赠送功能,string的format,fmtlib库 // 额外赠送功能,string的format,fmtlib库
std::string fmtstr; std::string fmtstr;
...@@ -101,19 +97,14 @@ int main() ...@@ -101,19 +97,14 @@ int main()
std::cout << fmtstr; std::cout << fmtstr;
// 打印二进制数据方法
unsigned char buffer[1024]; unsigned char buffer[1024];
//memset(buffer, 1024, 0);
// 打印二进制数据
sublog->info("binary: {}", spdlog::to_hex(std::begin(buffer), std::begin(buffer)+1024)); sublog->info("binary: {}", spdlog::to_hex(std::begin(buffer), std::begin(buffer)+1024));
//反初始化
SLog::cleanup(); SLog::cleanup();
SLog::get("subject")->error("after drop 1"); //创建多个线程同时写日志,SLP_MS改小增加日志量,测试性能
SLog::global()->info("after drop global");
//return 0;
auto th = std::thread(thd); auto th = std::thread(thd);
th.detach(); th.detach();
auto th2 = std::thread(thd2); auto th2 = std::thread(thd2);
...@@ -123,12 +114,24 @@ int main() ...@@ -123,12 +114,24 @@ int main()
auto th4 = std::thread(thd4); auto th4 = std::thread(thd4);
th4.detach(); th4.detach();
SLog::global()->info("输入dump回车,将trace日志打印到文件中"); SLog::global()->info("输入dump回车,将trace日志打印到文件中,输入debug、info、error动态更改日志等级");
while (1) { while (1) {
std::string input; std::string input;
std::cin >> input; std::cin >> input;
if (input == "dump") { if (input == "dump") {
SLog::dump_trace(); SLog::dump_trace();
} else if(input == "info") {
//动态变更日志等级至info
SLog::change_level(spdlog::level::info);
SLog::global()->critical("input:info");
} else if(input == "debug") {
//动态变更日志等级至debug
SLog::change_level(spdlog::level::debug);
SLog::global()->critical("input:debug");
} else if(input == "error") {
//动态变更日志等级至error
SLog::change_level(spdlog::level::err);
SLog::global()->critical("input:error");
} }
} }
} }
...@@ -23,6 +23,8 @@ std::map<std::string, std::shared_ptr<spdlog::logger>> SLog::m_loggers; ...@@ -23,6 +23,8 @@ std::map<std::string, std::shared_ptr<spdlog::logger>> SLog::m_loggers;
std::string SLog::m_logdir; std::string SLog::m_logdir;
std::string SLog::m_appname; std::string SLog::m_appname;
std::string SLog::m_lastymd = ""; std::string SLog::m_lastymd = "";
spdlog::level::level_enum SLog::m_sinkslevel = spdlog::level::trace;
spdlog::level::level_enum SLog::m_level = spdlog::level::info;
std::atomic<int> SLog::m_state(0); std::atomic<int> SLog::m_state(0);
bool SLog::m_inited = false; bool SLog::m_inited = false;
std::mutex SLog::m_lock; std::mutex SLog::m_lock;
...@@ -77,58 +79,27 @@ void SLog::makesure_dir(const std::string &path) ...@@ -77,58 +79,27 @@ void SLog::makesure_dir(const std::string &path)
} }
} }
void SLog::monitor_thread() {
while (1) {
std::string curymd = getymd();
if (curymd != m_lastymd) {
m_state = 1;
printf("spdlog::drop_all() ymd:%s, m_lastymd:%s", curymd.c_str(), m_lastymd.c_str());
m_lastymd = curymd;
spdlog::drop_all();
m_loggers.clear();
m_trace.clear();
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::debug);
std::string logname = m_logdir + "/" + getymd() + "/" + m_appname + getext(m_appname);
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, 100);
file_sink->set_level(spdlog::level::debug);
auto globallog = std::shared_ptr<spdlog::logger>(new spdlog::logger(m_appname, {console_sink, file_sink}));
m_globalLog.swap(globallog);
m_globalLog->set_level(spdlog::level::debug);
spdlog::set_pattern(_SPD_FORMAT_);
m_globalLog->set_pattern(fmt::format(_SPD_FORMAT_2, m_appname, "global"));
m_globalLog->info("rebuild spdlog success");
set_default_logger(m_globalLog);
m_state = 0;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
void SLog::init(const std::string &logdir, const std::string &appname) void SLog::init(const std::string &logdir, const std::string &appname)
{ {
m_logdir = logdir; m_logdir = logdir;
m_state = 0; m_state = 0;
m_appname = appname; m_appname = appname;
makesure_dir(logdir); makesure_dir(logdir);
makesure_dir(logdir + "/" + getymd());
m_lastymd = getymd();
std::thread th = std::thread(monitor_thread);
th.detach();
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::debug); console_sink->set_level(SLog::m_sinkslevel);
std::string logname = logdir + "/" + getymd() + "/" + appname + getext(appname); std::string logname = logdir + "/" + appname + getext(appname);
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, 100); #if defined(IS_ROTATING_MODE)
file_sink->set_level(spdlog::level::debug); auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, MAX_FILES);
#else
auto file_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt >(logname, DAILY_HOUR, DAILY_MINUTE);
#endif
file_sink->set_level(SLog::m_sinkslevel);
m_globalLog = std::shared_ptr<spdlog::logger>(new spdlog::logger(appname, {console_sink, file_sink})); m_globalLog = std::shared_ptr<spdlog::logger>(new spdlog::logger(appname, {console_sink, file_sink}));
m_globalLog->set_level(spdlog::level::debug);
spdlog::set_pattern(_SPD_FORMAT_); spdlog::set_pattern(_SPD_FORMAT_);
m_globalLog->set_pattern(fmt::format(_SPD_FORMAT_2, appname, "global")); m_globalLog->set_pattern(fmt::format(_SPD_FORMAT_2, appname, "global"));
m_globalLog->info("init spdlog success"); m_globalLog->info("init spdlog success");
set_default_logger(m_globalLog); set_default_logger(m_globalLog);
m_globalLog->set_level(m_level);
spdlog::flush_every(std::chrono::seconds(1)); spdlog::flush_every(std::chrono::seconds(1));
m_inited = true; m_inited = true;
} }
...@@ -143,13 +114,18 @@ std::shared_ptr<spdlog::logger> SLog::get(const std::string &name) ...@@ -143,13 +114,18 @@ std::shared_ptr<spdlog::logger> SLog::get(const std::string &name)
if (iter == m_loggers.end()) if (iter == m_loggers.end())
{ {
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::debug); console_sink->set_level(SLog::m_sinkslevel);
makesure_dir(m_logdir + "/" + getymd()); makesure_dir(m_logdir);
std::string logname = m_logdir + "/" + getymd() + "/" + name + getext(name); std::string logname = m_logdir + "/" + name + getext(name);
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, 300); #if defined(IS_ROTATING_MODE)
file_sink->set_level(spdlog::level::debug); auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, MAX_FILES);
#else
auto file_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt >(logname, DAILY_HOUR, DAILY_MINUTE);
#endif
file_sink->set_level(SLog::m_sinkslevel);
_logger = std::shared_ptr<spdlog::logger>(new spdlog::logger(name, {console_sink, file_sink})); _logger = std::shared_ptr<spdlog::logger>(new spdlog::logger(name, {console_sink, file_sink}));
_logger->set_pattern(fmt::format(_SPD_FORMAT_2, m_appname, name)); _logger->set_pattern(fmt::format(_SPD_FORMAT_2, m_appname, name));
_logger->set_level(m_level);
spdlog::register_logger(_logger); spdlog::register_logger(_logger);
m_loggers[name] = _logger; m_loggers[name] = _logger;
} }
...@@ -169,11 +145,13 @@ std::shared_ptr<spdlog::logger> SLog::get_trace(const std::string &name) ...@@ -169,11 +145,13 @@ std::shared_ptr<spdlog::logger> SLog::get_trace(const std::string &name)
if (iter == m_trace.end()) if (iter == m_trace.end())
{ {
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
// console_sink->set_level(spdlog::level::debug); makesure_dir(m_logdir );
makesure_dir(m_logdir + "/" + getymd()); std::string logname = m_logdir + "/" + name + getext(name);
std::string logname = m_logdir + "/" + getymd() + "/" + name + getext(name); #if defined(IS_ROTATING_MODE)
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, 100); auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logname, LOG_SIZE, MAX_FILES);
// file_sink->set_level(spdlog::level::debug); #else
auto file_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt >(logname, DAILY_HOUR, DAILY_MINUTE);
#endif
_logger = std::shared_ptr<spdlog::logger>(new spdlog::logger(name, {console_sink, file_sink})); _logger = std::shared_ptr<spdlog::logger>(new spdlog::logger(name, {console_sink, file_sink}));
_logger->set_pattern(fmt::format(_SPD_FORMAT_2, m_appname, name)); _logger->set_pattern(fmt::format(_SPD_FORMAT_2, m_appname, name));
_logger->enable_backtrace(512); _logger->enable_backtrace(512);
...@@ -197,6 +175,13 @@ void SLog::dump_trace() ...@@ -197,6 +175,13 @@ void SLog::dump_trace()
} }
} }
void SLog::change_level(spdlog::level::level_enum log_level)
{
m_level = log_level;
m_globalLog->set_level(log_level);
spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->set_level(log_level);l->critical("change level to {}", log_level);});
}
void SLog::transto(std::string &x) void SLog::transto(std::string &x)
{ {
for (std::size_t i = 0; i < x.length() - 1; i++) for (std::size_t i = 0; i < x.length() - 1; i++)
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!