//PRIVATE: Delete file with index 0 et rename all file i to i-1 until m_filenr-1 //After this function, the file with index m_filenr-1 is free (it doesn't exist) void CLog::renameFiles(const wchar_t *root_filename) { //We remove the file 0 std::wstring src; src=root_filename; src+=L"0.log"; #ifdef WIN32 _wremove(src.c_str()); #else remove(utilStringNarrow(src).c_str()); #endif std::wstring dest; wchar_t isrc[5]; wchar_t idest[5]; #ifdef WIN32 struct _stat results; #else struct stat results; #endif //For all file until m_filenr-1 // 1 become 0 // 2 become 1 //i+1 become i //m_filenr-1 become m_filenr-2 for(int i=0;i<m_filenr;i++) { swprintf_s(isrc,5,L"%d",i+1); swprintf_s(idest,5,L"%d",i); //if the source does not exist, we stop src=root_filename; src+=isrc; src+=L".log"; #ifdef WIN32 if (_wstat(src.c_str(), &results) != 0) break; #else if (stat(utilStringNarrow(src).c_str(), &results) != 0) break; #endif dest=root_filename; dest+=idest; dest+=L".log"; //Rename of the file #ifdef WIN32 _wrename(src.c_str(),dest.c_str()); #else rename(utilStringNarrow(src).c_str(),utilStringNarrow(dest).c_str()); #endif } }
bool CLog::writeLineHeaderA(tLOG_Level level_in,const int line,const char *file) { if(level_in>m_maxlevel) return false; long lPreviousOpenFailed = getOpenFailed(); if(!open(false)) return false; std::string timestamp; getLocalTimeA(timestamp); if(lPreviousOpenFailed > 0) { if(isFileMixingGroups()) { fprintf_s(m_f,"%s - %ld - %s: ...ERROR: This file could not be opened. %ld logging line(s) are missing...\n",timestamp.c_str(),CThread::getCurrentPid(),m_group.c_str(),lPreviousOpenFailed); } else { fprintf_s(m_f,"%s - %ld: ...ERROR: This file could not be opened. %ld logging line(s) are missing...\n",timestamp.c_str(),CThread::getCurrentPid(),lPreviousOpenFailed); } } std::string level=utilStringNarrow(getLevel(level_in)); if(isFileMixingGroups()) { std::string group=utilStringNarrow(m_group); if(line>0 && strlen(file)>0) fprintf_s(m_f,"%s - %ld|%ld - %s - %s -'%s'-line=%d: ",timestamp.c_str(),CThread::getCurrentPid(),CThread::getCurrentThreadId(),group.c_str(),level.c_str(),file,line); else fprintf_s(m_f,"%s - %ld|%ld - %s - %s: ",timestamp.c_str(),CThread::getCurrentPid(),CThread::getCurrentThreadId(),group.c_str(),level.c_str()); } else { if(line>0 && strlen(file)>0) fprintf_s(m_f,"%s - %ld|%ld - %s -'%s'-line=%d: ",timestamp.c_str(),CThread::getCurrentPid(),CThread::getCurrentThreadId(),level.c_str(),file,line); else fprintf_s(m_f,"%s - %ld|%ld - %s: ",timestamp.c_str(),CThread::getCurrentPid(),CThread::getCurrentThreadId(),level.c_str()); } return true; }
//*************************************************** // Retrieve the Processor name (== tag name) //*************************************************** std::string& TagProcessor::getProcessorName() { if ( 0 == m_tagName.size() ) { m_tagName = utilStringNarrow(m_wtagName); } return m_tagName; }
//PRIVATE: Open the file with the correct name bool CLog::open(bool bWchar) { if(!canWeTryToOpen()) { incrementOpenFailed(); return false; } #ifdef WIN32 WaitForSingleObject(LogMutex, INFINITE); #else m_mutex.Lock(); #endif if(m_f) //Should not happend { close(); throw CMWEXCEPTION(EIDMW_ERR_UNKNOWN); } #ifndef WIN32 m_flock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ m_flock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ m_flock.l_start = 0; /* Offset from l_whence */ m_flock.l_len = 0; /* length, 0 = to EOF */ m_flock.l_pid = getpid(); /* our PID */ #endif int err=0; std::wstring filename; int iLoop=0; do //If the file is locked by another process, we wait { getFilename(filename); //We get the file name in the loop because other process may rename the files #ifdef WIN32 if(bWchar) err = _wfopen_s(&m_f,filename.c_str(),L"a, ccs=UTF-8"); else err = fopen_s(&m_f,utilStringNarrow(filename).c_str(),"a"); #else m_f = fopen(utilStringNarrow(filename).c_str(),"a, ccs=UTF-8"); if (m_f == NULL) err=errno; #endif if (err != 0 && err != EACCES) m_f=NULL; if(err==EACCES) CThread::SleepMillisecs(20); iLoop++; } while(err==EACCES && iLoop<100); #ifndef WIN32 // on Linux/Mac we set an advisory lock, i.e. it prevents // other processes from using the file only if they are collaborative // and check for the lock, otherwise they can do whatever they like .. if(m_f!=NULL) { if( fcntl(fileno(m_f), F_SETLK, &m_flock) == -1) /* set the lock */ { fclose(m_f); m_f=NULL; } } #endif if(!m_f) { #ifdef WIN32 ReleaseMutex(LogMutex); #else m_mutex.Unlock(); #endif incrementOpenFailed(); return false; } resetOpenFailed(); return true; }
//PRIVATE: Return the name of to file to write into void CLog::getFilename(std::wstring &filename) { //Test if the directory exist std::wstring directory; #ifdef WIN32 DWORD dwError=0; directory=m_directory + L"\\"; DWORD dwAttr = GetFileAttributes(directory.c_str()); if(dwAttr == INVALID_FILE_ATTRIBUTES) dwError = GetLastError(); if(dwError == ERROR_FILE_NOT_FOUND || dwError == ERROR_PATH_NOT_FOUND) { m_directory=L"."; directory=m_directory + L"\\"; } #else // --> TODO : Test if the directory exist directory = m_directory; struct stat buffer; if ( stat(utilStringNarrow(directory).c_str(),&buffer)){ // check error code m_directory=LOG_DIRECTORY_DEFAULT; } directory=m_directory + L"/"; #endif //Initialize the root filename std::wstring root_filename; root_filename=directory + m_prefix + L"_"; if(m_groupinnewfile && m_group.size()>0) root_filename+=m_group + L"_"; wchar_t index[5]; swprintf_s(index,5,L"%d",0); //If there is a maximal file size, // we parse the file from index 0 to m_filenr-1 // until we find one -that doesn't exist // or // -with a size smaller than m_filesize // If we don't, we have to rename the files // //Else If there is only one file its index is 0 if(m_filesize>0) { //There must be at least 2 files if(m_filenr<2) m_filenr=2; std::wstring file; #ifdef WIN32 struct _stat results; #else struct stat results; #endif bool find=false; for(int i=0;i<m_filenr;i++) { swprintf_s(index,5,L"%d",i); file=root_filename + index + L".log"; #ifdef WIN32 if (_wstat(file.c_str(), &results) != 0 || results.st_size<m_filesize) #else if (stat(utilStringNarrow(file).c_str(), &results) != 0 || results.st_size<m_filesize) #endif { find=true; break; } } if(!find) { renameFiles(root_filename.c_str()); swprintf_s(index,5,L"%d",m_filenr-1); } } filename=root_filename + index + L".log"; }