BRPC日志

BRPC日志

BRPC关于日志的描述比较模糊,因此记录下BRPC中日志的使用,内容包括BRPC日志重定向,BRPC日志自定义日志格式,BRPC日志实现不同级别打印到不同的文件去

BRPC日志重定向

BRPC日志默认打印在STDERR,但是可以重定向,也可以重新实现,先说最简单的重定向,只需要添加以下代码:

std::string log_path = "SB_YOYO.log";

::logging::LoggingSettings log_setting;  # 创建LoggingSetting对象进行设置
log_setting.log_file = log_path.c_str(); # 设置日志路径
log_setting.logging_dest = logging::LOG_TO_FILE; # 设置日志写到文件,不写的话不生效
::logging::InitLogging(log_setting);     # 应用日志设置

BRPC日志自定义格式

默认的BPRC日志格式如下:

I0716 17:09:08.911966 22206 core/listener.cpp:111] Create socket success.

但是默认个格式感觉有点长,其实我根本不需要毫秒,线程ID这种信息,所以需要去除这些信息。

BRPC日志支持自定义格式,只需要继承LogSink对象即可,示例如下:

FILE* bili_log = fopen("SB_YOYO.log", "a");

class BiliLogSink : public ::logging::LogSink
{
public:
    BiliLogSink();
    ~BiliLogSink();

    // 一定要写这个方法,用这个OnLogMessage去替换原本的方法,实现自定义日志格式
    bool OnLogMessage(int severity,
                      const char* file,
                      int line,
                      const butil::StringPiece& content)
    {
        // 写的方式模仿BRPC默认的OnLogMessage
        // 这里只写Linux下的日志,Windows参考BRPC/src/butil/logging.cc
        std::ostringstream os; // BRPC默认的就用的是ostringstream
  
        // 仅打印日志级别,文件,行数,日志内容
        os << severity << ' ' << file << ':' << line << ']' << content << '\n';
        
        // 大于ERROR级别的日志,都要打印到STDERR中去
        if (severity >= kAlwaysPrintErrorLevel) {
            fwrite(log.data(), log.size(), 1, stderr);
            fflush(stderr);
        }

        // 开始打日志,logging_destination这种东西都自己参考logging.cc定义下
        if ((logging_destination & LOG_TO_FILE) != 0) {
            // 为了线程安全,这种日志需要加锁,锁的实现我直接抄logging.cc了
            // BRPC内部logging.cc的锁是匿名空间的内容,外部是看不到的
            // 为了尽量不修改BRPC代码,自己抄一份锁
            LoggingLock::Init(LOCK_LOG_FILE, NULL);
            LoggingLock logging_lock;
            if (bili_log) {
                fwrite(log.data(), log.size(), 1, bili_log);
                fflush(bili_log_file);
            }
        }
        return true;
    }
};

继承了LogSink还不够,还需要再应用以下BRPC的日志,应用示例如下:

::logging::LogSink* new_sink = new BiliLogSink();
::logging::LogSink* old_sink = ::logging::SetLogSink(new_sink);
if (old_sink) {
    delete old_sink;
}

应用了之后,日志就会按照我们写的OnLogMessage进行打印,效果如下:

0 core/listener.cpp:111] Create socket success.

不同级别打印到不同文件

BRPC默认只打印到一个文件内,但是我希望INFO级别的日志打印到INFO.logERROR级别的日志打印到ERROR.log中去,怎么做?

我们其实还是可以通过继承LogSink进行编写自己的方法,只需要将刚才的代码修改一下即可:

FILE* bili_info_log = fopen("SB_YOYO.info.log", "a");
FILE* bili_error_log = fopen("SB_YOYO.error.log", "a");

class BiliLogSink : public ::logging::LogSink
{
public:
    BiliLogSink();
    ~BiliLogSink();

    // 一定要写这个方法,用这个OnLogMessage去替换原本的方法,实现自定义日志格式
    bool OnLogMessage(int severity,
                      const char* file,
                      int line,
                      const butil::StringPiece& content)
    {
        // 写的方式模仿BRPC默认的OnLogMessage
        // 这里只写Linux下的日志,Windows参考BRPC/src/butil/logging.cc
        std::ostringstream os; // BRPC默认的就用的是ostringstream
  
        // 仅打印日志级别,文件,行数,日志内容
        os << severity << ' ' << file << ':' << line << ']' << content << '\n';
        
        // 大于ERROR级别的日志,都要打印到STDERR中去
        if (severity >= kAlwaysPrintErrorLevel) {
            fwrite(log.data(), log.size(), 1, stderr);
            fflush(stderr);
        }

        // 开始打日志,logging_destination这种东西都自己参考logging.cc定义下
        if ((logging_destination & LOG_TO_FILE) != 0) {
            // 为了线程安全,这种日志需要加锁,锁的实现我直接抄logging.cc了
            // BRPC内部logging.cc的锁是匿名空间的内容,外部是看不到的
            // 为了尽量不修改BRPC代码,自己抄一份锁
            LoggingLock::Init(LOCK_LOG_FILE, NULL);
            LoggingLock logging_lock;
            if (bili_info_log && bili_error_log) {
                // 唯一不同的就是这里,根据日志级别不同,打印到不同文件就好了
                // 这样做的话,LogSetting中的log_file就没有设置的意义了,
                // 因为根本没用到
                if (severity == ::logging::BLOG_INFO) {
                    fwrite(log.data(), log.size(), 1, bili_info_log);
                    fflush(bili_info_log);
                } else if (severity == ::logging::BLOG_INFO) {
                    fwrite(log.data(), log.size(), 1, bili_error_log);
                    fflush(bili_error_log);
                }
            }
        }
        return true;
    }
};

你可能感兴趣的:(C++,BRPC)