#ifndef _LOGGER_H_
#define _LOGGER_H_
#include <sstream>
class Logger
{
public:
typedef enum
{
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
FATAL,
LOGLEVEL_COUNT
}LogLevel;
Logger(const char *file, int line);
Logger(const char *file, int line, LogLevel level);
Logger(const char *file, int line, bool isAbort);
~Logger();
std::ostream& Stream();
static LogLevel GetLevel();
static void SetLevel(LogLevel level);
static void SetHandle(int fd);
static LogLevel _s_level;
static int _s_fd;
private:
void InitMsgHead(const char *file, int line, LogLevel level = TRACE);
private:
LogLevel _level;
int _fd;
std::ostringstream _stream;
};
#define LOG_TRACE if (Logger::GetLevel() <= Logger::TRACE) \
Logger(__FILE__, __LINE__, Logger::TRACE).Stream()
#define LOG_DEBUG if (Logger::GetLevel() <= Logger::DEBUG) \
Logger(__FILE__, __LINE__, Logger::DEBUG).Stream()
#define LOG_INFO if (Logger::GetLevel() <= Logger::INFO) \
Logger(__FILE__, __LINE__).Stream()
#define LOG_WARN Logger(__FILE__, __LINE__, Logger::WARN).Stream()
#define LOG_ERROR Logger(__FILE__, __LINE__, Logger::ERROR).Stream()
#define LOG_FATAL Logger(__FILE__, __LINE__, Logger::FATAL).Stream()
#define LOG_SYSERR Logger(__FILE__, __LINE__, false).Stream()
#define LOG_SYSFATAL Logger(__FILE__, __LINE__, true).Stream()
#endif // _LOGGER_H_
#include "Logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sstream>
/// for test
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
Logger::LogLevel Logger::_s_level = Logger::TRACE;
int Logger::_s_fd = 1;
Logger::Logger(const char *file, int line)
{
InitMsgHead(file, line);
}
Logger::Logger(const char *file, int line, LogLevel level)
{
InitMsgHead(file, line, level);
}
Logger::Logger(const char *file, int line, bool isAbort)
{
LogLevel level = (isAbort?FATAL:ERROR);
InitMsgHead(file, line, level);
}
Logger::~Logger()
{
std::string buf(_stream.str());
ssize_t num = ::write(_s_fd, buf.data(), buf.size());
if (_level == FATAL)
{
abort();
}
}
std::ostream& Logger::Stream()
{
return _stream;
}
Logger::LogLevel Logger::GetLevel()
{
return _s_level;
}
void Logger::SetLevel(LogLevel level)
{
_s_level = level;
}
void Logger::SetHandle(int fd)
{
_s_fd = fd;
}
void Logger::InitMsgHead(const char *file, int line, LogLevel level)
{
const char *logLevel[LOGLEVEL_COUNT] =
{"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
char msgHead[128] = {0};
time_t curtime = time(NULL);
struct tm *gm = localtime(&curtime);
const char *pstr = strrchr(file, '/');
const char *name = ((pstr!=NULL) ? pstr+1 : file);
_level = level;
snprintf(msgHead, sizeof(msgHead), "[%s\t%04d-%02d-%02d %02d:%02d:%02d %s:%03d]",
logLevel[_level], gm->tm_year+1900, gm->tm_mon+1, gm->tm_mday,
gm->tm_hour, gm->tm_min, gm->tm_sec, name, line);
_stream << msgHead;
}
/////////////////////////test pass//////////////////////////////
int main(void)
{
/*int fd = open("./log.txt", O_RDWR|O_CREAT|O_APPEND);
if (-1 == fd)
{
printf("open error\n");
}
Logger::SetHandle(fd);
Logger::SetLevel(Logger::ERROR);
*/
LOG_TRACE << "this is trace\n";
printf("\n");
LOG_WARN << "this is warning\n";
printf("\n");
LOG_ERROR << "this is error\n";
printf("\n");
LOG_SYSERR << "this is system\n";
printf("\n");
//LOG_SYSFATAL << "this is sysfatal\n";
//printf("\n");
LOG_WARN << "this is last\n";
getchar();
return 0;
}
//*////////////////////////////////////////////////////////////////
日志监视,当日志文件大小超过1M的时候关闭文件改名保存起来,用相同的路径名重新创建一个日志文件写入日志
int InitLog()
{
int fd = open(AUDIT_LOG_FILE, O_RDWR|O_CREAT|O_APPEND);
if (-1 == fd)
{
return -1;
}
Logger::SetHandle(fd);
Logger::SetLevel(Logger::DEBUG);
Logger::SetProcname("hello");
return 0;
}
/**
* 监视日志文件
* @param void
* @return void
*/
void WatchAuditLog()
{
char mvCmd[256] = {0};
struct stat logStat;
if (fstat(Logger::_s_fd, &logStat))
{
return;
}
if (logStat.st_size > (1024*1024))
{
close(Logger::_s_fd);
snprintf(mvCmd, sizeof(mvCmd), "mv %s %s", AUDIT_LOG_FILE, AUDIT_LOG_FILE_BAK);
if (system(mvCmd) < 0)
{
return;
}
InitLog();
}
}