找到了一个LOGGER类,但是输出中文有点毛病,就修改了一下贴出来。
第二次修改将指针改为了智能指针,不用显式释放资源了。
/************************************************************************/
/* CLogger类 */
/************************************************************************/
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <memory>
#include <Windows.h>
#include <process.h>
namespace hangba
{
namespace logger
{
#ifndef tstring
#ifdef UNICODE
#define tstring wstring
#else
#define tstring string
#endif
#endif
#ifndef tostringstream
#ifdef UNICODE
#define tostringstream wostringstream
#else
#define tostringstream ostringstream
#endif
#endif
#ifndef tofstream
#ifdef UNICODE
#define tofstream wofstream
#else
#define tofstream ofstream
#endif
#endif
#ifndef tcout
#ifdef UNICODE
#define tcout wcout
#else
#define tcout cout
#endif
#endif
#ifndef tsetlocale
#ifdef UNICODE
#define tsetlocale _wsetlocale
#else
#define tsetlocale setlocale
#endif
#endif
#ifndef tctime_s
#ifdef UNICODE
#define tctime_s _wctime_s
#else
#define tctime_s ctime_s
#endif
#endif
#define LOG_ERROR(x) CLogger::GetInstance()->error(x)
#define LOG_ALARM(x) CLogger::GetInstance()->alarm(x)
#define LOG_ALWAYS(x) CLogger::GetInstance()->always(x)
#define LOG_INFO(x) CLogger::GetInstance()->info(x)
#define LOG_BUFFER(x) CLogger::GetInstance()->buffer(x)
#define LOG_TRACE(x) CLogger::GetInstance()->trace(x)
#define LOG_DEBUG(x) CLogger::GetInstance()->debug(x)
typedef enum LOG_LEVEL
{
DISABLE_LOG = 1,
LOG_LEVEL_INFO,
LOG_LEVEL_BUFFER,
LOG_LEVEL_TRACE,
LOG_LEVEL_DEBUG,
ENABLE_LOG,
} LogLevel;
typedef enum LOG_TYPE
{
NO_LOG = 1,
CONSOLE,
FILE_LOG,
} LogType;
class CLogger
{
public:
static CLogger* GetInstance() throw();
void error(const _TCHAR *text) throw();
void error(std::tstring& text) throw();
void error(std::tostringstream& stream) throw();
void alarm(const _TCHAR *text) throw();
void alarm(std::tstring& text) throw();
void alarm(std::tostringstream& stream) throw();
void always(const _TCHAR *text) throw();
void always(std::tstring& text) throw();
void always(std::tostringstream& stream) throw();
void buffer(const _TCHAR *text) throw();
void buffer(std::tstring& text) throw();
void buffer(std::tostringstream& stream) throw();
void info(const _TCHAR *text) throw();
void info(std::tstring& text) throw();
void info(std::tostringstream& stream) throw();
void trace(const _TCHAR *text) throw();
void trace(std::tstring& text) throw();
void trace(std::tostringstream& stream) throw();
void debug(const _TCHAR *text) throw();
void debug(std::tstring& text) throw();
void debug(std::tostringstream& stream) throw();
void UpdateLogLevel(LogLevel level);
void EnableLog();
void DisableLog();
void UpdateLogType(LogType type);
void EnableConsoleLogging();
void EnableFileLogging();
CLogger();
~CLogger();
protected:
void lock();
void unlock();
std::tstring GetCurrentTime();
private:
void LogIntoFile(std::tstring& data);
void LogOnConsole(std::tstring& data);
CLogger(const CLogger& obj) {}
void operator=(const CLogger& obj) {}
private:
static std::auto_ptr<CLogger> m_Instance;
std::tofstream m_File;
LogLevel m_LogLevel;
LogType m_LogType;
CRITICAL_SECTION m_Mutex;
};
}
}
#include "stdafx.h"
#include "Logger.h"
#include <stdio.h>
#include <time.h>
using namespace std;
using namespace hangba::logger;
std::auto_ptr<CLogger> CLogger::m_Instance;
const tstring strLogFileName = _T("logfile.log");
CLogger::CLogger()
{
m_File.open(strLogFileName.c_str(), ios::out | ios::app);
m_File.imbue(locale(""));
m_LogLevel = LOG_LEVEL_TRACE;
m_LogType = FILE_LOG;
InitializeCriticalSection(&m_Mutex);
}
CLogger::~CLogger()
{
m_File.close();
m_File.clear();
DeleteCriticalSection(&m_Mutex);
}
CLogger* CLogger::GetInstance() throw()
{
if (m_Instance.get() == NULL)
{
m_Instance.reset(new CLogger());
}
return m_Instance.get();
}
void CLogger::lock()
{
EnterCriticalSection(&m_Mutex);
}
void CLogger::unlock()
{
LeaveCriticalSection(&m_Mutex);
}
void CLogger::LogIntoFile(std::tstring& data)
{
lock();
m_File << GetCurrentTime() << _T(" ") << data << endl;
unlock();
}
void CLogger::LogOnConsole(std::tstring& data)
{
lock();
tcout << GetCurrentTime() << _T(" ") << data << endl;
unlock();
}
tstring CLogger::GetCurrentTime()
{
time_t now = time(0);
tstring strCurTime;
_TCHAR t[128];
tctime_s(t, 128, &now);
strCurTime.assign(t);
tstring strRet = strCurTime.substr(0, strCurTime.size() - 1);
return strRet;
}
void CLogger::error(const _TCHAR *text) throw()
{
tstring data;
data.append(_T("[ERROR]: "));
data.append(text);
if (m_LogType == FILE_LOG)
{
LogIntoFile(data);
}
else if (m_LogType == CONSOLE)
{
LogOnConsole(data);
}
}
void CLogger::error(std::tstring& text) throw()
{
error(text.data());
}
void CLogger::error(std::tostringstream& stream) throw()
{
tstring text = stream.str();
error(text.data());
}
void CLogger::alarm(const _TCHAR *text) throw()
{
tstring data;
data.append(_T("[ALARM]: "));
data.append(text);
if (m_LogType == FILE_LOG)
{
LogIntoFile(data);
}
else if (m_LogType == CONSOLE)
{
LogOnConsole(data);
}
}
void CLogger::alarm(std::tstring& text) throw()
{
alarm(text.data());
}
void CLogger::alarm(std::tostringstream& stream) throw()
{
tstring text = stream.str();
alarm(text.data());
}
void CLogger::always(const _TCHAR *text) throw()
{
tstring data;
data.append(_T("[ALWAYS]: "));
data.append(text);
if (m_LogType == FILE_LOG)
{
LogIntoFile(data);
}
else if (m_LogType == CONSOLE)
{
LogOnConsole(data);
}
}
void CLogger::always(std::tstring& text) throw()
{
always(text.data());
}
void CLogger::always(std::tostringstream& stream) throw()
{
tstring text = stream.str();
always(text.data());
}
// 除了输出字符什么也不变
void CLogger::buffer(const _TCHAR *text) throw()
{
if (m_LogType == FILE_LOG && m_LogLevel >= LOG_LEVEL_BUFFER)
{
m_File << text << endl;
}
else if (m_LogType == CONSOLE && m_LogLevel >= LOG_LEVEL_BUFFER)
{
cout << text << endl;
}
}
void CLogger::buffer(std::tstring& text) throw()
{
buffer(text.data());
}
void CLogger::buffer(std::tostringstream& stream) throw()
{
tstring text = stream.str();
buffer(text.data());
}
void CLogger::info(const _TCHAR *text) throw()
{
tstring data;
data.append(_T("[INFO]: "));
data.append(text);
if (m_LogType == FILE_LOG)
{
LogIntoFile(data);
}
else if (m_LogType == CONSOLE)
{
LogOnConsole(data);
}
}
void CLogger::info(std::tstring& text) throw()
{
info(text.data());
}
void CLogger::info(std::tostringstream& stream) throw()
{
tstring text = stream.str();
info(text.data());
}
void CLogger::trace(const _TCHAR *text) throw()
{
tstring data;
data.append(_T("[TRACE]: "));
data.append(text);
if (m_LogType == FILE_LOG)
{
LogIntoFile(data);
}
else if (m_LogType == CONSOLE)
{
LogOnConsole(data);
}
}
void CLogger::trace(std::tstring& text) throw()
{
trace(text.data());
}
void CLogger::trace(std::tostringstream& stream) throw()
{
tstring text = stream.str();
trace(text.data());
}
void CLogger::debug(const _TCHAR *text) throw()
{
tstring data;
data.append(_T("[DEBUG]: "));
data.append(text);
if (m_LogType == FILE_LOG)
{
LogIntoFile(data);
}
else if (m_LogType == CONSOLE)
{
LogOnConsole(data);
}
}
void CLogger::debug(std::tstring& text) throw()
{
debug(text.data());
}
void CLogger::debug(std::tostringstream& stream) throw()
{
tstring text = stream.str();
debug(text.data());
}
void CLogger::UpdateLogLevel(LogLevel level)
{
m_LogLevel = level;
}
void CLogger::EnableLog()
{
m_LogLevel = ENABLE_LOG;
}
void CLogger::DisableLog()
{
m_LogLevel = DISABLE_LOG;
}
void CLogger::UpdateLogType(LogType type)
{
m_LogType = type;
if (m_LogType == FILE_LOG)
{
m_File.imbue(locale(""));
}
if (m_LogType == CONSOLE)
{
std::locale::global(std::locale(""));
}
}
void CLogger::EnableConsoleLogging()
{
std::locale::global(std::locale(""));
m_LogType = CONSOLE;
}
void CLogger::EnableFileLogging()
{
m_File.imbue(locale(""));
m_LogType = FILE_LOG;
}
自己测试过没有问题。