mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-08 17:05:25 +02:00
Implemented logging to files and made logging configurable.
This commit is contained in:
parent
86ae6579ed
commit
a64c99c176
@ -11,8 +11,6 @@ libbase_la_SOURCES = \
|
||||
component.h \
|
||||
configobject.cpp \
|
||||
configobject.h \
|
||||
consolelogger.cpp \
|
||||
consolelogger.h \
|
||||
dictionary.cpp \
|
||||
dictionary.h \
|
||||
event.cpp \
|
||||
@ -34,6 +32,8 @@ libbase_la_SOURCES = \
|
||||
ringbuffer.h \
|
||||
socket.cpp \
|
||||
socket.h \
|
||||
streamlogger.cpp \
|
||||
streamlogger.h \
|
||||
sysloglogger.cpp \
|
||||
sysloglogger.h \
|
||||
tcpclient.cpp \
|
||||
|
@ -396,7 +396,7 @@ int Application::Run(int argc, char **argv)
|
||||
} else {
|
||||
try {
|
||||
result = Main(m_Arguments);
|
||||
} catch (const std::exception& ex) {
|
||||
} catch (const exception& ex) {
|
||||
Application::m_Instance.reset();
|
||||
|
||||
Logger::Write(LogCritical, "base", "---");
|
||||
|
@ -1,48 +0,0 @@
|
||||
#include "i2-base.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
/**
|
||||
* Constructor for the ConsoleLogger class.
|
||||
*
|
||||
* @param minSeverity Minimum severity for log messages.
|
||||
*/
|
||||
ConsoleLogger::ConsoleLogger(LogSeverity minSeverity)
|
||||
: Logger(minSeverity)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Processes a log entry and outputs it to standard out.
|
||||
*
|
||||
* @param entry The log entry.
|
||||
*/
|
||||
void ConsoleLogger::ProcessLogEntry(const LogEntry& entry)
|
||||
{
|
||||
char timestamp[100];
|
||||
|
||||
string severityStr;
|
||||
switch (entry.Severity) {
|
||||
case LogDebug:
|
||||
severityStr = "debug";
|
||||
break;
|
||||
case LogInformation:
|
||||
severityStr = "info";
|
||||
break;
|
||||
case LogWarning:
|
||||
severityStr = "warning";
|
||||
break;
|
||||
case LogCritical:
|
||||
severityStr = "critical";
|
||||
break;
|
||||
default:
|
||||
assert(!"Invalid severity specified.");
|
||||
}
|
||||
|
||||
tm tmnow = *localtime(&entry.Timestamp);
|
||||
|
||||
strftime(timestamp, sizeof(timestamp), "%Y/%m/%d %H:%M:%S", &tmnow);
|
||||
|
||||
std::cout << "[" << timestamp << "] "
|
||||
<< severityStr << "/" << entry.Facility << ": "
|
||||
<< entry.Message << std::endl;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#ifndef CONSOLELOGGER_H
|
||||
#define CONSOLELOGGER_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A logger that logs to stdout.
|
||||
*/
|
||||
class ConsoleLogger : public Logger
|
||||
{
|
||||
public:
|
||||
ConsoleLogger(LogSeverity minSeverity);
|
||||
|
||||
protected:
|
||||
virtual void ProcessLogEntry(const LogEntry& entry);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* CONSOLELOGGER_H */
|
@ -28,7 +28,7 @@ namespace icinga
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_BASE_API Exception : public virtual std::exception
|
||||
class I2_BASE_API Exception : public virtual exception
|
||||
{
|
||||
public:
|
||||
Exception(void)
|
||||
|
@ -86,6 +86,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <typeinfo>
|
||||
#include <map>
|
||||
@ -103,7 +104,10 @@ using std::pair;
|
||||
using std::deque;
|
||||
|
||||
using std::stringstream;
|
||||
using std::ostream;
|
||||
using std::ofstream;
|
||||
|
||||
using std::exception;
|
||||
using std::runtime_error;
|
||||
using std::logic_error;
|
||||
using std::invalid_argument;
|
||||
@ -169,7 +173,7 @@ using boost::system_time;
|
||||
#include "component.h"
|
||||
#include "threadpool.h"
|
||||
#include "logger.h"
|
||||
#include "consolelogger.h"
|
||||
#include "streamlogger.h"
|
||||
#include "sysloglogger.h"
|
||||
|
||||
#endif /* I2BASE_H */
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
vector<Logger::Ptr> Logger::m_Loggers;
|
||||
set<Logger::Ptr> Logger::m_Loggers;
|
||||
|
||||
/**
|
||||
* Constructor for the logger class.
|
||||
@ -63,7 +63,19 @@ void Logger::RegisterLogger(const Logger::Ptr& logger)
|
||||
{
|
||||
assert(Application::IsMainThread());
|
||||
|
||||
m_Loggers.push_back(logger);
|
||||
m_Loggers.insert(logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a logger.
|
||||
*
|
||||
* @param logger The logger.
|
||||
*/
|
||||
void Logger::UnregisterLogger(const Logger::Ptr& logger)
|
||||
{
|
||||
assert(Application::IsMainThread());
|
||||
|
||||
m_Loggers.erase(logger);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +95,7 @@ LogSeverity Logger::GetMinSeverity(void) const
|
||||
*/
|
||||
void Logger::ForwardLogEntry(const LogEntry& entry)
|
||||
{
|
||||
vector<Logger::Ptr>::iterator it;
|
||||
set<Logger::Ptr>::iterator it;
|
||||
for (it = m_Loggers.begin(); it != m_Loggers.end(); it++) {
|
||||
Logger::Ptr logger = *it;
|
||||
|
||||
|
@ -57,12 +57,13 @@ public:
|
||||
typedef shared_ptr<Logger> Ptr;
|
||||
typedef weak_ptr<Logger> WeakPtr;
|
||||
|
||||
Logger(LogSeverity minSeverity = LogDebug);
|
||||
Logger(LogSeverity minSeverity);
|
||||
|
||||
static void Write(LogSeverity severity, const string& facility,
|
||||
const string& message);
|
||||
|
||||
static void RegisterLogger(const Logger::Ptr& logger);
|
||||
static void UnregisterLogger(const Logger::Ptr& logger);
|
||||
|
||||
protected:
|
||||
virtual void ProcessLogEntry(const LogEntry& entry) = 0;
|
||||
@ -72,7 +73,7 @@ protected:
|
||||
private:
|
||||
LogSeverity m_MinSeverity;
|
||||
|
||||
static vector<Logger::Ptr> m_Loggers;
|
||||
static set<Logger::Ptr> m_Loggers;
|
||||
|
||||
static void ForwardLogEntry(const LogEntry& entry);
|
||||
};
|
||||
|
@ -156,7 +156,7 @@ int Socket::GetLastSocketError(void)
|
||||
*
|
||||
* @param ex An exception.
|
||||
*/
|
||||
void Socket::HandleSocketError(const std::exception& ex)
|
||||
void Socket::HandleSocketError(const exception& ex)
|
||||
{
|
||||
if (!OnError.empty()) {
|
||||
Event::Ptr ev = boost::make_shared<Event>();
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
|
||||
~Socket(void);
|
||||
|
||||
boost::signal<void (const Socket::Ptr&, const std::exception&)> OnError;
|
||||
boost::signal<void (const Socket::Ptr&, const exception&)> OnError;
|
||||
boost::signal<void (const Socket::Ptr&)> OnClosed;
|
||||
|
||||
virtual void Start(void);
|
||||
@ -55,7 +55,7 @@ protected:
|
||||
|
||||
int GetError(void) const;
|
||||
static int GetLastSocketError(void);
|
||||
void HandleSocketError(const std::exception& ex);
|
||||
void HandleSocketError(const exception& ex);
|
||||
|
||||
virtual bool WantsToRead(void) const;
|
||||
virtual bool WantsToWrite(void) const;
|
||||
|
85
base/streamlogger.cpp
Normal file
85
base/streamlogger.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "i2-base.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
/**
|
||||
* Constructor for the StreamLogger class.
|
||||
*
|
||||
* @param minSeverity Minimum severity for log messages.
|
||||
*/
|
||||
StreamLogger::StreamLogger(LogSeverity minSeverity)
|
||||
: Logger(minSeverity), m_Stream(NULL), m_OwnsStream(false)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Constructor for the StreamLogger class.
|
||||
*
|
||||
* @param stream The stream.
|
||||
* @param minSeverity Minimum severity for log messages.
|
||||
*/
|
||||
StreamLogger::StreamLogger(ostream *stream, LogSeverity minSeverity)
|
||||
: Logger(minSeverity), m_Stream(stream), m_OwnsStream(false)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Destructor for the StreamLogger class.
|
||||
*/
|
||||
StreamLogger::~StreamLogger(void)
|
||||
{
|
||||
if (m_OwnsStream)
|
||||
delete m_Stream;
|
||||
}
|
||||
|
||||
void StreamLogger::OpenFile(const string& filename)
|
||||
{
|
||||
ofstream *stream = new ofstream();
|
||||
|
||||
try {
|
||||
stream->open(filename.c_str(), ofstream::out | ofstream::trunc);
|
||||
|
||||
if (!stream->good())
|
||||
throw runtime_error("Could not open logfile '" + filename + "'");
|
||||
} catch (const exception&) {
|
||||
delete stream;
|
||||
throw;
|
||||
}
|
||||
|
||||
m_Stream = stream;
|
||||
m_OwnsStream = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a log entry and outputs it to a stream.
|
||||
*
|
||||
* @param entry The log entry.
|
||||
*/
|
||||
void StreamLogger::ProcessLogEntry(const LogEntry& entry)
|
||||
{
|
||||
char timestamp[100];
|
||||
|
||||
string severityStr;
|
||||
switch (entry.Severity) {
|
||||
case LogDebug:
|
||||
severityStr = "debug";
|
||||
break;
|
||||
case LogInformation:
|
||||
severityStr = "info";
|
||||
break;
|
||||
case LogWarning:
|
||||
severityStr = "warning";
|
||||
break;
|
||||
case LogCritical:
|
||||
severityStr = "critical";
|
||||
break;
|
||||
default:
|
||||
assert(!"Invalid severity specified.");
|
||||
}
|
||||
|
||||
tm tmnow = *localtime(&entry.Timestamp);
|
||||
|
||||
strftime(timestamp, sizeof(timestamp), "%Y/%m/%d %H:%M:%S", &tmnow);
|
||||
|
||||
*m_Stream << "[" << timestamp << "] "
|
||||
<< severityStr << "/" << entry.Facility << ": "
|
||||
<< entry.Message << std::endl;
|
||||
}
|
31
base/streamlogger.h
Normal file
31
base/streamlogger.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef STREAMLOGGER_H
|
||||
#define STREAMLOGGER_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A logger that logs to stdout.
|
||||
*/
|
||||
class StreamLogger : public Logger
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<StreamLogger> Ptr;
|
||||
typedef weak_ptr<StreamLogger> WeakPtr;
|
||||
|
||||
StreamLogger(LogSeverity minSeverity);
|
||||
StreamLogger(std::ostream *stream, LogSeverity minSeverity);
|
||||
~StreamLogger(void);
|
||||
|
||||
void OpenFile(const string& filename);
|
||||
protected:
|
||||
virtual void ProcessLogEntry(const LogEntry& entry);
|
||||
|
||||
private:
|
||||
ostream *m_Stream;
|
||||
bool m_OwnsStream;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* STREAMLOGGER_H */
|
@ -10,6 +10,9 @@ namespace icinga
|
||||
class SyslogLogger : public Logger
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<SyslogLogger> Ptr;
|
||||
typedef weak_ptr<SyslogLogger> WeakPtr;
|
||||
|
||||
SyslogLogger(LogSeverity minSeverity);
|
||||
|
||||
protected:
|
||||
|
@ -263,7 +263,7 @@ void CIBSyncComponent::RemoteObjectCommittedHandler(const Endpoint::Ptr& sender,
|
||||
m_SyncingConfig = true;
|
||||
object->Commit();
|
||||
m_SyncingConfig = false;
|
||||
} catch (const std::exception&) {
|
||||
} catch (const exception&) {
|
||||
m_SyncingConfig = false;
|
||||
throw;
|
||||
}
|
||||
@ -293,7 +293,7 @@ void CIBSyncComponent::RemoteObjectRemovedHandler(const RequestMessage& request)
|
||||
m_SyncingConfig = true;
|
||||
object->Unregister();
|
||||
m_SyncingConfig = false;
|
||||
} catch (const std::exception&) {
|
||||
} catch (const exception&) {
|
||||
m_SyncingConfig = false;
|
||||
throw;
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ void DiscoveryComponent::DiscoveryTimerHandler(void)
|
||||
try {
|
||||
if (!info->Node.empty() && !info->Service.empty())
|
||||
endpointManager->AddConnection(info->Node, info->Service);
|
||||
} catch (const std::exception& ex) {
|
||||
} catch (const exception& ex) {
|
||||
stringstream msgbuf;
|
||||
msgbuf << "Exception while trying to reconnect to endpoint '" << endpoint->GetIdentity() << "': " << ex.what();;
|
||||
Logger::Write(LogInformation, "discovery", msgbuf.str());
|
||||
|
@ -36,12 +36,9 @@ using namespace icinga;
|
||||
*/
|
||||
int IcingaApplication::Main(const vector<string>& args)
|
||||
{
|
||||
ConsoleLogger::Ptr consoleLogger = boost::make_shared<ConsoleLogger>(LogInformation);
|
||||
StreamLogger::Ptr consoleLogger = boost::make_shared<StreamLogger>(&std::cout, LogInformation);
|
||||
Logger::RegisterLogger(consoleLogger);
|
||||
|
||||
SyslogLogger::Ptr syslogLogger = boost::make_shared<SyslogLogger>(LogInformation);
|
||||
Logger::RegisterLogger(syslogLogger);
|
||||
|
||||
#ifdef _WIN32
|
||||
Logger::Write(LogInformation, "icinga", "Icinga component loader");
|
||||
#else /* _WIN32 */
|
||||
@ -52,11 +49,64 @@ int IcingaApplication::Main(const vector<string>& args)
|
||||
|
||||
if (args.size() < 2) {
|
||||
stringstream msgbuf;
|
||||
msgbuf << "Syntax: " << args[0] << " <config-file>";
|
||||
msgbuf << "Syntax: " << args[0] << " [-S] [-L logfile] [-d] [--] <config-file>";
|
||||
Logger::Write(LogInformation, "icinga", msgbuf.str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
bool enableSyslog = false;
|
||||
bool daemonize = false;
|
||||
bool parseOpts = true;
|
||||
string configFile;
|
||||
|
||||
/* TODO: clean up this mess; for now it will just have to do */
|
||||
vector<string>::const_iterator it;
|
||||
for (it = args.begin() + 1 ; it != args.end(); it++) {
|
||||
string arg = *it;
|
||||
|
||||
/* ignore empty arguments */
|
||||
if (arg.empty())
|
||||
continue;
|
||||
|
||||
if (arg == "--") {
|
||||
parseOpts = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parseOpts && arg[0] == '-') {
|
||||
if (arg == "-S") {
|
||||
enableSyslog = true;
|
||||
continue;
|
||||
} else if (arg == "-L") {
|
||||
if (it + 1 == args.end())
|
||||
throw invalid_argument("Option -L requires a parameter");
|
||||
|
||||
StreamLogger::Ptr fileLogger = boost::make_shared<StreamLogger>(LogInformation);
|
||||
fileLogger->OpenFile(*(it + 1));
|
||||
Logger::RegisterLogger(fileLogger);
|
||||
|
||||
it++;
|
||||
|
||||
continue;
|
||||
} else {
|
||||
throw invalid_argument("Unknown option: " + arg);
|
||||
}
|
||||
}
|
||||
|
||||
configFile = arg;
|
||||
|
||||
if (it + 1 != args.end())
|
||||
throw invalid_argument("Trailing command line arguments after config filename.");
|
||||
}
|
||||
|
||||
if (configFile.empty())
|
||||
throw invalid_argument("No config file was specified on the command line.");
|
||||
|
||||
if (enableSyslog) {
|
||||
SyslogLogger::Ptr syslogLogger = boost::make_shared<SyslogLogger>(LogInformation);
|
||||
Logger::RegisterLogger(syslogLogger);
|
||||
}
|
||||
|
||||
string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2";
|
||||
AddComponentSearchDir(componentDirectory);
|
||||
|
||||
@ -79,7 +129,7 @@ int IcingaApplication::Main(const vector<string>& args)
|
||||
fileComponentConfig->SetType("component");
|
||||
fileComponentConfig->SetName("configfile");
|
||||
fileComponentConfig->SetLocal(true);
|
||||
fileComponentConfig->AddExpression("configFilename", OperatorSet, args[1]);
|
||||
fileComponentConfig->AddExpression("configFilename", OperatorSet, configFile);
|
||||
fileComponentConfig->Compile()->Commit();
|
||||
|
||||
ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("application", "icinga");
|
||||
@ -111,6 +161,12 @@ int IcingaApplication::Main(const vector<string>& args)
|
||||
if (!service.empty())
|
||||
EndpointManager::GetInstance()->AddListener(service);
|
||||
|
||||
if (daemonize) {
|
||||
Logger::Write(LogInformation, "icinga", "Daemonizing.");
|
||||
Utility::Daemonize();
|
||||
Logger::UnregisterLogger(consoleLogger);
|
||||
}
|
||||
|
||||
RunEventLoop();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
@ -127,7 +127,7 @@ void JsonRpcEndpoint::ClientClosedHandler(void)
|
||||
// TODO: persist events, etc., for now we just disable the endpoint
|
||||
}
|
||||
|
||||
void JsonRpcEndpoint::ClientErrorHandler(const std::exception& ex)
|
||||
void JsonRpcEndpoint::ClientErrorHandler(const exception& ex)
|
||||
{
|
||||
stringstream message;
|
||||
message << "Error occured for JSON-RPC socket: Message=" << ex.what();
|
||||
|
@ -64,7 +64,7 @@ void JsonRpcClient::DataAvailableHandler(void)
|
||||
try {
|
||||
message = MessagePart(jsonString);
|
||||
OnNewMessage(GetSelf(), message);
|
||||
} catch (const std::exception& ex) {
|
||||
} catch (const exception& ex) {
|
||||
Logger::Write(LogCritical, "jsonrpc", "Exception while processing message from JSON-RPC client: " + string(ex.what()));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user