/************************************************************************ $Id: sysloglogdriver.cpp,v 1.3 2005/02/22 20:12:37 jonico Exp $ RTB - Team Framework: Framework for RealTime Battle robots to communicate efficiently in a team Copyright (C) 2004 The RTB- Team Framework Group: http://rtb-team.sourceforge.net 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Log: sysloglogdriver.cpp,v $ Revision 1.3 2005/02/22 20:12:37 jonico Changed some minor behavior to let the framework work together with Solaris Revision 1.2 2005/01/06 17:59:28 jonico Now all files in the repository have their new header format. **************************************************************************/ #include #include #include "sysloglogdriver.h" namespace Log { using std::set; int SyslogLogDriver::_instanceCount=0; bool SyslogLogDriver::_logOpened=false; bool SyslogLogDriver::_mapsInitialized=false; int SyslogLogDriver::_lastLoggingInstance; int SyslogLogDriver::_lastLoggingSyslogOption; string SyslogLogDriver::_lastLoggingSyslogIdent; map SyslogLogDriver::_options; map SyslogLogDriver::_priorities; SyslogLogDriver::SyslogLogDriver() throw (bad_exception) { init(); // _instanceInitialized is NOT set true, because the LogDriver parameters // have not been set yet. } SyslogLogDriver::SyslogLogDriver(const string& logDriverParameters) throw (IOException,bad_exception) { init(); setLogDriverParameters(logDriverParameters); } SyslogLogDriver::SyslogLogDriver(const string& syslogIdent, int syslogOption, int syslogPriority) throw (bad_exception) { init(); setLogDriverParameters(syslogIdent, syslogOption, syslogPriority); } SyslogLogDriver::~SyslogLogDriver() throw() { if(_logOpened && _instanceCount==1) { closelog(); _logOpened=false; } --_instanceCount; } void SyslogLogDriver::setLogDriverParameters(const string& syslogIdent, int syslogOption, int syslogPriority) throw() { _syslogOption=syslogOption; _syslogIdent=syslogIdent; _syslogPriority=syslogPriority; _instanceInitialized=true; } void SyslogLogDriver::setLogDriverParameters(const string& logDriverParameters) throw (IOException,bad_exception) { string syslogIdent; int syslogOption, syslogPriority; map parameters=parseParameterString(logDriverParameters); if(parameters.find("option")==parameters.end()) { // set default value for option syslogOption=LOG_CONS|LOG_PID; } else { syslogOption=parseOption(parameters["option"]); } if(parameters.find("ident")==parameters.end()) { // set default value for ident syslogIdent="RTB-Team"; } else { syslogIdent=trim(parameters["ident"]); } if(parameters.find("priority")==parameters.end()) { // set default value for priority syslogPriority=LOG_INFO; } else { syslogPriority=parsePriority(parameters["priority"]); } set validParameters; validParameters.insert("option"); validParameters.insert("ident"); validParameters.insert("priority"); for(map::iterator i=parameters.begin();i!=parameters.end();++i) { if(validParameters.find(i->first)==validParameters.end()) { throw IOException(string("Invalid parameter in SyslogLogDriver parameters: '")+(i->first)+"'!"); } } setLogDriverParameters(syslogIdent, syslogOption, syslogPriority); } // the common code of all constructors void SyslogLogDriver::init() throw (bad_exception) { _instanceInitialized=false; if(!_mapsInitialized) { // valid options _options["LOG_CONS"]=LOG_CONS; _options["LOG_NDELAY"]=LOG_NDELAY; // this option exists on almost every unix #ifdef OS_LINUX // _options["LOG_PERROR"]=LOG_PERROR; // this option exist on almost every unix #endif _options["LOG_PID"]=LOG_PID; // valid priorities _priorities["LOG_EMERG"]=LOG_EMERG; _priorities["LOG_ALERT"]=LOG_ALERT; _priorities["LOG_CRIT"]=LOG_CRIT; _priorities["LOG_ERR"]=LOG_ERR; _priorities["LOG_WARNING"]=LOG_WARNING; _priorities["LOG_NOTICE"]=LOG_NOTICE; _priorities["LOG_INFO"]=LOG_INFO; _priorities["LOG_DEBUG"]=LOG_DEBUG; _mapsInitialized=true; } _instance=_instanceCount; ++_instanceCount; } auto_ptr SyslogLogDriver::clone() const throw (bad_exception) { // the returned SyslogLogDriver instance should be initialized if this // instance is initialized already if(_instanceInitialized) return auto_ptr(new SyslogLogDriver(_syslogIdent, _syslogOption, _syslogPriority)); else return auto_ptr(new SyslogLogDriver()); } void SyslogLogDriver::openlog() throw() { ::openlog(_syslogIdent.c_str(), _syslogOption, LOG_USER); _lastLoggingSyslogOption=_syslogOption; _lastLoggingSyslogIdent=_syslogIdent; _lastLoggingInstance=_instance; _logOpened=true; } void SyslogLogDriver::logMessage(const string& message) throw (IOException, bad_exception) { if(!_instanceInitialized) { throw IOException("SyslogLogDriver: Cannot log: LogDriver parameters are not set yet!"); } if(!_logOpened) openlog(); if(_lastLoggingInstance!=_instance) { if(_syslogOption!=_lastLoggingSyslogOption || _syslogIdent!=_lastLoggingSyslogIdent) { // The instance that logged the last time had a different option- or // ident value. So we have to reopen the syslog connection to set // our values. closelog(); openlog(); } } syslog(_syslogPriority, message.c_str()); } map SyslogLogDriver::parseParameterString(const string& parameters) throw (IOException, bad_exception) { // States: // BEFOREKEY // PARAMKEY // PARAMVALUE // BEFORECOLON int BEFOREKEY=0, PARAMKEY=1, PARAMVALUE=2, BEFORECOLON=3; int state; map parsed; string key=""; string value=""; state=BEFOREKEY; for(int i=0;i