对glog日志库的封装与开关控制
glog是Google开发的一个C++日志库,功能强大但接口较为简单。在实际项目中,我们通常需要对glog进行二次封装,以便更好地控制日志输出。下面介绍一种常见的封装方法,实现日志开关功能。
基本封装思路
- 创建日志管理类:封装glog的初始化、关闭和日志级别控制
- 添加开关控制:通过配置文件或运行时参数控制日志输出
- 提供便捷接口:简化常用日志操作
示例实现代码
#include <glog/logging.h>
#include <string>
class GlogWrapper {
public:
// 初始化glog
static void Initialize(const std::string& program_name,
const std::string& log_dir,
int stderr_log_level = google::INFO,
bool enable_log_to_stderr = true) {
google::InitGoogleLogging(program_name.c_str());
FLAGS_log_dir = log_dir;
FLAGS_stderrthreshold = stderr_log_level;
FLAGS_alsologtostderr = enable_log_to_stderr;
// 默认开启所有级别的日志
SetLogLevel(google::INFO);
}
// 设置全局日志级别
static void SetLogLevel(int level) {
if (level >= google::INFO && level <= google::FATAL) {
FLAGS_minloglevel = level;
m_current_level = level;
}
}
// 获取当前日志级别
static int GetLogLevel() {
return m_current_level;
}
// 关闭特定模块的日志
static void DisableModuleLog(const std::string& module) {
google::AddLogSink(new NullLogSink(module));
}
// 关闭所有日志输出
static void DisableAllLogs() {
SetLogLevel(google::FATAL + 1); // 设置为比FATAL更高的级别
}
// 恢复所有日志输出
static void EnableAllLogs(int level = google::INFO) {
SetLogLevel(level);
}
private:
static int m_current_level;
// 用于禁用特定模块的空的LogSink实现
class NullLogSink : public google::LogSink {
public:
explicit NullLogSink(const std::string& module) : m_module(module) {}
void send(google::LogSeverity severity, const char* full_filename,
const char* base_filename, int line,
const struct ::tm* tm_time,
const char* message, size_t message_len) override {
if (strstr(full_filename, m_module.c_str()) != nullptr) {
return; // 丢弃该模块的日志
}
// 其他模块的日志正常处理(可选)
LogToStderr(severity, full_filename, line, tm_time, message, message_len);
}
private:
std::string m_module;
};
};
int GlogWrapper::m_current_level = google::INFO;
// 使用示例:
int main(int argc, char* argv[]) {
GlogWrapper::Initialize("my_program", "./logs");
LOG(INFO) << "This is an info message";
// 关闭DEBUG及以下级别的日志
GlogWrapper::SetLogLevel(google::WARNING);
LOG(DEBUG) << "This debug message won't be printed";
LOG(WARNING) << "This warning will be printed";
return 0;
}
gRPC服务中的集成应用
在gRPC服务中,可以结合上述封装实现更灵活的日志控制:
class MyServiceImpl final : public MyService::Service {
public:
Status MyMethod(...) override {
if (GlogWrapper::GetLogLevel() <= google:INFO) {
LOG(INFO) << "MyMethod called with params...";
}
...
}
Status AnotherMethod(...) override { ... }
};
// gRPC服务器启动时配置不同服务的详细程度不同:
void RunServer() {
GlogWrapper:Initialize("grpc_server", "/var/log/grpc");
if (config.disable_core_service_logs()) {
GlogWrapper:DisableModuleLog("core_service");
}
...
}
这种封装方式提供了细粒度的控制能力,可以根据实际需求动态调整各个组件和方法的详细程度。
内容由零声教学AI助手提供,问题来源于学员提问