Files
smartservice_native/hdssd/huslib/Logger.cpp
T
2026-05-20 03:08:08 +09:00

536 lines
11 KiB
C++

#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);
}