Remove the ILogger interface.

Fixes #3860
This commit is contained in:
Gunnar Beutner 2013-06-06 11:26:30 +02:00
parent b8669d67ca
commit 4fadd3bfa0
12 changed files with 141 additions and 224 deletions

View File

@ -13,6 +13,8 @@ libbase_la_SOURCES = \
attribute.h \ attribute.h \
bufferedstream.cpp \ bufferedstream.cpp \
bufferedstream.h \ bufferedstream.h \
consolelogger.cpp \
consolelogger.h \
convert.cpp \ convert.cpp \
convert.h \ convert.h \
dictionary.cpp \ dictionary.cpp \
@ -25,6 +27,8 @@ libbase_la_SOURCES = \
exception.h \ exception.h \
fifo.cpp \ fifo.cpp \
fifo.h \ fifo.h \
filelogger.cpp \
filelogger.h \
i2-base.h \ i2-base.h \
logger.cpp \ logger.cpp \
logger.h \ logger.h \

View File

@ -17,42 +17,19 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "base/sysloglogger.h" #include "base/consolelogger.h"
#include "base/dynamictype.h"
#include <iostream>
#ifndef _WIN32
using namespace icinga; using namespace icinga;
/** REGISTER_TYPE(ConsoleLogger);
* Constructor for the SyslogLogger class.
*/
SyslogLogger::SyslogLogger(const Dictionary::Ptr& serializedUpdate)
: Logger(serializedUpdate)
{ }
/** /**
* Processes a log entry and outputs it to syslog. * Constructor for the ConsoleLogger class.
*
* @param entry The log entry.
*/ */
void SyslogLogger::ProcessLogEntry(const LogEntry& entry) ConsoleLogger::ConsoleLogger(const Dictionary::Ptr& serializedUpdate)
: StreamLogger(serializedUpdate)
{ {
int severity; BindStream(&std::cout, false);
switch (entry.Severity) {
case LogDebug:
severity = LOG_DEBUG;
break;
case LogWarning:
severity = LOG_WARNING;
break;
case LogCritical:
severity = LOG_CRIT;
break;
case LogInformation:
default:
severity = LOG_INFO;
break;
}
syslog(severity | LOG_USER, "%s", entry.Message.CStr());
} }
#endif /* _WIN32 */

View File

