#ifndef nlog_h__
#define nlog_h__
/*
* nlog
* Email:<[email protected]>
* 異步
* 多線程安全
* Example:
* #include "nlog.h" //包含頭文件, 並連接對應的lib
* ...
* _NLOG_ERR("Hello, %s", "nlog") << " Now Time:" << nlog::time; //c,c++風格混搭格式化輸出
* ...
* _NLOG_SHUTDOWN(); //最後執行清理
*/
#include <map>
#include <sstream>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* export */
#ifdef NLOG_STATIC_LIB
# define NLOG_LIB
#else
#pragma warning( push )
#pragma warning( disable : 4251 )
#ifdef NLOG_SHARE_LIB
# define NLOG_LIB __declspec(dllexport)
#else
# define NLOG_LIB __declspec(dllimport)
#endif // NLOG_SHARE_LIB
#endif // NLOG_STATIC_LIB
class CIOCP;
class CSimpleLock;
namespace nlog{
/*
* 日誌等級
*/
enum LogLevel
{
LV_ERR = 0,
LV_WAR = 1,
LV_APP = 2,
LV_PRO = 3
};
/*
* 日誌配置數據結構
*/
struct Config
{
/*
* 日誌存儲目錄 default: "{module_dir}\\log\\"
* 可選變量:
* {module_dir} 當前可執行模塊目錄, 默認是程序的當前目錄
* %Y,%m,%d,%H ... 時間日期格式化
*/
std::wstring logDir;
/*
* 文件名格式 default: "log-%m%d-%H%M.log" 如(log-0805-2348.log)
* 可選變量:
* %Y,%m,%d,%H ... 時間日期格式化
*/
std::wstring fileName;
/*
* 日期格式 default: "%m-%d %H:%M:%S" 如(08-05 23:48:06)
* 可選變量:
* %Y(%y),%m,%d,%H,%M,%S 時間日期格式化 分別是 年,月,日,時,分,秒
*/
std::wstring dateFormat;
/*
* 前綴格式 default: "[{time}][{level}][{id}]: "
* 如([08-05 23:48:06][ERR][2F84 ]: )
* 可選變量:
* {module_dir} 當前可執行模塊目錄
* {level} 當前打印日誌的等級
* {time} 當前打印日誌的時間 格式由dateFormat指定
* {id} 當前打印日誌的線程id
* {file} 當前打印日誌的源文件名
* {line} 當前打印日誌的源文件行
*/
std::wstring prefixion;
};
/*
* 日誌類
*/
class NLOG_LIB CLog
{
CLog();
~CLog();
CLog(const CLog&);
CLog operator=(const CLog&);
friend class CLogHelper;
friend NLOG_LIB CLogHelper& time(CLogHelper& slef);
static std::map<std::string, CLog*> __Instances;
static std::auto_ptr<CSimpleLock> __pLock;
public:
/*
* 獲得一個Log的實例, 允許存在多個Log實例, guid代表實例的唯一Id
* 每一個實例獨佔一個日誌文件, 若它們之間具有相同的文件名稱格式
* 那麼後一個被實例化的Log將指向一個具有"_1"的名稱
*/
static CLog& Instance(std::string guid = "");
static bool Release (std::string guid = "");
static bool ReleaseAll();
/*
* Log配置, 輸出文件名稱格式, 打印格式等...
* 要注意的是, 設置必須在打印第一條日誌之前完成否則可能不起任何作用
*/
bool SetConfig(const Config& setting);
Config GetConfig() const;
/* 在任何時候都可以指定日誌打印的等級 */
void SetLevel(LogLevel level);
protected:
bool InitLog();
bool CompleteHandle(bool bClose = false);
struct LogInfomation
{
LogLevel level;
unsigned int line;
std::wstring file;
};
std::wstring Format (const std::wstring& strBuf, const LogInfomation& info = LogInfomation());
CLog& FormatWriteLog(const std::wstring& strBuf, const LogInfomation& info = LogInfomation());
CLog& WriteLog (const std::wstring& strBuf);
private:
CIOCP* __pIocp;
HANDLE __hFile;
Config __config;
bool __bAlreadyInit;
LogLevel __filterLevel;
unsigned int __count;
LARGE_INTEGER __liNextOffset;
};
/*
* 日誌格式化輔助類
*/
class NLOG_LIB CLogHelper
{
public:
CLogHelper(LogLevel level, const char* file, const unsigned int line, const std::string& guid = "");
~CLogHelper();
CLogHelper& Format();
CLogHelper& Format(const wchar_t * _Format, ...);
CLogHelper& Format(const char * _Format, ...);
template<class T>
CLogHelper& operator<<(T info);
CLogHelper& operator<<(const std::string& info);
CLogHelper& operator<<(CLogHelper&(__cdecl* pfn)(CLogHelper &));
friend NLOG_LIB CLogHelper& time(CLogHelper& slef);
friend NLOG_LIB CLogHelper& id (CLogHelper& slef);
private:
std::string __sessionId;
std::wstringstream __strbuf;
CLog::LogInfomation __logInfo;
};
template<class T>
CLogHelper& CLogHelper::operator<<(T info){
__strbuf << info;
return *this;
}
NLOG_LIB CLogHelper& time(CLogHelper& slef);
NLOG_LIB CLogHelper& id (CLogHelper& slef);
}// namespace nlog
#ifndef NLOG_STATIC_LIB
#pragma warning( pop )
#endif
/*
* 使用默認Log實例, 格式化輸出一條信息
* example:
* _NLOG_ERR("hello") << "nlog";
*/
#define _NLOG_ERR nlog::CLogHelper(nlog::LV_ERR, __FILE__, __LINE__).Format
#define _NLOG_WAR nlog::CLogHelper(nlog::LV_WAR, __FILE__, __LINE__).Format
#define _NLOG_APP nlog::CLogHelper(nlog::LV_APP, __FILE__, __LINE__).Format
#define _NLOG_PRO nlog::CLogHelper(nlog::LV_PRO, __FILE__, __LINE__).Format
/*
* 使用指定的Log實例, 格式化輸出一條信息
* example:
* #define LOG_UID "custom log id"
* #define LOG_ERR _NLOG_ERR_WITH_ID(LOG_UID)
* ...
* LOG_ERR("hello") << "nlog";
*/
#define _NLOG_ERR_WITH_ID(id) nlog::CLogHelper(nlog::LV_ERR, __FILE__, __LINE__, id).Format
#define _NLOG_WAR_WITH_ID(id) nlog::CLogHelper(nlog::LV_WAR, __FILE__, __LINE__, id).Format
#define _NLOG_APP_WITH_ID(id) nlog::CLogHelper(nlog::LV_APP, __FILE__, __LINE__, id).Format
#define _NLOG_PRO_WITH_ID(id) nlog::CLogHelper(nlog::LV_PRO, __FILE__, __LINE__, id).Format
/*
* 設置初始配置
* example:
*
* _NLOG_CFG cfg = {
* L"",
* L"nlog-%m%d%H%M.log",
* L"",
* L"[{time}][{level}][{id}][{file}:{line}]: "
* };
*
* _NLOG_SET_CONFIG(cfg);
*/
#define _NLOG_CFG nlog::Config
#define _NLOG_SET_CONFIG(cfg) nlog::CLog::Instance().SetConfig(cfg)
#define _NLOG_SET_CONFIG_WITH_ID(id, cfg) nlog::CLog::Instance(id).SetConfig(cfg)
/*
* 設置實時打印等級
* example: - 設置只打印警告及以上的日誌
*
* _NLOG_SET_LEVE(LV_WAR);
*/
#define _NLOG_SET_LEVE(lev) nlog::CLog::Instance().SetLevel(lev)
#define _NLOG_SET_LEVE_WITH_ID(id, lev) nlog::CLog::Instance(id).SetLevel(lev)
/*
* 執行清理工作, 銷燬所有存在的nlog實例
* example: - 初始配置與自動銷燬
*
* struct _NLogMgr
* {
* _NLogMgr()
* {
* _NLOG_CFG cfg = {
* L"",
* L"nlog-%m%d%H%M.log",
* L"",
* L"[{time}][{level}][{id}][{file}:{line}]: "
* };
*
* _NLOG_SET_CONFIG(cfg);
* }
*
* ~_NLogMgr() {
* _NLOG_SHUTDOWN();
* }
* };
*
* static _NLogMgr _NLog;
*/
#define _NLOG_SHUTDOWN nlog::CLog::ReleaseAll
#endif // nlog_h__
https://download.csdn.net/download/u011269801/12379124