首页 > 代码库 > (转)日志类
(转)日志类
#ifndef CLASSES_LOGGING_H__ #define CLASSES_LOGGING_H__ #include <iostream> #include <iomanip> #include <sstream> #include <Windows.h> #define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ TypeName(const TypeName&); void operator=(const TypeName&) enum LoggingSeverity { LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR, INFO = LS_INFO, WARNING = LS_WARNING, LERROR = LS_ERROR }; enum LogErrorContext { ERRCTX_NONE, ERRCTX_ERRNO, ERRCTX_HRESULT }; class LogMessage { public: LogMessage(const char* file, int line, LoggingSeverity sev, LogErrorContext err_ctx = ERRCTX_NONE, int err = 0, const char* module = NULL); ~LogMessage(); std::ostream& stream() { return print_stream_; } static void ResetTimestamps(); private: static const char* Describe(LoggingSeverity sev); static const char* DescribeFile(const char* file); static long TimeDiff(unsigned long later, unsigned long earlier); static bool TimeIsBetween(unsigned long later, unsigned long middle, unsigned long earlier); std::ostringstream print_stream_; LoggingSeverity severity_; std::string extra_; static unsigned long start_; HANDLE hFile_; DISALLOW_EVIL_CONSTRUCTORS(LogMessage); }; #define LOG_INFO() LogMessage(__FILE__, __LINE__, LS_INFO).stream() #define LOG(sev) LogMessage(__FILE__, __LINE__, sev).stream() #define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " #define PLOG(sev, err) LogMessage(__FILE__, __LINE__, sev, ERRCTX_ERRNO, err).stream() #define LOG_ERR(sev) LogMessage(__FILE__, __LINE__, sev, ERRCTX_ERRNO, errno).stream() #define LOG_GLE(sev) LogMessage(__FILE__, __LINE__, sev, \ ERRCTX_HRESULT, GetLastError()).stream() #define LOG_GLEM(sev, mod) LogMessage(__FILE__, __LINE__, sev, \ ERRCTX_HRESULT, GetLastError(), mod) .stream() #endif
#include "logging.h" extern "C" BOOL WINAPI IsDebuggerPresent(void); unsigned long LogMessage::start_ = GetTickCount(); LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev, LogErrorContext err_ctx, int err, const char* module) : severity_(sev) { unsigned long time = TimeDiff(GetTickCount(), start_); print_stream_ << "[" << std::setfill(‘0‘) << std::setw(3) << (time / 60000) << ":" << std::setw(2) << (time %60000)/1000 << ":" << std::setw(3) << time %1000 << std::setfill(‘ ‘) << "] "; DWORD id = GetCurrentThreadId(); print_stream_ << "[0x" << std::setfill(‘0‘) << std::setw(8) << std::hex << id << std::dec << "] "; print_stream_ << Describe(sev) << "(" << DescribeFile(file) << ":" << line << "): "; if (err_ctx != ERRCTX_NONE) { std::ostringstream tmp; tmp << "[0x" << std::setfill(‘0‘) << std::hex << std::setw(8) << err << "]"; switch (err_ctx) { case ERRCTX_ERRNO: { tmp << " " << strerror(err); break; } case ERRCTX_HRESULT: { char msgbuf[256]={0}; DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; HMODULE hmod = GetModuleHandleA(module); if (hmod) flags |= FORMAT_MESSAGE_FROM_HMODULE; if (DWORD len = FormatMessageA( flags, hmod, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), NULL)) { while ((len > 0) && isspace(static_cast<unsigned char>(msgbuf[len-1]))) { msgbuf[--len] = 0; } tmp << " " << msgbuf; } break; } default: break; } extra_ = tmp.str(); } } LogMessage::~LogMessage() { if (!extra_.empty()) print_stream_ << " : " << extra_; print_stream_ << "\r\n"; const std::string& str = print_stream_.str(); static bool debugger_present = (IsDebuggerPresent() != FALSE); if (debugger_present) { OutputDebugStringA(str.c_str()); } else { hFile_ = ::CreateFileA("Test.txt",GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE != hFile_) { unsigned long written=0L; ::SetFilePointer (hFile_, 0, NULL, FILE_END); ::WriteFile(hFile_, str.data(), str.size(), &written, 0); FlushFileBuffers(hFile_); ::CloseHandle(hFile_); } else { hFile_ = NULL; } } } void LogMessage::ResetTimestamps() { start_ = GetTickCount(); } const char* LogMessage::Describe(LoggingSeverity sev) { switch (sev) { case LS_SENSITIVE: return "Sensitive"; case LS_VERBOSE: return "Verbose"; case LS_INFO: return "Info"; case LS_WARNING: return "Warning"; case LS_ERROR: return "Error"; default: return "<unknown>"; } } const char* LogMessage::DescribeFile(const char* file) { const char* end1 = ::strrchr(file, ‘/‘); const char* end2 = ::strrchr(file, ‘\\‘); if (!end1 && !end2) return file; else return (end1 > end2) ? end1 + 1 : end2 + 1; } bool LogMessage::TimeIsBetween(unsigned long later, unsigned long middle, unsigned long earlier) { if (earlier <= later) { return ((earlier <= middle) && (middle <= later)); } else { return !((later < middle) && (middle < earlier)); } } long LogMessage::TimeDiff(unsigned long later, unsigned long earlier) { unsigned long LAST = 0xFFFFFFFF; unsigned long HALF = 0x80000000; if (TimeIsBetween(earlier + HALF, later, earlier)) { if (earlier <= later) { return static_cast<long>(later - earlier); } else { return static_cast<long>(later + (LAST - earlier) + 1); } } else { if (later <= earlier) { return -static_cast<long>(earlier - later); } else { return -static_cast<long>(earlier + (LAST - later) + 1); } } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。