Exemple #1
0
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;
}
Exemple #2
0
//----------------------------------------------------------------------------
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;
}