/* * LogManager.h * * Copyright (C) 2008 Matthias Schiffer * * 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 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef MAD_COMMON_LOGMANAGER_H_ #define MAD_COMMON_LOGMANAGER_H_ #include #include "Configurable.h" #include "Logger.h" #include "RemoteLogger.h" #include #include #include "glthread/lock.h" #include "glthread/cond.h" namespace Mad { namespace Common { class ThreadManager; class LogManager : public Configurable { private: friend class ThreadManager; typedef LoggerBase::MessageCategory MessageCategory; typedef LoggerBase::MessageLevel MessageLevel; struct Message { MessageCategory category; MessageLevel level; time_t timestamp; std::string message; }; struct RemoteMessage { MessageCategory category; MessageLevel level; time_t timestamp; std::string message; std::string source; }; class ConsoleLogger : public Logger, public RemoteLogger { private: // For long messages, writing to cerr is not atomic // -> lock cerr to prevent mixing messages up gl_lock_t cerrLock; protected: virtual void logMessage(MessageCategory category _UNUSED_PARAMETER_, MessageLevel level, time_t timestamp _UNUSED_PARAMETER_, const std::string &message); virtual void logMessage(MessageCategory category _UNUSED_PARAMETER_, MessageLevel, time_t timestamp _UNUSED_PARAMETER_, const std::string &message, const std::string &messageSource); public: ConsoleLogger() {} void logMessageDirect(MessageCategory category _UNUSED_PARAMETER_, MessageLevel level _UNUSED_PARAMETER_, time_t timestamp _UNUSED_PARAMETER_, const std::string &message); }; static LogManager logManager; ConsoleLogger consoleLogger; std::set loggers; std::set remoteLoggers; bool configured, running; gl_lock_t lock; gl_cond_t queueCond; gl_lock_t loggerLock; gl_lock_t remoteLoggerLock; std::queue messageQueue; std::queue remoteMessageQueue; void loggerThread(); void stopLoggerThread() { gl_lock_lock(lock); running = false; gl_cond_signal(queueCond); gl_lock_unlock(lock); } LogManager() : configured(false), running(false) { gl_lock_init(lock); gl_lock_init(loggerLock); gl_lock_init(remoteLoggerLock); } protected: virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); virtual void configFinished(); public: ~LogManager() { gl_lock_destroy(remoteLoggerLock); gl_lock_destroy(loggerLock); gl_lock_destroy(lock); } void log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message); void log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message, const std::string &source); void registerLogger(Logger *logger) { gl_lock_lock(loggerLock); loggers.insert(logger); gl_lock_unlock(loggerLock); } void unregisterLogger(Logger *logger) { gl_lock_lock(loggerLock); loggers.erase(logger); gl_lock_unlock(loggerLock); } void registerLogger(RemoteLogger *logger) { gl_lock_lock(remoteLoggerLock); remoteLoggers.insert(logger); gl_lock_unlock(remoteLoggerLock); } void unregisterLogger(RemoteLogger *logger) { gl_lock_lock(remoteLoggerLock); remoteLoggers.erase(logger); gl_lock_unlock(remoteLoggerLock); } static LogManager *get() { return &logManager; } }; } } #endif /* MAD_COMMON_LOGMANAGER_H_ */