标签:des style blog class code c
贵灯提供的简单打印函数,非原创;
注意:
do{}while(false); 的使用(内部多个判断,用 do false 中的 break 可以避免使用 if true 引起的嵌套层数过多);
关键段 CRITICAL_SECTION 的使用,封装了 lock 和 unlock 函数;
不定长参数 va_list 的使用;
#pragma once /* * 1. 简单日志:支持多字节和 unicode 工程, 线程安全, 生成的文件名有进程名称和进程id组成 * 2. 调用接口: LOG_INFO 为主要日志输出函数, LOG_ERROR 为打印 lastError 错误信息 * 3. 日志输出格式为:[9348] [5-15 9:55:44] [.\loggerTest.cpp - threadProc1 - 14] this is a test 其中:第一列 [9348] 为线程 id 第二列 [5-15 9:55:44] 为时间信息, 具体为月份日期小时分钟秒钟 弟三列 [.\loggerTest.cpp - threadProc1 - 14] 为所在对应文件对应函数对应代码行信息 第四列 this is a test 为具体日志信息 * */ #ifdef SIMPLE_LOGGER #include <windows.h> #include <assert.h> #include <shlwapi.h> #include <stdlib.h> #pragma comment(lib, "shlwapi.lib") #define MAX_LOGGER_BUFFER (1024) #define WIDEN2(x) L ## x #define WIDEN(x) WIDEN2(x) #define __WFILE__ WIDEN(__FILE__) #define __WFUNCTION__ WIDEN(__FUNCTION__) #ifdef _UNICODE #define __TFILE__ __WFILE__ #define __TFUNCTION__ __WFUNCTION__ #else #define __TFILE__ __FILE__ #define __TFUNCTION__ __FUNCTION__ #endif #define OutputDebugLastError() \ { DWORD errid = ::GetLastError(); TCHAR buf[MAX_PATH] = {0}; _stprintf_s(buf, sizeof(buf)/sizeof(TCHAR), _T("[%s - %s - %d] errorid=%d\n"), __TFILE__, __TFUNCTION__, __LINE__, errid); OutputDebugString(buf); } class Logger { public: Logger() { do { SECURITY_DESCRIPTOR secutityDese; BOOL bRes = ::InitializeSecurityDescriptor(&secutityDese, SECURITY_DESCRIPTOR_REVISION); if(!bRes) { OutputDebugLastError(); break; } bRes = ::SetSecurityDescriptorDacl(&secutityDese, TRUE, NULL, FALSE); if(!bRes) { OutputDebugLastError(); break; } SECURITY_ATTRIBUTES securityAttr; securityAttr.nLength = sizeof SECURITY_ATTRIBUTES; securityAttr.bInheritHandle = FALSE; securityAttr.lpSecurityDescriptor = &secutityDese; TCHAR szProcName[MAX_PATH] = {0}; if( 0 == ::GetModuleFileName(NULL, szProcName, sizeof(szProcName) ) ) { OutputDebugLastError(); break; } PathStripPath(szProcName); TCHAR szDir[MAX_PATH] = _T("c:\\SimpleLog"); ::CreateDirectory(szDir, &securityAttr); TCHAR szFileName[MAX_PATH] = {0}; _stprintf_s(szFileName, sizeof(szFileName)/sizeof(TCHAR), _T("%s\\%s[%u].log"), szDir, szProcName, ::GetCurrentProcessId() ); // 加上该描述符控制, 可以接受任何条件的访问 _hFile = ::CreateFile(szFileName, FILE_GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &securityAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(_hFile == INVALID_HANDLE_VALUE) { OutputDebugLastError(); break; } #ifdef _UNICODE DWORD dwWrited = 0; DWORD dwUnicode = 0xFEFF; bRes = WriteFile(_hFile, &dwUnicode, sizeof(DWORD), &dwWrited, NULL); if(!bRes || dwWrited != sizeof(DWORD)) { OutputDebugLastError(); break; } #endif } while (FALSE); ::InitializeCriticalSection(&_cs); } ~Logger() { if(_hFile != INVALID_HANDLE_VALUE) { ::CloseHandle(_hFile); _hFile = INVALID_HANDLE_VALUE; } ::DeleteCriticalSection(&_cs); } void LogPrint(LPCTSTR pszFormat) { if(_hFile != INVALID_HANDLE_VALUE && pszFormat != NULL) { DWORD dwWrite = _tcslen(pszFormat) * sizeof(TCHAR); DWORD dwWrited = 0; BOOL bRes = WriteFile(_hFile, pszFormat, dwWrite, &dwWrited, NULL); if(!bRes || dwWrite != dwWrited) { OutputDebugLastError(); } } } void lock() { ::EnterCriticalSection(&_cs); } void unlock() { ::LeaveCriticalSection(&_cs); } protected: private: HANDLE _hFile; CRITICAL_SECTION _cs; }; static Logger g_logger; inline void LogMessage(LPCTSTR pszFormat, ...) { assert(pszFormat != NULL); if(pszFormat != NULL) { TCHAR szMsg[MAX_LOGGER_BUFFER] = {0}; va_list pArg; va_start(pArg, pszFormat); _vstprintf_s(szMsg, sizeof(szMsg)/sizeof(TCHAR), pszFormat, pArg); va_end(pArg); g_logger.LogPrint(szMsg); } } #define LOG_INFO(x, ...) \ { g_logger.lock(); SYSTEMTIME st = {0}; GetSystemTime(&st); SYSTEMTIME stLocalTime = {0}; SystemTimeToTzSpecificLocalTime(NULL, &st, &stLocalTime); TCHAR szAppend[MAX_PATH] = {0}; _stprintf_s(szAppend, sizeof(szAppend)/sizeof(TCHAR), _T("[%u] [%d-%d %d:%d:%d] "), ::GetCurrentThreadId(), stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); LogMessage(szAppend); LogMessage(_T("[%s - %s - %d] "), __TFILE__, __TFUNCTION__, __LINE__); LogMessage(x, __VA_ARGS__); LogMessage(_T("\r\n") ); g_logger.unlock(); } #define LOG_ERROR() \ { DWORD errid = ::GetLastError(); TCHAR buf[MAX_PATH] = {0}; _stprintf_s(buf, sizeof(buf)/sizeof(TCHAR), _T("errorid=%d"), errid); LOG_INFO(buf); } #else #define LOG_INFO(x, ...) #define LOG_ERROR() #endif
标签:des style blog class code c
原文地址:http://www.cnblogs.com/zuibunan/p/3729474.html