2012-05-29 13:31:11 +00:00
|
|
|
// NeLNS - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#ifndef NL_LOG_REPORT_H
|
|
|
|
#define NL_LOG_REPORT_H
|
|
|
|
|
|
|
|
#include "nel/misc/types_nl.h"
|
|
|
|
#include "nel/misc/log.h"
|
|
|
|
#include "nel/misc/thread.h"
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
|
|
class CLogReport;
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class CMakeLogTask : public NLMISC::IRunnable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
CMakeLogTask() : _Stopping(false), _Complete(false), _Thread(NULL), _OutputLogReport(NULL) {}
|
|
|
|
|
|
|
|
/// Destructor
|
|
|
|
~CMakeLogTask();
|
|
|
|
|
|
|
|
/// Start (called in main thread)
|
|
|
|
void start();
|
|
|
|
|
|
|
|
/// Ask for stop and wait until terminated (called in main thread)
|
|
|
|
void terminateTask();
|
|
|
|
|
|
|
|
///
|
|
|
|
bool isRunning() const { return (_Thread != NULL) && (!_Complete); }
|
|
|
|
|
|
|
|
///
|
|
|
|
bool isStopping() const { return _Stopping; }
|
|
|
|
|
|
|
|
///
|
|
|
|
bool isComplete() const { return _Complete; }
|
|
|
|
|
|
|
|
virtual void run();
|
|
|
|
|
|
|
|
/// Set the path of logfile directory.
|
|
|
|
void setLogPath(const std::string & logPath);
|
|
|
|
|
|
|
|
/// Set one or more paths of logfile directory. They will be processed when running the background thread.
|
|
|
|
void setLogPaths(const std::vector<std::string>& logPaths);
|
|
|
|
|
|
|
|
/// Set the path of logfile directory to default value
|
|
|
|
void setLogPathToDefault();
|
|
|
|
|
|
|
|
/// Return the log paths
|
|
|
|
const std::vector<std::string> getLogPaths() const { return _LogPaths; }
|
|
|
|
|
|
|
|
/** Set which files are to be browsed:
|
|
|
|
* v --> log*.log (default if setLogTarget() not called or called with an empty string)
|
|
|
|
* v* --> log*.log + v*_log*.log
|
|
|
|
* v<n> --> v<n>_log*.log
|
|
|
|
* v<n>+ --> v<n>_log*.log + all matching greater <n> + log*.log
|
|
|
|
* v<n>- --> v<n>_log*.log + all matching lower <n>
|
|
|
|
* * --> *.log
|
|
|
|
*/
|
|
|
|
void setLogTarget(const std::string & logTarget) { _LogTarget = logTarget; }
|
|
|
|
|
|
|
|
/// Return the log report (NULL if task not started yet)
|
|
|
|
CLogReport* getLogReport() { return _OutputLogReport; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
void pleaseStop() { _Stopping = true; }
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
volatile bool _Stopping;
|
|
|
|
volatile bool _Complete;
|
|
|
|
std::string _LogTarget;
|
|
|
|
std::vector<std::string> _LogPaths;
|
|
|
|
|
|
|
|
NLMISC::IThread *_Thread;
|
|
|
|
|
|
|
|
CLogReport *_OutputLogReport;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const uint NB_LINES_PER_PAGE = 100;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class CLogLineInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
CLogLineInfo() : NbOccurences(0) {}
|
|
|
|
|
|
|
|
void addAnOccurence( const std::vector<std::string>& lineTokens );
|
|
|
|
|
|
|
|
uint NbOccurences;
|
|
|
|
|
|
|
|
std::string SampleLogText;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class ILogReport
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
virtual void storeLine( const std::vector<std::string>& lineTokens, bool mainCountOnly ) = 0;
|
|
|
|
|
|
|
|
virtual void report( NLMISC::CLog *targetLog, bool detailed ) = 0;
|
|
|
|
|
|
|
|
virtual uint getNbDistinctLines() const = 0;
|
|
|
|
|
|
|
|
virtual uint getNbTotalLines( NLMISC::CLog::TLogType logType ) = 0;
|
|
|
|
|
|
|
|
virtual ~ILogReport() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For one service (service name, not service instance), store info about log lines
|
|
|
|
*/
|
|
|
|
class CLogReportLeaf : public ILogReport
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
CLogReportLeaf( const std::string& service ) : _Service(service), _TotalLines(0) {}
|
|
|
|
|
|
|
|
std::string service() { return _Service; }
|
|
|
|
|
|
|
|
virtual uint getNbDistinctLines() const { return (uint)_LogLineInfo.size(); }
|
|
|
|
|
|
|
|
virtual uint getNbTotalLines( NLMISC::CLog::TLogType logType );
|
|
|
|
|
|
|
|
virtual void storeLine( const std::vector<std::string>& lineTokens, bool mainCountOnly );
|
|
|
|
|
|
|
|
virtual void report( NLMISC::CLog *targetLog, bool detailed );
|
|
|
|
|
|
|
|
uint reportPart( uint beginIndex, uint maxNbLines, NLMISC::CLog *targetLog );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
typedef std::map< std::string, CLogLineInfo > CLogLineInfoMap;
|
|
|
|
|
|
|
|
std::string _Service;
|
|
|
|
|
|
|
|
CLogLineInfoMap _LogLineInfo;
|
|
|
|
|
|
|
|
std::map< std::string, uint > _Counts; // indexed by log type string
|
|
|
|
|
|
|
|
uint _TotalLines;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Store info about log lines for several services
|
|
|
|
*/
|
|
|
|
class CLogReportNode : public ILogReport
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
CLogReportNode() {}
|
|
|
|
|
|
|
|
/// Destructor
|
|
|
|
~CLogReportNode() { reset(); }
|
|
|
|
|
|
|
|
/// Clear all
|
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
for ( std::vector<CLogReportLeaf*>::iterator it=_Children.begin(); it!=_Children.end(); ++it )
|
|
|
|
delete (*it);
|
|
|
|
_Children.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
virtual void storeLine( const std::vector<std::string>& lineTokens, bool mainCountOnly=false );
|
|
|
|
|
|
|
|
CLogReportLeaf* getChild( const std::string& service )
|
|
|
|
{
|
|
|
|
for ( std::vector<CLogReportLeaf*>::iterator it=_Children.begin(); it!=_Children.end(); ++it )
|
|
|
|
{
|
|
|
|
if ( (*it)->service() == service )
|
|
|
|
return (*it);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
CLogReportLeaf* addChild( const std::string& service )
|
|
|
|
{
|
|
|
|
CLogReportLeaf *child = new CLogReportLeaf( service );
|
|
|
|
_Children.push_back( child );
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void report( NLMISC::CLog *targetLog, bool displayDetailsPerService );
|
|
|
|
|
|
|
|
virtual uint getNbDistinctLines() const
|
|
|
|
{
|
|
|
|
uint n = 0;
|
|
|
|
for ( std::vector<CLogReportLeaf*>::const_iterator it=_Children.begin(); it!=_Children.end(); ++it )
|
|
|
|
n += (*it)->getNbDistinctLines();
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual uint getNbTotalLines( NLMISC::CLog::TLogType logType=NLMISC::CLog::LOG_UNKNOWN )
|
|
|
|
{
|
|
|
|
uint n = 0;
|
|
|
|
for ( std::vector<CLogReportLeaf*>::const_iterator it=_Children.begin(); it!=_Children.end(); ++it )
|
|
|
|
n += (*it)->getNbTotalLines( logType );
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reportPage( uint pageNum, NLMISC::CLog *targetLog );
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
std::vector<CLogReportLeaf*> _Children;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* <Class description>
|
|
|
|
* \author Olivier Cado
|
|
|
|
* \author Nevrax France
|
|
|
|
* \date 2004
|
|
|
|
*/
|
|
|
|
class CLogReport : public CLogReportNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
CLogReport() : _CurrentFile(~0), _TotalFiles(~0) {}
|
|
|
|
|
|
|
|
/// Clear all
|
|
|
|
void reset() { CLogReportNode::reset(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a log line to the report tree.
|
|
|
|
* \param onlyType Type of log to study. If LOG_UNKNOWN, study all.
|
|
|
|
* \param countOtherTypes If true and onlyType not LOG_UNKNOWN, count the number of lines of each other type found.
|
|
|
|
*/
|
|
|
|
void pushLine( const std::string& line, NLMISC::CLog::TLogType onlyType=NLMISC::CLog::LOG_WARNING, bool countOtherTypes=true );
|
|
|
|
|
|
|
|
/// Set the current progress
|
|
|
|
void setProgress( uint currentFile, uint totalFiles ) { _CurrentFile = currentFile; _TotalFiles = totalFiles; }
|
|
|
|
|
|
|
|
/// Get the current progress
|
|
|
|
void getProgress( uint& currentFile, uint& totalFiles ) { currentFile = _CurrentFile; totalFiles = _TotalFiles; }
|
|
|
|
|
|
|
|
/// Get results for a service
|
|
|
|
void reportByService( const std::string& service, NLMISC::CLog *targetLog );
|
|
|
|
|
|
|
|
/// Get partial results (pageNum>=1)
|
|
|
|
void reportPage( uint pageNum, NLMISC::CLog *targetLog ) { CLogReportNode::reportPage( pageNum, targetLog ); }
|
|
|
|
|
|
|
|
/// Get summary of results
|
|
|
|
virtual void report( NLMISC::CLog *targetLog, bool displayDetailsPerService=false ) { CLogReportNode::report( targetLog, displayDetailsPerService ); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
uint _CurrentFile;
|
|
|
|
uint _TotalFiles;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif // NL_LOG_REPORT_H
|
|
|
|
|
|
|
|
/* End of log_report.h */
|