inline int findMatchingLine( CharString & sText, int nPosition, CharString & sLine ) { int startPos = sText.reverseFind('\n',nPosition); // left linebreak if( startPos > 0 ) startPos++; // Skip linebreak int endPos = sText.find( '\n', nPosition ); // right linebreak if( endPos < 0 ) endPos = startPos+sText.length() - 1; sLine = sText.copy(sText); sLine.mid( startPos, ( endPos - startPos ) + 1 ); return endPos + 1; }
//---------------------------------------------------------------------------- CharString ProcessServer::searchLogFiles( CharString sFilemask, CharString sSearch, bool bRegExp, char nSearchLevel, bool bResolveClients ) { CharString sResult; RegExpM rxSearch; RegExpM rxClientId, rxLogin; Tree< unsigned int, String > trClientLookup; sSearch.lower(); // all search is performed case insensitive if( bRegExp ) rxSearch.regComp( sSearch ); if( bResolveClients ) rxClientId.regComp( STR("[Cc]lient ([0-9]+)[, ]") ); FindFile ff; CharString sMask = CharString().format("./Logs/%s.log",sFilemask.cstr()); ff.findFiles( sMask, false, false ); // sorted by date int nTotalFoundSize = 0; int nTotalSearchedSize = 0; int nTotalFilesSearched = 0; CharString sLine; dword tStart = Time::seconds(); bool bAbort = false; // search through all found files for( int i = 0 ; i < ff.fileCount() && !bAbort ; i++ ) { CharString sLocalFile( ff.file( i ) ); if( nSearchLevel == 2 ) // only list the files, not search them ? { CharString sFile = CharString().format("./Logs/%s", sLocalFile.cstr()) ; sResult += String().format("*** [%s] *** %s\r\n", Time::format( FileDisk::fileDate( sFile ),"%c").cstr(), sLocalFile.cstr() ); continue; } bool fileNamePrintedYet = false; CharString sText; CharString sTextOrig; int nCurPos = 0; try { CharString sFile = CharString().format("./Logs/%s",sLocalFile.cstr() ); char * pTemp = FileDisk::loadTextFile( sFile ); sText.copy( pTemp ).lower(); // pText is all lowercase, as it's used for case insensitive search sTextOrig = CharString().format("%s", pTemp ); // pTextOrig is orig-case, as it's used to build sResult delete pTemp; int nTextLen = sText.length(); nTotalSearchedSize += nTextLen; nTotalFilesSearched++; int pos = -1; // loop to find all occurences of the string while( nCurPos < nTextLen && ( pos = findString( sText, nCurPos, sSearch, &rxSearch, bRegExp ) ) >= 0 ) { if( !fileNamePrintedYet ) { if( nSearchLevel == 0 ) sResult += STR("\r\n\r\n"); CharString sFile = CharString().format("./Logs/%s", sLocalFile.cstr()) ; sResult += String().format("*** [%s] *** %s\r\n", Time::format( FileDisk::fileDate( sFile ),"%c").cstr(), sLocalFile.cstr() ); fileNamePrintedYet = true; } if( nSearchLevel == 1 ) // only check if there is a match in the file at all ? break; // find the matching line, this time in the original-case text nCurPos = findMatchingLine( sTextOrig, nCurPos + pos, sLine ); // need to resolve clientIds when found ? if( bResolveClients ) { int nClientIdPos = rxClientId.regFind( sLine ); if( nClientIdPos >= 0 ) // line holds a clientId ? { int nClientIdLen = rxClientId.getFindLen() - 8; // match length - static chars // extract the clientId CharString sClientId = sLine; sClientId.right( sClientId.length() - ( nClientIdPos + 7 ) ); sClientId.left( nClientIdLen ); int nClientId = CharString::strint(sClientId); CharString sResolvedClient(STR("")); if( trClientLookup.find( nClientId ).valid() ) // know this clientId already ? { sResolvedClient = trClientLookup[ nClientId ]; } else { // haven't seen it yet. Look it up. rxLogin.regComp( String().format( STR("\n../../.. ..:..:.. : Login client %d user ([^,\n]+), userId = ([0-9]+), "), nClientId ) ); if( rxLogin.regFind( sTextOrig ) >= 0 ) { sResolvedClient = rxLogin.getReplaceString( STR(" ( \\1 @\\2 )") ); } else { // not found yet ? Try alternate way to resolve it rxLogin.regComp( String().format( STR("\n../../.. ..:..:.. : Client %d login, id = ([^\r]+)"), nClientId ) ); if( rxLogin.regFind( sTextOrig ) >= 0 ) { sResolvedClient = rxLogin.getReplaceString( STR(" ( \\1 )") ); } // no further "else". If it's not found the result is left blank } trClientLookup[ nClientId ] = sResolvedClient; } if( sResolvedClient != "" ) // got something to insert ? sLine.insert( sResolvedClient, nClientIdPos + nClientIdLen + 7 ); } } // done resolving clientId // add the found line to the result nTotalFoundSize += sLine.length(); sResult += sLine; // abort conditions if( nTotalFoundSize > 300000 ) { sResult += STR("\r\n\r\n*** Result too large, search aborted"); bAbort = true; break; } } } catch( ... ) { return STR("Failed"); } } if( sResult.length() == 0 ) sResult = STR("No results"); else sResult += STR("\r\nDone..."); sResult += CharString().format( STR("\r\nSearched %d file(s) containing %d bytes within %d seconds. Result is %d bytes."), nTotalFilesSearched, nTotalSearchedSize, Time::seconds() - tStart, nTotalFoundSize ); return sResult; }