@ -17,34 +17,29 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef SYSLOGLOGGER_H #ifndef CONSOLELOGGER_H
#define SYSLOGLOGGER_H #define CONSOLELOGGER_H
#include "base/i2-base.h" #include "base/i2-base.h"
#include "base/logger.h" #include "base/streamlogger.h"
#ifndef _WIN32
namespace icinga namespace icinga
{ {
/** /**
* A logger that logs to syslog. * A logger that logs to the console.
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API SyslogLogger : public Logger class I2_BASE_API ConsoleLogger : public StreamLogger
{ {
public: public:
typedef shared_ptr<SyslogLogger> Ptr; typedef shared_ptr<ConsoleLogger> Ptr;
typedef weak_ptr<SyslogLogger> WeakPtr; typedef weak_ptr<ConsoleLogger> WeakPtr;
explicit SyslogLogger(const Dictionary::Ptr& serializedUpdate); explicit ConsoleLogger(const Dictionary::Ptr& serializedUpdate);
protected:
virtual void ProcessLogEntry(const LogEntry& entry);
}; };
} }
#endif /* _WIN32 */
#endif /* SYSLOGLOGGER_H */ #endif /* CONSOLELOGGER_H */

View File

@ -17,42 +17,35 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "base/sysloglogger.h" #include "base/filelogger.h"
#include "base/dynamictype.h"
#include <fstream>
#ifndef _WIN32
using namespace icinga; using namespace icinga;
/** REGISTER_TYPE(FileLogger);
* Constructor for the SyslogLogger class.
*/
SyslogLogger::SyslogLogger(const Dictionary::Ptr& serializedUpdate)
: Logger(serializedUpdate)
{ }
/** /**
* Processes a log entry and outputs it to syslog. * Constructor for the FileLogger class.
*
* @param entry The log entry.
*/ */
void SyslogLogger::ProcessLogEntry(const LogEntry& entry) FileLogger::FileLogger(const Dictionary::Ptr& serializedUpdate)
: StreamLogger(serializedUpdate)
{ {
int severity; RegisterAttribute("path", Attribute_Config, &m_Path);
switch (entry.Severity) {
case LogDebug: std::ofstream *stream = new std::ofstream();
severity = LOG_DEBUG;
break; String path = m_Path;
case LogWarning:
severity = LOG_WARNING; try {
break; stream->open(path.CStr(), std::fstream::out | std::fstream::trunc);
case LogCritical:
severity = LOG_CRIT; if (!stream->good())
break; BOOST_THROW_EXCEPTION(std::runtime_error("Could not open logfile '" + path + "'"));
case LogInformation: } catch (...) {
default: delete stream;
severity = LOG_INFO; throw;
break;
} }
syslog(severity | LOG_USER, "%s", entry.Message.CStr()); BindStream(stream, true);
} }
#endif /* _WIN32 */

View File

@ -17,34 +17,32 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef SYSLOGLOGGER_H #ifndef FILELOGGER_H
#define SYSLOGLOGGER_H #define FILELOGGER_H
#include "base/i2-base.h" #include "base/i2-base.h"
#include "base/logger.h" #include "base/streamlogger.h"
#ifndef _WIN32
namespace icinga namespace icinga
{ {
/** /**
* A logger that logs to syslog. * A logger that logs to a file.
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API SyslogLogger : public Logger class I2_BASE_API FileLogger : public StreamLogger
{ {
public: public:
typedef shared_ptr<SyslogLogger> Ptr; typedef shared_ptr<FileLogger> Ptr;
typedef weak_ptr<SyslogLogger> WeakPtr; typedef weak_ptr<FileLogger> WeakPtr;
explicit SyslogLogger(const Dictionary::Ptr& serializedUpdate); explicit FileLogger(const Dictionary::Ptr& serializedUpdate);
protected: private:
virtual void ProcessLogEntry(const LogEntry& entry); Attribute<String> m_Path;
}; };
} }
#endif /* _WIN32 */
#endif /* SYSLOGLOGGER_H */ #endif /* FILELOGGER_H */

View File

@ -29,7 +29,8 @@
using namespace icinga; using namespace icinga;
REGISTER_TYPE(Logger); std::set<Logger::Ptr> Logger::m_Loggers;
boost::mutex Logger::m_Mutex;
/** /**
* Constructor for the Logger class. * Constructor for the Logger class.
@ -39,8 +40,6 @@ REGISTER_TYPE(Logger);
Logger::Logger(const Dictionary::Ptr& serializedUpdate) Logger::Logger(const Dictionary::Ptr& serializedUpdate)
: DynamicObject(serializedUpdate) : DynamicObject(serializedUpdate)
{ {
RegisterAttribute("type", Attribute_Config, &m_Type);
RegisterAttribute("path", Attribute_Config, &m_Path);
RegisterAttribute("severity", Attribute_Config, &m_Severity); RegisterAttribute("severity", Attribute_Config, &m_Severity);
if (!IsLocal()) if (!IsLocal())
@ -49,36 +48,20 @@ Logger::Logger(const Dictionary::Ptr& serializedUpdate)
void Logger::Start(void) void Logger::Start(void)
{ {
String type = m_Type; boost::mutex::scoped_lock(m_Mutex);
if (type.IsEmpty()) m_Loggers.insert(GetSelf());
BOOST_THROW_EXCEPTION(std::runtime_error("Logger objects must have a 'type' property.")); }
ILogger::Ptr impl; void Logger::Stop(void)
{
if (type == "syslog") { boost::mutex::scoped_lock(m_Mutex);
#ifndef _WIN32 m_Loggers.erase(GetSelf());
impl = boost::make_shared<SyslogLogger>(); }
#else /* _WIN32 */
BOOST_THROW_EXCEPTION(std::invalid_argument("Syslog is not supported on Windows."));
#endif /* _WIN32 */
} else if (type == "file") {
String path = m_Path;
if (path.IsEmpty())
BOOST_THROW_EXCEPTION(std::invalid_argument("'log' object of type 'file' must have a 'path' property"));
StreamLogger::Ptr slogger = boost::make_shared<StreamLogger>();
slogger->OpenFile(path);
impl = slogger;
} else if (type == "console") {
impl = boost::make_shared<StreamLogger>(&std::cout);
} else {
BOOST_THROW_EXCEPTION(std::runtime_error("Unknown log type: " + type));
}
impl->m_Config = GetSelf();
m_Impl = impl;
std::set<Logger::Ptr> Logger::GetLoggers(void)
{
boost::mutex::scoped_lock(m_Mutex);
return m_Loggers;
} }
/** /**
@ -97,40 +80,14 @@ void icinga::Log(LogSeverity severity, const String& facility,
entry.Facility = facility; entry.Facility = facility;
entry.Message = message; entry.Message = message;
Logger::ForwardLogEntry(entry);
}
/**
* Retrieves the minimum severity for this logger.
*
* @returns The minimum severity.
*/
LogSeverity Logger::GetMinSeverity(void) const
{
String severity = m_Severity;
if (severity.IsEmpty())
return LogInformation;
else
return Logger::StringToSeverity(severity);
}
/**
* Forwards a log entry to the registered loggers.
*
* @param entry The log entry.
*/
void Logger::ForwardLogEntry(const LogEntry& entry)
{
bool processed = false; bool processed = false;
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Logger")) { BOOST_FOREACH(const Logger::Ptr& logger, Logger::GetLoggers()) {
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
{ {
ObjectLock llock(logger); ObjectLock llock(logger);
if (entry.Severity >= logger->GetMinSeverity()) if (entry.Severity >= logger->GetMinSeverity())
logger->m_Impl->ProcessLogEntry(entry); logger->ProcessLogEntry(entry);
} }
processed = true; processed = true;
@ -150,6 +107,20 @@ void Logger::ForwardLogEntry(const LogEntry& entry)
} }
} }
/**
* Retrieves the minimum severity for this logger.
*
* @returns The minimum severity.
*/
LogSeverity Logger::GetMinSeverity(void) const
{
String severity = m_Severity;
if (severity.IsEmpty())
return LogInformation;
else
return Logger::StringToSeverity(severity);
}
/** /**
* Converts a severity enum value to a string. * Converts a severity enum value to a string.
* *
@ -190,12 +161,12 @@ LogSeverity Logger::StringToSeverity(const String& severity)
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid severity: " + severity)); BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid severity: " + severity));
} }
/** ///**
* Retrieves the configuration object that belongs to this logger. // * Retrieves the configuration object that belongs to this logger.
* // *
* @returns The configuration object. // * @returns The configuration object.
*/ // */
DynamicObject::Ptr ILogger::GetConfig(void) const //DynamicObject::Ptr ILogger::GetConfig(void) const
{ //{
return m_Config.lock(); // return m_Config.lock();
} //}

