起因
偶然打印了一个超长的单行日志,发现glog进行了截断,后续的没有打印.
排查
排查后,发现是在源码里写死的.
可以在logging.cc 源文件里找到这个变量 kMaxLogMessageLen
cpp
// An arbitrary limit on the length of a single log message. This
// is so that streaming can be done more efficiently.
const size_t LogMessage::kMaxLogMessageLen = 30000;
struct LogMessage::LogMessageData {
LogMessageData();
int preserved_errno_; // preserved errno
// Buffer space; contains complete message text.
char message_text_[LogMessage::kMaxLogMessageLen+1];
const 的哦
解决
1.方案1: 修改代码后重新编译.
当然,可以解决问题,但是吧,有以下问题.
- 多长算够呢 ?
- 而且还要重新编译,现在用的动态库的话,还要替换库.
2.方案2: 自定义一个多次输出的处理函数
大概是这个意思,就是自己分成多条进行输出.
当然,还有更好的实现方式,暂时这样就行,只是一个处理思路.
cpp
string log_str;//超长的日志
constexpr int kMaxChunkSize = google::LogMessage::kMaxLogMessageLen - 100;
const size_t len = log_str.length();
const size_t total = (len + kMaxChunkSize - 1) / kMaxChunkSize; // 向上取整
for (size_t i = 0, pack = 1; i < len; i += kMaxChunkSize, ++pack) {
LOG(INFO) << "[" << pack << "/" << total << "] " << std::string_view(log_str.data() + i, std::min<size_t>(kMaxChunkSize, len - i));
// 标准低于C++17的话,考虑下substr
//LOG(INFO) << "[" << pack_i << "/" << total_packets << "]" << log_str.substr(i, max_length) << std::endl;
}
应该还有更好的处理方式,暂时不想深入这个库的原理.
其它具体形式优化上,推荐 宏定义形式的函数.
但是,最好别搞成普通调用函数,不然,输出的行号和实际日志位置就不一样了.