일을하면서 로그를 남겨야 할 일이 많아서 이와 같이구현한다.
#include <stdarg.h>
#include <stdio.h>
typedef enum {
NORMAL = 0,
WARNING = 1,
DEBUGMODE = 2,
} LogLevel; //로그레벨은
class CLogWriter{
public:
CLogWriter(){ }
~CLogWriter(){ }
//method
public:
void InitializeLogWriter(){ //로그라이터 설정
GetWorkDirectory(strCurPath); //현재 디렉토리 가져오는 함수
//로그 경로 만들기.
strLogPath.Format(_T("%s\\Log"), strCurPath);
if (::PathFileExists(strLogPath) == FALSE){
::CreateDirectory(strLogPath, NULL);
}
m_enCurLogLevel = (LogLevel)::GetPrivateProfileInt(_T("Logs"), _T("LogWriteLevel"), 0, strIniPath);
CTime curTime = CTime::GetTickCount();
//CONVLOG_YYYYMMDD_HH.log파일 형태로 파일명을 정하기 위함
m_strLogFilePath.Format(_T("%s\\CONVLOG_%04d%02d%02d_%02d.log"), strLogPath,
curTime.GetYear(), curTime.GetMonth(), curTime.GetDay(), curTime.GetHour());
}
void WriteLog(LogLevel reqLogLevel, const TCHAR* strFormat, ...){
//요청된 로그 레벨이 현재 설정된 로그 레벨보다 낮으면 return
if (reqLogLevel > m_enCurLogLevel){ return; }
va_list Marker;
TCHAR szBuffer[1024];
memset(szBuffer, 0x00, sizeof(szBuffer));
va_start(Marker, strFormat);
//어차피 로그를 남기려면 문자열로 남겨야 하니까. 귀찮아서 그냥 vsprintf로..
vsprintf_s(szBuffer,sizeof(szBuffer), strFormat, Marker);
va_end(Marker);
CString strLogFormat;
CTime curTime = CTime::GetTickCount();
strLogFormat.Format(_T("[%04d/%02d/%02d %02d:%02d:%02d] %s\r\n"), curTime.GetYear(), curTime.GetMonth(), curTime.GetDay(), curTime.GetHour(), curTime.GetMinute(), curTime.GetSecond(), szBuffer);
WriteLogToFile(strLogFormat);
}
private:
//실제 파일에 기록하기
void WriteLogToFile(const CString& strLogString){
if (m_strLogFilePath.IsEmpty() == true){ InitializeLogWriter(); }
CFile file;
int flag = CFile::modeWrite;
//파일이 존재하지 않을 경우에만 modeCreate를 덧붙인다. 아닐경우 마지막 로그만 남음.
if (::PathFileExists(m_strLogFilePath) == FALSE){
flag = flag | CFile::modeCreate;
}
file.Open(m_strLogFilePath, flag);
file.SeekToEnd(); //파일 마지막에 덧붙이기 위함.
file.Write(strLogString, strLogString.GetLength() * sizeof(TCHAR)); //char의 크기를 정확하게 알수없으므로 무조건 TCHAR의 크기만큼 곱한다.
file.Close();
}
//variables
private:
LogLevel m_enCurLogLevel;
CString m_strLogFilePath;
};
근데.. 뭐.. 요즘은 log4시리즈등.. 워낙 좋은 로그 라이브러리가 많아서.. 더이상 쓸일은.. (사실 C#은 log4net이 편리하니까)
그냥, 나중에 가변 파라미터 처리하는 메소드 쓸때 참조하면 좋다.
반응형
댓글