#include "log.h"
|
#include <atomic>
|
#include <boost/log/core.hpp>
|
#include <boost/log/expressions.hpp>
|
#include <boost/log/sinks/text_file_backend.hpp>
|
#include <boost/log/sources/record_ostream.hpp>
|
#include <boost/log/sources/severity_logger.hpp>
|
#include <boost/log/trivial.hpp>
|
#include <boost/log/utility/setup/common_attributes.hpp>
|
#include <boost/log/utility/setup/console.hpp>
|
#include <boost/log/utility/setup/file.hpp>
|
#include <execinfo.h>
|
|
namespace ns_log
|
{
|
|
namespace logging = boost::log;
|
namespace src = boost::log::sources;
|
namespace sinks = boost::log::sinks;
|
namespace keywords = boost::log::keywords;
|
|
std::string TimeStamp()
|
{
|
char buf[64] = {0};
|
timeval tv = {0};
|
gettimeofday(&tv, 0);
|
tm r = {0};
|
localtime_r(&tv.tv_sec, &r);
|
int n = snprintf(buf, sizeof(buf) - 1, "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
|
r.tm_year + 1900, r.tm_mon + 1, r.tm_mday,
|
r.tm_hour, r.tm_min, r.tm_sec,
|
tv.tv_usec);
|
return std::string(buf, buf + n);
|
}
|
|
void GetTrace()
|
{
|
const int ntrace = 256;
|
void *buffer[ntrace];
|
char **strings;
|
int nptrs = backtrace(buffer, ntrace);
|
strings = backtrace_symbols(buffer, nptrs);
|
if (strings) {
|
LOG_DEBUG() << "[[[ call trace begin:";
|
MsgIndent(2);
|
for (int i = 0; i < nptrs; ++i) {
|
LOG_DEBUG() << strings[i];
|
}
|
free(strings);
|
MsgIndent(-2);
|
LOG_DEBUG() << "]]] call trace end.";
|
}
|
}
|
|
std::string LogPrefix(logging::trivial::severity_level level)
|
{
|
return "[" + TimeStamp() + "](" +
|
// logging::trivial::to_string(level) +
|
std::to_string(level) +
|
") " + MsgPrefix();
|
}
|
|
void AddLogRaw(const std::string &file_ptn, bool flush, bool with_console)
|
{
|
logging::add_file_log(
|
keywords::file_name = file_ptn,
|
keywords::open_mode = std::ios_base::app,
|
keywords::rotation_size = 1024 * 1024 * 50,
|
// keywords::target = "/tmp/bhshmq_logs",
|
// keywords::format = "[%TimeStamp%] %Severity% %Message%",
|
// keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0)
|
keywords::auto_flush = flush);
|
if (with_console) {
|
logging::add_console_log();
|
}
|
logging::add_common_attributes();
|
logging::core::get()->set_filter(logging::trivial::severity >= GetLogLevel());
|
}
|
void AddLog(const std::string &file_ptn, bool flush, bool with_console)
|
{
|
AddLogRaw(file_ptn, flush, with_console);
|
std::string hint;
|
for (int i = 0; i < 6; ++i) {
|
hint += "(" + std::to_string(i) + ")=" + logging::trivial::to_string(logging::trivial::severity_level(i)) + ", ";
|
}
|
BOOST_LOG_TRIVIAL(fatal) << "[" + TimeStamp() + "]*info* log levels: " << hint;
|
}
|
|
std::atomic<LogLevel> &CurLogLevel()
|
{
|
static std::atomic<LogLevel> cur(logging::trivial::info);
|
return cur;
|
}
|
|
LogLevel GetLogLevel() { return LogLevel(CurLogLevel().load()); }
|
|
LogLevel ResetLogLevel(LogLevel level, bool log_this)
|
{
|
if (log_this) {
|
BOOST_LOG_TRIVIAL(fatal) << "[" + TimeStamp() + "]*info* log level reset to " << level;
|
}
|
logging::core::get()->set_filter(logging::trivial::severity >= level);
|
return CurLogLevel().exchange(level);
|
}
|
|
} // namespace ns_log
|