최종완료보고 버전
This commit is contained in:
@@ -0,0 +1,535 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "Object.h"
|
||||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
#include "Logger.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
//#include <io.h>
|
||||
//#pragma warning(disable:4201)
|
||||
//#include <mmsystem.h>
|
||||
//#pragma warning(default:4201)
|
||||
//#pragma comment(lib, "winmm.lib")
|
||||
#include <time.h>
|
||||
#else
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
|
||||
|
||||
// my defines for portablity
|
||||
#ifdef _WIN32
|
||||
|
||||
#define ftime _ftime
|
||||
#define timeb _timeb
|
||||
#define vsnprintf _vsnprintf
|
||||
#define snprintf _snprintf
|
||||
|
||||
#define FILECRETEFAIL_CAPTION "HLogger Message"
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef SINGLE_THREADED_MODEL
|
||||
#if _MSC_VER <= 1200
|
||||
#define Lock() ((void)0)
|
||||
#define Unlock() ((void)0)
|
||||
#else
|
||||
#define Lock() __noop
|
||||
#define Unlock() __noop
|
||||
#endif
|
||||
#endif // SINGLE_THREADED_MODEL
|
||||
|
||||
|
||||
|
||||
HLogger * g_pLogFile__Logger = NULL;
|
||||
|
||||
|
||||
HLogger::HLogger()
|
||||
{
|
||||
m_fhLog = -1;
|
||||
m_nLevel = 0;
|
||||
m_flagOption = dayWrite | timeWrite;
|
||||
m_bIsContinue = false;
|
||||
m_nFileSplitSize = 0;
|
||||
m_nFileLimitSize = 0;
|
||||
m_nLogFileNameExt = 0;
|
||||
m_bIsFileNameChange = false;
|
||||
m_nSrcLine = 0;
|
||||
m_szPathName[0] = '\0';
|
||||
|
||||
#ifndef SINGLE_THREADED_MODEL
|
||||
#ifdef _WIN32
|
||||
InitializeCriticalSection(&m_csInstance);
|
||||
#else
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
#endif // _WIN32
|
||||
#endif // SINGLE_THREADED_MODEL
|
||||
|
||||
m_pExtension = NULL;
|
||||
|
||||
m_szWriteString = (char *)malloc(MD_MAX_STRING);
|
||||
m_szLogString = (char *)malloc(MD_MAX_STRING);
|
||||
m_szTmpString = (char *)malloc(MD_MAX_STRING);
|
||||
}
|
||||
|
||||
HLogger::~HLogger()
|
||||
{
|
||||
free(m_szWriteString);
|
||||
free(m_szLogString);
|
||||
free(m_szTmpString);
|
||||
|
||||
#ifndef SINGLE_THREADED_MODEL
|
||||
#ifdef _WIN32
|
||||
DeleteCriticalSection(&m_csInstance);
|
||||
#else
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
#endif // _WIN32
|
||||
#endif // SINGLE_THREADED_MODEL
|
||||
}
|
||||
|
||||
bool HLogger::Create(unsigned nLevel, bool bContinue,
|
||||
const char * szPathName, bool bIsBinary)
|
||||
{
|
||||
Lock();
|
||||
|
||||
m_bIsContinue = bContinue;
|
||||
m_bIsBinary = bIsBinary;
|
||||
bool bSuccess = OpenFile(nLevel, szPathName);
|
||||
|
||||
Unlock();
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void HLogger::Release()
|
||||
{
|
||||
Lock();
|
||||
|
||||
CloseFile();
|
||||
|
||||
m_nFileSplitSize = 0;
|
||||
m_nFileLimitSize = 0;
|
||||
m_nLogFileNameExt = 0;
|
||||
m_bIsFileNameChange = false;
|
||||
|
||||
if (m_pExtension)
|
||||
{
|
||||
delete m_pExtension;
|
||||
m_pExtension = NULL;
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
bool HLogger::OpenFile(unsigned nLevel, const char * szPathName)
|
||||
{
|
||||
if (m_fhLog != -1) return false;
|
||||
|
||||
m_nLevel = nLevel;
|
||||
|
||||
if (szPathName != NULL && !(szPathName[strlen(szPathName) - 1] == '/' ||
|
||||
szPathName[strlen(szPathName) - 1] == '\\'))
|
||||
{
|
||||
// Full Path Name ==> equal.
|
||||
if (m_szPathName[0] == '\0')
|
||||
{
|
||||
strncpy(m_szPathName, szPathName, MD_MAX_PATH - 1);
|
||||
m_szPathName[MD_MAX_PATH - 1] = '\0';
|
||||
}
|
||||
|
||||
strncpy(m_szLogFileName, szPathName, MD_MAX_PATH - 1);
|
||||
m_szLogFileName[MD_MAX_PATH - 1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bIsFileNameChange = true;
|
||||
|
||||
// Directory ==> log name is date. ex) Start("log/") = log/20030201.log
|
||||
if (szPathName != NULL && m_szPathName[0] == '\0')
|
||||
{
|
||||
strncpy(m_szPathName, szPathName, MD_MAX_PATH - 1);
|
||||
m_szPathName[MD_MAX_PATH - 1] = '\0';
|
||||
}
|
||||
|
||||
char szDay[MD_MAX_DATE];
|
||||
|
||||
GetDateTime(szDay, NULL);
|
||||
sprintf(m_szLogFileName, "%s%s.log", m_szPathName, szDay);
|
||||
|
||||
strncpy(m_szPrevDate, szDay, MD_MAX_DATE - 1);
|
||||
m_szPrevDate[MD_MAX_DATE - 1] = '\0';
|
||||
|
||||
//#ifdef _WIN32
|
||||
// CreateDirectory(m_szPathName, NULL);
|
||||
//#else
|
||||
// mkdir(m_szPathName, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
//#endif
|
||||
}
|
||||
|
||||
int oflag = O_CREAT | O_RDWR;
|
||||
|
||||
if (m_bIsContinue == false)
|
||||
oflag |= O_TRUNC;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (m_bIsBinary)
|
||||
oflag |= O_BINARY;
|
||||
else
|
||||
oflag |= O_TEXT;
|
||||
|
||||
m_fhLog = open(m_szLogFileName, oflag, S_IREAD | S_IWRITE);
|
||||
#else
|
||||
m_fhLog = open(m_szLogFileName, oflag, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH);
|
||||
#endif
|
||||
|
||||
if (m_fhLog == -1)
|
||||
{
|
||||
char szMessage[MD_MAX_PATH + 32];
|
||||
sprintf(szMessage, "[ERROR], Failed to create log file, [%s]\n", m_szLogFileName);
|
||||
|
||||
#ifdef _WIN32
|
||||
MessageBoxA(HWND_TOP, szMessage, FILECRETEFAIL_CAPTION, MB_OK | MB_ICONERROR);
|
||||
#else
|
||||
printf(szMessage);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_bIsContinue)
|
||||
lseek(m_fhLog, 0L, SEEK_END);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HLogger::CloseFile()
|
||||
{
|
||||
if (m_fhLog == -1) return;
|
||||
|
||||
if (m_nFileLimitSize > 0)
|
||||
{
|
||||
const char * pszEndTxt = "--------------------------------\nEnd of log writing.\n--------------------------------\n\n";
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable:4267)
|
||||
#endif
|
||||
write(m_fhLog, pszEndTxt, strlen(pszEndTxt));
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(default:4267)
|
||||
#endif
|
||||
}
|
||||
|
||||
close(m_fhLog);
|
||||
m_fhLog = -1;
|
||||
}
|
||||
|
||||
void HLogger::GetDateTime(char * szDate, char * szTime)
|
||||
{
|
||||
SYSTEMTIME systemTime;
|
||||
HTIMER()->GetSystemTime(&systemTime);
|
||||
|
||||
if (szDate != NULL)
|
||||
sprintf(szDate, "%.4ld%.2ld%.2ld", systemTime.wYear, systemTime.wMonth, systemTime.wDay);
|
||||
|
||||
if (szTime != NULL)
|
||||
sprintf(szTime, "%.2ld:%.2ld:%.2ld.%.3ld", systemTime.wHour, systemTime.wMinute, systemTime.wSecond,
|
||||
systemTime.wMilliseconds);
|
||||
}
|
||||
|
||||
void HLogger::Write(int nLevel, const char * pszLog)
|
||||
{
|
||||
Lock();
|
||||
|
||||
if (m_fhLog == -1 || nLevel > m_nLevel ||
|
||||
((m_flagOption & onlyLevel) == onlyLevel && m_nLevel != nLevel))
|
||||
{
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
char * pszSwap = m_szLogString;
|
||||
m_szLogString = (char *)pszLog;
|
||||
|
||||
m_nLogLength = (int)strlen(pszLog);
|
||||
|
||||
WriteLog(false);
|
||||
m_szLogString = pszSwap;
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void HLogger::Dump(int nLevel, const char * pszLog, size_t nSize, bool bWithHex)
|
||||
{
|
||||
Lock();
|
||||
|
||||
if (m_fhLog == -1 || nLevel > m_nLevel ||
|
||||
((m_flagOption & onlyLevel) == onlyLevel && m_nLevel != nLevel))
|
||||
{
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (nSize > MD_MAX_STRING - 3)
|
||||
nSize = MD_MAX_STRING - 3;
|
||||
|
||||
strncpy(m_szLogString, pszLog, nSize);
|
||||
m_szLogString[nSize] = '\0';
|
||||
m_nLogLength = (int)nSize;
|
||||
|
||||
if (bWithHex)
|
||||
{
|
||||
char * pszTemp = m_szLogString + nSize;
|
||||
pszTemp[0] = '\n';
|
||||
|
||||
const char HEX[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
char cByte;
|
||||
unsigned i = 0, j = 1;
|
||||
for (; i < nSize; i++)
|
||||
{
|
||||
cByte = pszLog[i];
|
||||
|
||||
pszTemp[j++] = HEX[(cByte & 0xF0) >> 4];
|
||||
pszTemp[j++] = HEX[(cByte & 0x0F) >> 0];
|
||||
pszTemp[j++] = ' ';
|
||||
}
|
||||
|
||||
m_nLogLength += j;
|
||||
}
|
||||
|
||||
m_szLogString[m_nLogLength] = '\n';
|
||||
m_szLogString[m_nLogLength + 1] = '\0';
|
||||
m_nLogLength += 1;
|
||||
|
||||
WriteLog(false);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void HLogger::Format(int nLevel, const char *fmt, ...)
|
||||
{
|
||||
Lock();
|
||||
|
||||
if (m_fhLog == -1 || nLevel > m_nLevel ||
|
||||
((m_flagOption & onlyLevel) == onlyLevel && m_nLevel != nLevel))
|
||||
{
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
va_list vaList;
|
||||
va_start(vaList, fmt);
|
||||
|
||||
m_nLogLength = vsnprintf(m_szLogString, MD_MAX_STRING - 1, fmt, vaList);
|
||||
if (m_nLogLength < 0 || m_nLogLength >= MD_MAX_STRING)
|
||||
{
|
||||
m_nLogLength = MD_MAX_STRING;
|
||||
m_szLogString[MD_MAX_STRING - 1] = '\0';
|
||||
}
|
||||
|
||||
va_end(vaList);
|
||||
|
||||
WriteLog(false);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void HLogger::Trace(const char * szSrcFileName, const unsigned nSrcLine, int nLevel, const char *fmt, ...)
|
||||
{
|
||||
Lock();
|
||||
|
||||
if (m_fhLog == -1 || nLevel > m_nLevel ||
|
||||
((m_flagOption & onlyLevel) == onlyLevel && m_nLevel != nLevel))
|
||||
{
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// remove path name
|
||||
const char * pPos = strrchr(szSrcFileName, '\\');
|
||||
|
||||
if (pPos == NULL)
|
||||
pPos = strrchr(szSrcFileName, '/');
|
||||
|
||||
if (pPos != NULL)
|
||||
{
|
||||
strncpy(m_szSrcFileName, ++pPos, MD_MAX_PATH);
|
||||
m_szSrcFileName[MD_MAX_PATH - 1] = '\0';
|
||||
}
|
||||
else
|
||||
#endif // _WIN32
|
||||
strncpy(m_szSrcFileName, szSrcFileName, MD_MAX_PATH - 1);
|
||||
m_szSrcFileName[MD_MAX_PATH - 1] = '\0';
|
||||
m_nSrcLine = nSrcLine;
|
||||
|
||||
|
||||
va_list vaList;
|
||||
va_start(vaList, fmt);
|
||||
|
||||
m_nLogLength = vsnprintf(m_szLogString, MD_MAX_STRING - 1, fmt, vaList);
|
||||
if (m_nLogLength < 0 || m_nLogLength >= MD_MAX_STRING)
|
||||
{
|
||||
m_nLogLength = MD_MAX_STRING;
|
||||
m_szLogString[MD_MAX_STRING - 1] = '\0';
|
||||
}
|
||||
|
||||
va_end(vaList);
|
||||
|
||||
WriteLog(true);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void HLogger::SetSrcInfoWithLock(const char * szSrcFileName, const unsigned nSrcLine)
|
||||
{
|
||||
Lock();
|
||||
|
||||
#ifdef _WIN32
|
||||
// remove path name
|
||||
const char * pPos = strrchr(szSrcFileName, '\\');
|
||||
|
||||
if (pPos == NULL)
|
||||
pPos = strrchr(szSrcFileName, '/');
|
||||
|
||||
if (pPos != NULL)
|
||||
{
|
||||
strncpy(m_szSrcFileName, ++pPos, MD_MAX_PATH);
|
||||
m_szSrcFileName[MD_MAX_PATH - 1] = '\0';
|
||||
}
|
||||
else
|
||||
#endif // _WIN32
|
||||
strncpy(m_szSrcFileName, szSrcFileName, MD_MAX_PATH - 1);
|
||||
m_szSrcFileName[MD_MAX_PATH - 1] = '\0';
|
||||
m_nSrcLine = nSrcLine;
|
||||
}
|
||||
|
||||
void HLogger::TraceWithUnlock(int nLevel)
|
||||
{
|
||||
if (m_fhLog == -1 || nLevel > m_nLevel ||
|
||||
((m_flagOption & onlyLevel) == onlyLevel && m_nLevel != nLevel))
|
||||
{
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
WriteLog(true);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
inline void HLogger::WriteLog(const bool bIsTrace)
|
||||
{
|
||||
m_szWriteString[0] = '\0';
|
||||
m_nWriteLength = 0;
|
||||
|
||||
if (m_bIsFileNameChange)
|
||||
{
|
||||
char szDate[MD_MAX_DATE];
|
||||
|
||||
GetDateTime(szDate, NULL);
|
||||
if (strcmp(m_szPrevDate, szDate) != 0)
|
||||
{
|
||||
CloseFile();
|
||||
OpenFile(m_nLevel, NULL);
|
||||
m_nLogFileNameExt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_nFileSplitSize > 0 && m_nFileSplitSize <= lseek(m_fhLog, 0L, SEEK_CUR))
|
||||
{
|
||||
// file split : filename.001, filename.002, ...
|
||||
char szLogFileName[MD_MAX_PATH], szFileName[MD_MAX_PATH];
|
||||
char * pRear;
|
||||
|
||||
pRear = strrchr(m_szLogFileName, '.');
|
||||
strncpy(szFileName, m_szLogFileName, pRear - m_szLogFileName);
|
||||
szFileName[pRear - m_szLogFileName] = '\0';
|
||||
sprintf(szLogFileName, "%s.%.3d", szFileName, ++m_nLogFileNameExt);
|
||||
|
||||
CloseFile();
|
||||
OpenFile(m_nLevel, szLogFileName);
|
||||
}
|
||||
|
||||
if ((m_flagOption & dayWrite) == dayWrite)
|
||||
{
|
||||
GetDateTime(m_szWriteString, NULL);
|
||||
m_szWriteString[8] = ' ';
|
||||
m_szWriteString[9] = '\0';
|
||||
m_nWriteLength += 9;
|
||||
}
|
||||
|
||||
if ((m_flagOption & timeWrite) == timeWrite)
|
||||
{
|
||||
GetDateTime(NULL, m_szTmpString);
|
||||
memcpy(m_szWriteString + m_nWriteLength, m_szTmpString, 12);
|
||||
m_szWriteString[m_nWriteLength + 12] = '\t';
|
||||
m_szWriteString[m_nWriteLength + 13] = '\0';
|
||||
m_nWriteLength += 13;
|
||||
}
|
||||
|
||||
if (bIsTrace)
|
||||
{
|
||||
m_nTracePathLength = sprintf(m_szTracePathName, "%s(%d)", m_szSrcFileName, m_nSrcLine);
|
||||
|
||||
if (m_nTracePathLength < 26)
|
||||
m_nTracePathLength = sprintf(m_szTmpString, "%25s\t", m_szTracePathName);
|
||||
else if (m_nTracePathLength < 32)
|
||||
m_nTracePathLength = sprintf(m_szTmpString, "%31s\t", m_szTracePathName);
|
||||
else if (m_nTracePathLength < 38)
|
||||
m_nTracePathLength = sprintf(m_szTmpString, "%37s\t", m_szTracePathName);
|
||||
else
|
||||
m_nTracePathLength = sprintf(m_szTmpString, "%43s\t", m_szTracePathName);
|
||||
|
||||
memcpy(m_szWriteString + m_nWriteLength, m_szTmpString, m_nTracePathLength + 1);
|
||||
m_nWriteLength += m_nTracePathLength;
|
||||
}
|
||||
|
||||
if (m_nLogLength + m_nWriteLength > MD_MAX_STRING - 1)
|
||||
m_nLogLength = MD_MAX_STRING - m_nWriteLength - 1;
|
||||
|
||||
memcpy(m_szWriteString + m_nWriteLength, m_szLogString, m_nLogLength);
|
||||
m_nWriteLength += m_nLogLength;
|
||||
|
||||
if (m_nWriteLength >= MD_MAX_STRING - 1 || (m_flagOption & autoNewLine) == autoNewLine)
|
||||
{
|
||||
if (m_nWriteLength >= MD_MAX_STRING - 1)
|
||||
m_nWriteLength--;
|
||||
|
||||
m_szWriteString[m_nWriteLength++] = '\n';
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable:4267)
|
||||
#endif
|
||||
if (m_nFileLimitSize > 0 && m_nFileLimitSize <= lseek(m_fhLog, 0L, SEEK_CUR))
|
||||
{
|
||||
const static char * pszFirstTxt = "Log writing was contiued from file end. See date and time of end line.\n--------------------------------\n";
|
||||
|
||||
#ifdef _WIN32
|
||||
_chsize(m_fhLog, m_nFileLimitSize / 4);
|
||||
#else
|
||||
ftruncate(m_fhLog, m_nFileLimitSize / 4);
|
||||
#endif
|
||||
|
||||
lseek(m_fhLog, 0L, SEEK_SET);
|
||||
write(m_fhLog, pszFirstTxt, strlen(pszFirstTxt));
|
||||
}
|
||||
|
||||
OnWrite(m_szWriteString, m_nWriteLength);
|
||||
|
||||
if ((m_flagOption & consoleWrite) == consoleWrite)
|
||||
fwrite(m_szWriteString, sizeof(char), m_nWriteLength, stdout);
|
||||
|
||||
//#ifdef _WIN32
|
||||
//#pragma warning(default:4267)
|
||||
// _commit(m_fhLog);
|
||||
//#endif
|
||||
|
||||
if (m_pExtension)
|
||||
m_pExtension->OnWrite(m_szWriteString, m_nWriteLength);
|
||||
}
|
||||
Reference in New Issue
Block a user