View File

@ -23,6 +23,7 @@
#include "base/i2-base.h" #include "base/i2-base.h"
#include "base/dynamicobject.h" #include "base/dynamicobject.h"
#include "base/logger_fwd.h" #include "base/logger_fwd.h"
#include <set>
namespace icinga namespace icinga
{ {
@ -40,35 +41,7 @@ struct LogEntry {
}; };
/** /**
* Base class for all loggers. * A log provider.
*
* @ingroup base
*/
class I2_BASE_API ILogger : public Object
{
public:
typedef shared_ptr<ILogger> Ptr;
typedef weak_ptr<ILogger> WeakPtr;
/**
* Processes the log entry and writes it to the log that is
* represented by this ILogger object.
*
* @param entry The log entry that is to be processed.
*/
virtual void ProcessLogEntry(const LogEntry& entry) = 0;
protected:
DynamicObject::Ptr GetConfig(void) const;
private:
DynamicObject::WeakPtr m_Config;
friend class Logger;
};
/**
* A log provider. Can be instantiated from the config.
* *
* @ingroup base * @ingroup base
*/ */
@ -85,18 +58,27 @@ public:
LogSeverity GetMinSeverity(void) const; LogSeverity GetMinSeverity(void) const;
/**
* Processes the log entry and writes it to the log that is
* represented by this ILogger object.
*
* @param entry The log entry that is to be processed.
*/
virtual void ProcessLogEntry(const LogEntry& entry) = 0;
static std::set<Logger::Ptr> GetLoggers(void);
protected: protected:
virtual void Start(void); virtual void Start(void);
virtual void Stop(void);
private: private:
Attribute<String> m_Type;
Attribute<String> m_Path;
Attribute<String> m_Severity; Attribute<String> m_Severity;
LogSeverity m_MinSeverity; LogSeverity m_MinSeverity;
ILogger::Ptr m_Impl;
static void ForwardLogEntry(const LogEntry& entry); static boost::mutex m_Mutex;
static std::set<Logger::Ptr> m_Loggers;
friend void Log(LogSeverity severity, const String& facility, friend void Log(LogSeverity severity, const String& facility,
const String& message); const String& message);

View File

@ -31,17 +31,8 @@ boost::mutex StreamLogger::m_Mutex;
/** /**
* Constructor for the StreamLogger class. * Constructor for the StreamLogger class.
*/ */
StreamLogger::StreamLogger(void) StreamLogger::StreamLogger(const Dictionary::Ptr& serializedUpdate)
: ILogger(), m_Stream(NULL), m_OwnsStream(false), m_Tty(false) : Logger(serializedUpdate), m_Stream(NULL), m_OwnsStream(false), m_Tty(false)
{ }
/**
* Constructor for the StreamLogger class.
*
* @param stream The stream.
*/
StreamLogger::StreamLogger(std::ostream *stream)
: ILogger(), m_Stream(stream), m_OwnsStream(false), m_Tty(IsTty(*stream))
{ } { }
/** /**
@ -53,25 +44,13 @@ StreamLogger::~StreamLogger(void)
delete m_Stream; delete m_Stream;
} }
void StreamLogger::OpenFile(const String& filename) void StreamLogger::BindStream(std::ostream *stream, bool ownsStream)
{ {
std::ofstream *stream = new std::ofstream();
try {
stream->open(filename.CStr(), std::fstream::out | std::fstream::trunc);
if (!stream->good())
BOOST_THROW_EXCEPTION(std::runtime_error("Could not open logfile '" + filename + "'"));
} catch (...) {
delete stream;
throw;
}
ObjectLock olock(this); ObjectLock olock(this);
m_Stream = stream; m_Stream = stream;
m_OwnsStream = true; m_OwnsStream = ownsStream;
m_Tty = false; m_Tty = IsTty(*stream);
} }
/** /**
@ -117,8 +96,6 @@ void StreamLogger::ProcessLogEntry(std::ostream& stream, bool tty, const LogEntr
*/ */
void StreamLogger::ProcessLogEntry(const LogEntry& entry) void StreamLogger::ProcessLogEntry(const LogEntry& entry)
{ {
ObjectLock olock(this);
ProcessLogEntry(*m_Stream, m_Tty, entry); ProcessLogEntry(*m_Stream, m_Tty, entry);
} }

View File

@ -32,17 +32,16 @@ namespace icinga
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API StreamLogger : public ILogger class I2_BASE_API StreamLogger : public Logger
{ {
public: public:
typedef shared_ptr<StreamLogger> Ptr; typedef shared_ptr<StreamLogger> Ptr;
typedef weak_ptr<StreamLogger> WeakPtr; typedef weak_ptr<StreamLogger> WeakPtr;
StreamLogger(void); StreamLogger(const Dictionary::Ptr& serializedUpdate);
explicit StreamLogger(std::ostream *stream);
~StreamLogger(void); ~StreamLogger(void);
void OpenFile(const String& filename); void BindStream(std::ostream *stream, bool ownsStream);
static void ProcessLogEntry(std::ostream& stream, bool tty, const LogEntry& entry); static void ProcessLogEntry(std::ostream& stream, bool tty, const LogEntry& entry);
static bool IsTty(std::ostream& stream); static bool IsTty(std::ostream& stream);

View File

@ -18,10 +18,20 @@
******************************************************************************/ ******************************************************************************/
#include "base/sysloglogger.h" #include "base/sysloglogger.h"
#include "base/dynamictype.h"
#ifndef _WIN32 #ifndef _WIN32
using namespace icinga; using namespace icinga;
REGISTER_TYPE(SyslogLogger);
/**
* Constructor for the SyslogLogger class.
*/
SyslogLogger::SyslogLogger(const Dictionary::Ptr& serializedUpdate)
: Logger(serializedUpdate)
{ }
/** /**
* Processes a log entry and outputs it to syslog. * Processes a log entry and outputs it to syslog.
* *

View File

@ -32,12 +32,14 @@ namespace icinga
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API SyslogLogger : public ILogger class I2_BASE_API SyslogLogger : public Logger
{ {
public: public:
typedef shared_ptr<SyslogLogger> Ptr; typedef shared_ptr<SyslogLogger> Ptr;
typedef weak_ptr<SyslogLogger> WeakPtr; typedef weak_ptr<SyslogLogger> WeakPtr;
explicit SyslogLogger(const Dictionary::Ptr& serializedUpdate);
protected: protected:
virtual void ProcessLogEntry(const LogEntry& entry); virtual void ProcessLogEntry(const LogEntry& entry);
}; };

View File

@ -33,11 +33,20 @@ type DynamicObject {
} }
type Logger { type Logger {
%attribute string "type",
%attribute string "path",
%attribute string "severity" %attribute string "severity"
} }
type ConsoleLogger inherits Logger {
}
type FileLogger inherits Logger {
%require "path",
%attribute string "path"
}
type SyslogLogger inherits Logger {
}
type Script { type Script {
%require "language", %require "language",
%attribute string "language", %attribute string "language",