#ifndef __LOGGER_H_
#define __LOGGER_H_
#include <iostream>
#include <atlstr.h>
#pragma warning(disable:4996)
#define LEVEL_FATAL 0
#define LEVEL_ERROR 1
#define LEVEL_WARN 2
#define LEVEL_INFO 3
#define LEVEL_VERBOSE 4
#define LEVEL_DEBUG 5
static int nLoggerLevel = LEVEL_INFO;
void SetLoggerLevel(int nLevel);
void Log(int nLevel, LPCSTR func, INT line, LPCTSTR fmt, ...);
static const char * const LOGGER_LEVEL_NAME[] = {"崩溃", "错误", "警告", "信息", "详细", "调试"};
static const char * const LOGGER_LEVEL_CODE[] = {"FATAL", "ERROR", "WARN ", "INFO ", "VERBOSE", "DEBUG"};
#define logging(nLevel, x, ...) \
Log(nLevel, __FUNCTION__, __LINE__, (x), __VA_ARGS__)
#define LOG_FATAL(x,...) logging(LEVEL_FATAL, (x), __VA_ARGS__)
#define LOG_ERROR(x,...) logging(LEVEL_ERROR, (x), __VA_ARGS__)
#define LOG_WARN(x, ...) logging(LEVEL_WARN, (x), __VA_ARGS__)
#define LOG_INFO(x, ...) logging(LEVEL_INFO, (x), __VA_ARGS__)
#define LOG_VERBOSE(x,...) logging(LEVEL_VERBOSE, (x), __VA_ARGS__)
#define LOG_DEBUG(x,...) logging(LEVEL_DEBUG, (x), __VA_ARGS__)
#endif
Logger.cpp
#include <stdafx.h>
#include <tchar.h>
#include "Logger.h"
void SetLoggerLevel(int nLevel)
{
if (LEVEL_DEBUG < nLevel || nLevel < LEVEL_FATAL)
{
LOG_WARN(_T("设置日志级别:%d 失败,默认INFO级别!"), nLevel);
return;
}
nLoggerLevel = nLevel;
LOG_INFO(_T("设置日志级别:%s 成功!"), LOGGER_LEVEL_NAME[nLevel]);
}
void Log(INT nLevel, LPCSTR func, INT line, LPCTSTR fmt, ...)
{
if (nLevel > nLoggerLevel)
return;
// 设置地域,不然fprintf写不了中文
setlocale(0, "chs");
FILE *fp = NULL;
TCHAR szLogFile[MAX_PATH] = {0};
va_list args;
va_start(args, fmt);
GetCurrentDirectory(MAX_PATH, szLogFile);
SYSTEMTIME sys;
GetLocalTime( &sys );
// 创建Log目录
_stprintf_s(szLogFile, _T("%s\\log\\"), szLogFile);
::_tmkdir(szLogFile);
_stprintf_s(szLogFile, _T("%s\\log_%4d%02d%02d.log"), szLogFile, sys.wYear, sys.wMonth, sys.wDay);
fopen_s(&fp, CW2A(szLogFile), "a+");
if (!fp)
{
TCHAR szOutput[MAX_PATH] = {0};
char errMsg[MAX_PATH] = { 0 };
strerror_s(errMsg, MAX_PATH, errno);
_stprintf_s(szOutput, _T("Open run log file[%s] error: %s\n"), szLogFile, (CA2T)errMsg);
OutputDebugString(szOutput);
return;
}
fprintf(fp, "[%4d/%02d/%02d %02d:%02d:%02d.%03d][%ld:%ld][%s]", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds,
GetProcessId(NULL), GetThreadId(NULL), LOGGER_LEVEL_CODE[nLevel]);
//fprintf( fp, "%s:Line%d ", func, line);
fprintf(fp, "%s ", func);
//_ftprintf(fp, fmt, args);
_vftprintf_s(fp, fmt, args);
fprintf( fp, "\n");
fclose(fp);
va_end(args);
}
代码经过较长时间的测试,可用性高。