Commit 7aea2be1 by 刘航

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

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