lichao
2021-05-10 77a6c3512a44dfe6540dde71946e6484fe4f173f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#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