239 lines
5.9 KiB
C++
239 lines
5.9 KiB
C++
/*
|
|
* ZoneMinder Logger Interface, $Date$, $Revision$
|
|
* Copyright (C) 2001-2008 Philip Coombes
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#ifndef ZM_LOGGER_H
|
|
#define ZM_LOGGER_H
|
|
|
|
#include "zm_config.h"
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <string>
|
|
#include <map>
|
|
#ifdef HAVE_SYS_SYSCALL_H
|
|
#include <sys/syscall.h>
|
|
#endif // HAVE_SYS_SYSCALL_H
|
|
#include <mysql/mysql.h>
|
|
|
|
class Logger {
|
|
public:
|
|
enum {
|
|
NOOPT=-6,
|
|
NOLOG,
|
|
PANIC,
|
|
FATAL,
|
|
ERROR,
|
|
WARNING,
|
|
INFO,
|
|
DEBUG1,
|
|
DEBUG2,
|
|
DEBUG3,
|
|
DEBUG4,
|
|
DEBUG5,
|
|
DEBUG6,
|
|
DEBUG7,
|
|
DEBUG8,
|
|
DEBUG9
|
|
};
|
|
|
|
typedef int Level;
|
|
|
|
typedef std::map<Level,std::string> StringMap;
|
|
typedef std::map<Level,int> IntMap;
|
|
|
|
class Options {
|
|
public:
|
|
int mTermLevel;
|
|
int mDatabaseLevel;
|
|
int mFileLevel;
|
|
int mSyslogLevel;
|
|
|
|
std::string mLogPath;
|
|
std::string mLogFile;
|
|
|
|
public:
|
|
Options( Level termLevel=NOOPT, Level databaseLevel=NOOPT, Level fileLevel=NOOPT, Level syslogLevel=NOOPT, const std::string &logPath=".", const std::string &logFile="" ) :
|
|
mTermLevel( termLevel ),
|
|
mDatabaseLevel( databaseLevel ),
|
|
mFileLevel( fileLevel ),
|
|
mSyslogLevel( syslogLevel ),
|
|
mLogPath( logPath ),
|
|
mLogFile( logFile )
|
|
{
|
|
}
|
|
};
|
|
|
|
private:
|
|
static bool smInitialised;
|
|
static Logger *smInstance;
|
|
|
|
static StringMap smCodes;
|
|
static IntMap smSyslogPriorities;
|
|
|
|
private:
|
|
bool mInitialised;
|
|
|
|
std::string mId;
|
|
std::string mIdRoot;
|
|
std::string mIdArgs;
|
|
|
|
Level mLevel; // Level that is currently in operation
|
|
Level mTermLevel; // Maximum level output via terminal
|
|
Level mDatabaseLevel; // Maximum level output via database
|
|
Level mFileLevel; // Maximum level output via file
|
|
Level mSyslogLevel; // Maximum level output via syslog
|
|
Level mEffectiveLevel; // Level optimised to take account of maxima
|
|
|
|
bool mDbConnected;
|
|
std::string mLogPath;
|
|
std::string mLogFile;
|
|
FILE *mLogFileFP;
|
|
|
|
bool mHasTerm;
|
|
bool mFlush;
|
|
|
|
private:
|
|
static void usrHandler( int sig );
|
|
|
|
public:
|
|
friend void logInit( const char *name, const Options &options );
|
|
friend void logTerm();
|
|
|
|
static Logger *fetch()
|
|
{
|
|
if ( !smInstance )
|
|
{
|
|
smInstance = new Logger();
|
|
Options options;
|
|
smInstance->initialise( "undef", options );
|
|
}
|
|
return( smInstance );
|
|
}
|
|
|
|
private:
|
|
Logger();
|
|
~Logger();
|
|
|
|
public:
|
|
void initialise( const std::string &id, const Options &options );
|
|
void terminate();
|
|
|
|
private:
|
|
int limit( int level )
|
|
{
|
|
if ( level > DEBUG9 )
|
|
return( DEBUG9 );
|
|
if ( level < NOLOG )
|
|
return( NOLOG );
|
|
return( level );
|
|
}
|
|
|
|
bool boolEnv( const std::string &name, bool defaultValue=false );
|
|
int intEnv( const std::string &name, bool defaultValue=0 );
|
|
std::string strEnv( const std::string &name, const std::string &defaultValue="" );
|
|
char *getTargettedEnv( const std::string &name );
|
|
|
|
void loadEnv();
|
|
|
|
public:
|
|
const std::string &id() const
|
|
{
|
|
return( mId );
|
|
}
|
|
|
|
const std::string &id( const std::string &id );
|
|
|
|
Level level() const
|
|
{
|
|
return( mLevel );
|
|
}
|
|
Level level( Level=NOOPT );
|
|
|
|
bool debugOn() {
|
|
return( mEffectiveLevel >= DEBUG1 );
|
|
}
|
|
|
|
Level termLevel( Level=NOOPT );
|
|
Level databaseLevel( Level=NOOPT );
|
|
Level fileLevel( Level=NOOPT );
|
|
Level syslogLevel( Level=NOOPT );
|
|
|
|
private:
|
|
void logFile( const std::string &logFile );
|
|
void openFile();
|
|
void closeFile();
|
|
void openSyslog();
|
|
void closeSyslog();
|
|
void closeDatabase();
|
|
|
|
public:
|
|
void logPrint( bool hex, const char * const filepath, const int line, const int level, const char *fstring, ... );
|
|
};
|
|
|
|
void logInit( const char *name, const Logger::Options &options=Logger::Options() );
|
|
void logTerm();
|
|
inline const std::string &logId() {
|
|
return( Logger::fetch()->id() );
|
|
}
|
|
inline Logger::Level logLevel() {
|
|
return( Logger::fetch()->level() );
|
|
}
|
|
inline void logCapLevel( Logger::Level level ) {
|
|
Logger::fetch()->level( level );
|
|
}
|
|
inline Logger::Level logDebugging() {
|
|
return( Logger::fetch()->debugOn() );
|
|
}
|
|
|
|
#define logPrintf(logLevel,params...) {\
|
|
if ( logLevel <= Logger::fetch()->level() )\
|
|
Logger::fetch()->logPrint( false, __FILE__, __LINE__, logLevel, ##params );\
|
|
}
|
|
|
|
#define logHexdump(logLevel,data,len) {\
|
|
if ( logLevel <= Logger::fetch()->level() )\
|
|
Logger::fetch()->logPrint( true, __FILE__, __LINE__, logLevel, "%p (%d)", data, len );\
|
|
}
|
|
|
|
/* Debug compiled out */
|
|
#ifndef DBG_OFF
|
|
#define Debug(level,params...) logPrintf(level,##params)
|
|
#define Hexdump(level,data,len) logHexdump(level,data,len)
|
|
#else
|
|
#define Debug(level,params...)
|
|
#define Hexdump(level,data,len)
|
|
#endif
|
|
|
|
/* Standard debug calls */
|
|
#define Info(params...) logPrintf(Logger::INFO,##params)
|
|
#define Warning(params...) logPrintf(Logger::WARNING,##params)
|
|
#define Error(params...) logPrintf(Logger::ERROR,##params)
|
|
#define Fatal(params...) logPrintf(Logger::FATAL,##params)
|
|
#define Panic(params...) logPrintf(Logger::PANIC,##params)
|
|
#define Mark() Info("Mark/%s/%d",__FILE__,__LINE__)
|
|
#define Log() Info("Log")
|
|
#ifdef __GNUC__
|
|
#define Enter(level) logPrintf(level,("Entering %s",__PRETTY_FUNCTION__))
|
|
#define Exit(level) logPrintf(level,("Exiting %s",__PRETTY_FUNCTION__))
|
|
#else
|
|
#define Enter(level)
|
|
#define Exit(level)
|
|
#endif
|
|
|
|
#endif // ZM_LOGGER_H
|