클라이언트가 프로그램 사용 중 오류가 발생했을 때 원인을 확인하기 위해 Log 정보를 텍스트 파일로 저장할 수 있도록 하는 것이 좋다.

 

검색으로 찾은 내용을 후에 다시 사용하기 위해 글로 작성해두려고 한다.

 

- 기존 코드로 실행하고 Log를 남겼을 때 문자열이 깨지는 현상이 있어 한 부분을 수정했다.

  -> 기존 코드 strLog += szLog;

       수정 후 : strLog += (Cstring)fmt;

  -> 혹은 Multibyte <-> Unicode 변환으로도 가능합니다.

 

 

 

<stdafx.h>

 

extern CCriticalSection g_criticalLog;
extern CCriticalSection g_criticalDbg;
extern CCriticalSection g_criticalExe;

//가변인수함수로 Log 함수 선언
void Log(int nType, const char* fmt, ...);
CString GetFilePath();

// Log Type
enum LogType
{
	Debug = 0,	//	디버그
	Normal,		//	정상
	End,		//	끝
	Error		//	에러
};

 

<stdafx.cpp>

 

CCriticalSection g_criticalLog;
CCriticalSection g_criticalExe;

void Log(int nType, const char* fmt, ...)
{
	g_criticalLog.Lock();

	static _TCHAR szLog[5096];

	FILE *fp = NULL;
	CTime tm = CTime::GetCurrentTime();

	CString strLog = _T("");
	CString strPath = _T("");

	va_list args; //가변 변수를 읽기 위한 포인터 변수
	SYSTEMTIME cur_time;

	if (fmt == NULL)
	{
		g_criticalLog.Unlock();
		return;
	}

	ZeroMemory(szLog, 5096);
	
    #if 0 Multibyte
	va_start(args, fmt);
	wvsprintf(szLog, (LPCWSTR)fmt, args);
	va_end(args);
    
    #else
    MultiByteToWideChar(CP_ACP, 0, fmt, -1, szLog, 1024);
    
    #endif
    

	strPath.Format(_T("%s\\MainLog\\%s"), GetFilePath(), tm.Format("%Y_%m_%d_%H.log"));

	fopen_s(&fp, (CStringA)strPath, "a+");

	GetLocalTime(&cur_time);

	strLog.Format(_T("%04d-%02d-%02d %02d:%02d:%02d:%03ld:"),
		cur_time.wYear,
		cur_time.wMonth,
		cur_time.wDay,
		cur_time.wHour,
		cur_time.wMinute,
		cur_time.wSecond,
		cur_time.wMilliseconds);

	if (fp != NULL)
	{
		switch (nType)
		{
		case Normal: strLog += _T("[NORMAL    ] : "); break;
		case Debug: strLog += _T("[DEBUG    ] : "); break;
		case End: strLog += _T("[End    ] : "); break;
		case Error: strLog += _T("[Error    ] : "); break;
		}

		strLog += (CString)szLog;

		fprintf(fp, "%s\r\n", (CStringA)strLog);
		fflush(fp);
		fclose(fp);
	}
	else
	{
		CString strErrorMsg;
		DWORD	dwErrNo = GetLastError();

		strErrorMsg.Format(_T("LOG FILE Open Fail : Code = [ %d ], "), dwErrNo);
	}

	g_criticalLog.Unlock();
}

CString GetFilePath()
{
	g_criticalExe.Lock();

	static TCHAR pBuf[256] = { 0, };

	memset(pBuf, NULL, sizeof(pBuf));

	GetModuleFileName(NULL, pBuf, sizeof(pBuf));

	CString strFilePath;

	strFilePath.Format(_T("%s"), pBuf);

	strFilePath = strFilePath.Left(strFilePath.ReverseFind(_T('\\')));

	g_criticalExe.Unlock();

	return strFilePath;
}

 

<사용 예>

 

Log(Normal, "프로그램이 정상적으로 작동 중입니다.");
Log(LogType::Normal, "프로그램이 정상적으로 작동 중입니다."); // LogType이 모호할 경우

+ Recent posts