我们在写一些小项目时,封装一个log类,无论是在debug,还是运行信息输出,都可以带来不小的便利。
1. 信息分类
我们的输出信息可能时debug信息,错误信息,或者是运行状态信息,所以,我们可以利用enum来对信息分类,方便后续的日志打印。
enum class LogLevel : int
{
Debug = 0,
Info = 1,
Error = 2,
Fatal = 3
};
2. 主体功能实现
主体功能放在Logger类中实现
class Logger
{
friend class Log;
public:
explicit Logger(LogLevel level = LogLevel::Info);
void ResetLogLevel(LogLevel level)
{
level_ = level;
}
void Write(LogLevel level, const char *format, ...);
void Debug(const char *format, ...);
void Info(const char *format, ...);
void Error(const char *format, ...);
void Fatal(const char *format, ...);
private:
void WriteImpl(LogLevel level, const char *format, va_list *val);
std::string GetSystemTime();
std::string GetLevelStr(LogLevel level);
LogLevel level_;
Logger(const Logger &);
void operator=(const Logger &);
};
其中,构造函数只是指明日志的内别,是Debug信息,Error信息亦或者其他信息。另外,真正的输出打印工作放在WriteImpl函数中,其实现如下:
inline void Logger::WriteImpl(LogLevel level, const char *format, va_list *val)
{
std::string level_str = GetLevelStr(level);
std::string time_str = GetSystemTime();
va_list val_copy;
va_copy(val_copy, *val);
printf("[%s] [%s] ", level_str.c_str(), time_str.c_str());
vprintf(format, *val);
fflush(stdout);
va_end(val_copy);
}
其中,所用到的GetLevelStr与GetSystemTime函数的函数名便描述了函数的功能。
3. 顶层接口
用户通过顶层类的接口,直接打印日志信息。
class Log
{
public:
static void ResetLogLevel(LogLevel level);
static void Write(LogLevel level, const char *format, ...);
static void Debug(const char *format, ...);
static void Info(const char *format, ...);
static void Error(const char *format, ...);
static void Fatal(const char *format, ...);
private:
static Logger logger_;
};
4. 代码实现
1. log.h
enum class LogLevel : int
{
Debug = 0,
Info = 1,
Error = 2,
Fatal = 3
};
class Logger
{
friend class Log;
public:
explicit Logger(LogLevel level = LogLevel::Info);
void ResetLogLevel(LogLevel level)
{
level_ = level;
}
void Write(LogLevel level, const char *format, ...);
void Debug(const char *format, ...);
void Info(const char *format, ...);
void Error(const char *format, ...);
void Fatal(const char *format, ...);
private:
void WriteImpl(LogLevel level, const char *format, va_list *val);
std::string GetSystemTime();
std::string GetLevelStr(LogLevel level);
LogLevel level_;
Logger(const Logger &);
void operator=(const Logger &);
};
class Log
{
public:
static void ResetLogLevel(LogLevel level);
static void Write(LogLevel level, const char *format, ...);
static void Debug(const char *format, ...);
static void Info(const char *format, ...);
static void Error(const char *format, ...);
static void Fatal(const char *format, ...);
private:
static Logger logger_;
};
2. log.cpp
Logger::Logger(LogLevel level) : level_(level)
{
}
void Logger::Write(LogLevel level, const char *format, ...)
{
va_list val;
va_start(val, format);
WriteImpl(level, format, &val);
va_end(val);
}
inline void Logger::WriteImpl(LogLevel level, const char *format, va_list *val)
{
std::string level_str = GetLevelStr(level);
std::string time_str = GetSystemTime();
va_list val_copy;
va_copy(val_copy, *val);
printf("[%s] [%s] ", level_str.c_str(), time_str.c_str());
vprintf(format, *val);
fflush(stdout);
va_end(val_copy);
}
std::string Logger::GetSystemTime()
{
time_t t = time(0);
char str[64];
strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", localtime(&t));
return str;
}
std::string Logger::GetLevelStr(LogLevel level)
{
switch (level)
{
case LogLevel::Debug:
return "DEBUG";
case LogLevel::Info:
return "INFO";
case LogLevel::Error:
return "ERROR";
case LogLevel::Fatal:
return "FATAL";
default:
return "UNKNOW";
}
}
Logger Log::logger_;
void Log::ResetLogLevel(LogLevel level)
{
logger_.ResetLogLevel(level);
}
void Log::Write(LogLevel level, const char *format, ...)
{
va_list val;
va_start(val, format);
logger_.WriteImpl(level, format, &val);
va_end(val);
}
void Log::Info(const char *format, ...)
{
va_list val;
va_start(val, format);
logger_.WriteImpl(LogLevel::Info, format, &val);
va_end(val);
}
void Log::Error(const char *format, ...)
{
va_list val;
va_start(val, format);
logger_.WriteImpl(LogLevel::Error, format, &val);
va_end(val);
}
void Log::Fatal(const char *format, ...)
{
va_list val;
va_start(val, format);
logger_.WriteImpl(LogLevel::Fatal, format, &val);
va_end(val);
}
void Log::Debug(const char *format, ...)
{
va_list val;
va_start(val, format);
logger_.WriteImpl(LogLevel::Debug, format, &val);
va_end(val);
}
标签:const,val,level,LogLevel,void,format,C++,日志
From: https://www.cnblogs.com/caieleven/p/17017057.html