본문 바로가기
Programming/Tips(C++,C#)

내 마음대로 짠 로그라이터

by 곰네Zip 2016. 10. 13.

일을하면서 로그를 남겨야 할 일이 많아서 이와 같이구현한다.

 

#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이 편리하니까)

 

그냥, 나중에 가변 파라미터 처리하는 메소드 쓸때 참조하면 좋다.

반응형

댓글