123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- #include <pthread.h>
- #include <string.h>
- #include <time.h>
- #include <errno.h>
- #include "logfile.h"
- #include "fileutil.h"
- /////////////////////////////////////////////////////////////////////////////
- CLogfile::CLogfile(void) : m_pf(NULL),
- m_bAttached(false),
- m_bClose(false),
- m_vb(VB_Off),
- m_nFileSize(0),
- m_nMaxFileSize(0),
- m_nMaxBackupFiles(0)
- {
- m_lsync = PTHREAD_MUTEX_INITIALIZER;
- }
- CLogfile::CLogfile(FILE *pf, bool bClose, int verb) : m_pf(pf),
- m_bAttached(false),
- m_bClose(false),
- m_vb(VB_Off),
- m_nFileSize(0),
- m_nMaxFileSize(0),
- m_nMaxBackupFiles(0)
- {
- m_lsync = PTHREAD_MUTEX_INITIALIZER;
- if(!Attach(pf, bClose, verb))
- {
- StdErr("CLogfile::Attach failed!\n");
- throw EINVAL;
- }
- }
- CLogfile::CLogfile(const char *pszFilename, bool bAppend, int verb, size_t nMaxFileSize, unsigned int nMaxBackupFiles) : m_pf(NULL),
- m_bAttached(false),
- m_bClose(false),
- m_vb(VB_Off),
- m_nFileSize(0),
- m_nMaxFileSize(0),
- m_nMaxBackupFiles(0)
- {
- m_lsync = PTHREAD_MUTEX_INITIALIZER;
- if(!Open(pszFilename, bAppend, verb, nMaxFileSize, nMaxBackupFiles))
- {
- StdErr("CLogfile::Open failed!\n");
- throw errno;
- }
- }
- CLogfile::~CLogfile(void)
- {
- Close();
- ::pthread_mutex_destroy(&m_lsync);
- }
- void CLogfile::SetVerbosity(int verb)
- {
- if(verb < VB_Off)
- verb = VB_Off;
- else if(verb >= VB_Dbg)
- verb = VB_Dbg;
- m_vb = (Verbosity)verb;
- }
- /////////////////////////////////////////////////////////////////////////////
- bool CLogfile::Open(const char *pszFilename, bool bAppend, int verb, size_t nMaxFileSize, unsigned int nMaxBackupFiles)
- {
- if(!pszFilename || !*pszFilename)
- return false;
- if(nMaxBackupFiles < 1)
- nMaxBackupFiles = 1;
- Close();
- if((m_pf = fopen(pszFilename, bAppend ? "ab" : "wb")))
- {
- char szBuf[PATH_MAX];
- m_strFilePath = ::realpath(pszFilename, szBuf);
- m_nFileSize = GetFileSize();
- m_bAttached = false;
- m_bClose = true;
- m_nMaxFileSize = nMaxFileSize;
- m_nMaxBackupFiles = nMaxBackupFiles;
- SetVerbosity(verb);
- ProcessFileSizeLimit(m_pf);
- }
- return m_pf != NULL;
- }
- void CLogfile::Close(void)
- {
- CsLock();
- if(m_pf)
- {
- if(!m_bAttached || m_bClose)
- fclose(m_pf);
- m_pf = NULL;
- }
- m_bClose = false;
- m_bAttached = false;
- m_nFileSize = 0;
- m_nMaxFileSize = 0;
- m_nMaxBackupFiles = 0;
- m_vb = VB_Off;
- m_strFilePath.clear();
- CsUnlock();
- }
- void CLogfile::Flush(void)
- {
- if(m_pf)
- fflush(m_pf);
- }
- /////////////////////////////////////////////////////////////////////////////
- bool CLogfile::Attach(FILE *pf, bool bClose, int verb)
- {
- if(!pf)
- {
- errno = EINVAL;
- return false;
- }
- Close();
- m_pf = pf;
- m_bAttached = true;
- m_bClose = bClose;
- SetVerbosity(verb);
- return true;
- }
- void CLogfile::Detach(void)
- {
- CsLock();
- if(m_bAttached)
- {
- m_pf = NULL;
- m_bClose = false;
- m_bAttached = false;
- }
- CsUnlock();
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogfile::Log(FILE *pf, const char *pszFormat, va_list args)
- {
- int nLen;
- CsLock();
- if((nLen = vfprintf(pf, pszFormat, args)) > 0)
- {
- fflush(pf);
- m_nFileSize += nLen;
- ProcessFileSizeLimit(pf);
- }
- CsUnlock();
- }
- void CLogfile::Log(const char *pszFormat, ...)
- {
- if(m_pf && pszFormat && *pszFormat)
- {
- va_list args;
- va_start(args, pszFormat);
- Log(m_pf, pszFormat, args);
- va_end(args);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogfile::Debug(const char *pszFormat, ...)
- {
- #ifdef _DEBUG
- if(m_vb >= VB_Dbg)
- {
- const char *pszFmt;
- std::string sFormat;
- if((pszFmt = CreateFormatString(VB_Dbg, pszFormat, sFormat)))
- {
- va_list args;
- va_start(args, pszFormat);
- Log(m_pf, pszFmt, args);
- va_end(args);
- }
- }
- #endif // _DEBUG
- }
- void CLogfile::Info(const char *pszFormat, ...)
- {
- if(m_vb >= VB_Inf)
- {
- const char *pszFmt;
- std::string sFormat;
- if((pszFmt = CreateFormatString(VB_Inf, pszFormat, sFormat)))
- {
- va_list args;
- va_start(args, pszFormat);
- Log(m_pf, pszFmt, args);
- va_end(args);
- }
- }
- }
- void CLogfile::Warning(const char *pszFormat, ...)
- {
- if(m_vb >= VB_War)
- {
- const char *pszFmt;
- std::string sFormat;
- if((pszFmt = CreateFormatString(VB_War, pszFormat, sFormat)))
- {
- va_list args;
- va_start(args, pszFormat);
- Log(m_pf, pszFmt, args);
- va_end(args);
- }
- }
- }
- void CLogfile::Error(const char *pszFormat, ...)
- {
- if(m_vb >= VB_Err)
- {
- const char *pszFmt;
- std::string sFormat;
- if((pszFmt = CreateFormatString(VB_Err, pszFormat, sFormat)))
- {
- va_list args;
- va_start(args, pszFormat);
- Log(m_pf, pszFmt, args);
- va_end(args);
- }
- }
- }
- size_t CLogfile::GetFileSize(void)
- {
- CsLock();
- size_t s = m_pf ? ::GetFileSize(m_pf) : 0;
- CsUnlock();
- return s;
- }
- bool CLogfile::ProcessFileSizeLimit(FILE *pf)
- {
- if(m_nMaxFileSize && !m_bAttached && pf && (pf == m_pf))
- {
- if(m_nFileSize >= m_nMaxFileSize)
- {
- char szBuf1[PATH_MAX], szBuf2[PATH_MAX];
- std::string strFilePath = m_strFilePath;
- Verbosity vb = m_vb;
- size_t nMaxFileSize = m_nMaxFileSize;
- int nMaxBackupFiles = m_nMaxBackupFiles;
- fclose(m_pf);
- m_pf = NULL;
- m_bClose = false;
- m_bAttached = false;
- m_nFileSize = 0;
- m_nMaxFileSize = 0;
- m_nMaxBackupFiles = 0;
- m_vb = VB_Off;
- m_strFilePath.clear();
- snprintf(szBuf1, sizeof(szBuf1), "%s.%03u", strFilePath.c_str(), nMaxBackupFiles);
- remove(szBuf1);
- for(int i = nMaxBackupFiles; i > 1; --i)
- {
- snprintf(szBuf2, sizeof(szBuf2), "%s.%03u", strFilePath.c_str(), i);
- snprintf(szBuf1, sizeof(szBuf1), "%s.%03u", strFilePath.c_str(), i - 1);
- rename(szBuf1, szBuf2);
- }
- rename(strFilePath.c_str(), szBuf1);
- return Open(strFilePath.c_str(), false, vb, nMaxFileSize, nMaxBackupFiles);
- }
- }
- return false;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogfile::StdOut(const char *pszFormat, ...)
- {
- if(pszFormat && *pszFormat)
- {
- va_list args;
- va_start(args, pszFormat);
- vfprintf(stdout, pszFormat, args);
- va_end(args);
- fflush(stdout);
- }
- }
- void CLogfile::StdErr(const char *pszFormat, ...)
- {
- if(pszFormat && *pszFormat)
- {
- va_list args;
- va_start(args, pszFormat);
- vfprintf(stderr, pszFormat, args);
- va_end(args);
- fflush(stderr);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- const char* CLogfile::CreateFormatString(Verbosity verb, const char *pszFormat, std::string &ret) const
- {
- time_t ts = time(NULL);
- char szBuf[128], szTime[64];
- struct tm *pm = localtime(&ts);
- strftime(szTime, sizeof(szTime), "%d.%m.%Y %H:%M:%S", pm);
- switch(verb)
- {
- case VB_Dbg:
- sprintf(szBuf, "%s - DEBUG: ", szTime);
- break;
- case VB_Inf:
- sprintf(szBuf, "%s - INFO: ", szTime);
- break;
- case VB_War:
- sprintf(szBuf, "%s - WARNING: ", szTime);
- break;
- case VB_Err:
- sprintf(szBuf, "%s - ERROR: ", szTime);
- break;
- default:
- return NULL;
- }
- ret = szBuf;
- ret += pszFormat;
- return ret.c_str();
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogfile::CsLock(void)
- {
- ::pthread_mutex_lock(&m_lsync);
- }
- void CLogfile::CsUnlock(void)
- {
- ::pthread_mutex_unlock(&m_lsync);
- }
|