diff options
Diffstat (limited to 'src/Core')
-rw-r--r-- | src/Core/Application.cpp | 16 | ||||
-rw-r--r-- | src/Core/Application.h | 22 | ||||
-rw-r--r-- | src/Core/ConfigManager.cpp | 2 | ||||
-rw-r--r-- | src/Core/LogManager.cpp | 122 | ||||
-rw-r--r-- | src/Core/LogManager.h | 55 | ||||
-rw-r--r-- | src/Core/Logger.h | 55 | ||||
-rw-r--r-- | src/Core/LoggerBase.h | 81 | ||||
-rw-r--r-- | src/Core/RemoteLogger.h | 45 |
8 files changed, 145 insertions, 253 deletions
diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp index 7083be5..d75cbaf 100644 --- a/src/Core/Application.cpp +++ b/src/Core/Application.cpp @@ -40,7 +40,7 @@ Application::~Application() { } -void Application::logfv(LoggerBase::MessageCategory category, LoggerBase::MessageLevel level, const char *format, va_list ap) { +void Application::logfv(Logger::MessageCategory category, Logger::MessageLevel level, const char *format, va_list ap) { int size = 100; char *buf = (char*)std::malloc(size); @@ -68,35 +68,35 @@ void Application::logfv(LoggerBase::MessageCategory category, LoggerBase::Messag } -void Application::log(LoggerBase::MessageCategory category, LoggerBase::MessageLevel level, const std::string &message) { +void Application::log(Logger::MessageCategory category, Logger::MessageLevel level, const std::string &message) { logManager->log(category, level, boost::posix_time::microsec_clock::universal_time(), message); } -void Application::logf(LoggerBase::MessageCategory category, LoggerBase::MessageLevel level, const char *format, ...) { +void Application::logf(Logger::MessageCategory category, Logger::MessageLevel level, const char *format, ...) { va_list ap; va_start(ap, format); logfv(category, level, format, ap); va_end(ap); } -void Application::logf(LoggerBase::MessageCategory category, const char *format, ...) { +void Application::logf(Logger::MessageCategory category, const char *format, ...) { va_list ap; va_start(ap, format); - logfv(category, LoggerBase::LOG_DEFAULT, format, ap); + logfv(category, Logger::LOG_DEFAULT, format, ap); va_end(ap); } -void Application::logf(LoggerBase::MessageLevel level, const char *format, ...) { +void Application::logf(Logger::MessageLevel level, const char *format, ...) { va_list ap; va_start(ap, format); - logfv(LoggerBase::LOG_GENERAL, level, format, ap); + logfv(Logger::LOG_GENERAL, level, format, ap); va_end(ap); } void Application::logf(const char *format, ...) { va_list ap; va_start(ap, format); - logfv(LoggerBase::LOG_GENERAL, LoggerBase::LOG_DEFAULT, format, ap); + logfv(Logger::LOG_GENERAL, Logger::LOG_DEFAULT, format, ap); va_end(ap); } diff --git a/src/Core/Application.h b/src/Core/Application.h index 3951b5c..18521d5 100644 --- a/src/Core/Application.h +++ b/src/Core/Application.h @@ -22,7 +22,7 @@ #include "export.h" -#include "LoggerBase.h" +#include "Logger.h" #include <cstdarg> #include <string> @@ -45,7 +45,7 @@ class MAD_CORE_EXPORT Application : private boost::noncopyable { LogManager *logManager; ThreadManager *threadManager; - void logfv(LoggerBase::MessageCategory category, LoggerBase::MessageLevel level, const char *format, va_list ap); + void logfv(Logger::MessageCategory category, Logger::MessageLevel level, const char *format, va_list ap); protected: Application(); @@ -69,24 +69,24 @@ class MAD_CORE_EXPORT Application : private boost::noncopyable { } - void log(LoggerBase::MessageCategory category, LoggerBase::MessageLevel level, const std::string &message); + void log(Logger::MessageCategory category, Logger::MessageLevel level, const std::string &message); - void log(LoggerBase::MessageCategory category, const std::string &message) { - log(category, LoggerBase::LOG_DEFAULT, message); + void log(Logger::MessageCategory category, const std::string &message) { + log(category, Logger::LOG_DEFAULT, message); } - void log(LoggerBase::MessageLevel level, const std::string &message) { - log(LoggerBase::LOG_GENERAL, level, message); + void log(Logger::MessageLevel level, const std::string &message) { + log(Logger::LOG_GENERAL, level, message); } void log(const std::string &message) { - log(LoggerBase::LOG_GENERAL, LoggerBase::LOG_DEFAULT, message); + log(Logger::LOG_GENERAL, Logger::LOG_DEFAULT, message); } - void logf(LoggerBase::MessageCategory category, LoggerBase::MessageLevel level, const char *format, ...); - void logf(LoggerBase::MessageCategory category, const char *format, ...); - void logf(LoggerBase::MessageLevel level, const char *format, ...); + void logf(Logger::MessageCategory category, Logger::MessageLevel level, const char *format, ...); + void logf(Logger::MessageCategory category, const char *format, ...); + void logf(Logger::MessageLevel level, const char *format, ...); void logf(const char *format, ...); }; diff --git a/src/Core/ConfigManager.cpp b/src/Core/ConfigManager.cpp index 83e92db..bd20cc5 100644 --- a/src/Core/ConfigManager.cpp +++ b/src/Core/ConfigManager.cpp @@ -46,7 +46,7 @@ void ConfigManager::handleConfigEntry(const ConfigEntry &entry) { } if(!handled) - application->logf(LoggerBase::LOG_WARNING, "Invalid config option '%s'.", entry[entry.getSize()-1].getKey().c_str()); + application->logf(Logger::LOG_WARNING, "Invalid config option '%s'.", entry[entry.getSize()-1].getKey().c_str()); } bool ConfigManager::loadFile(const std::string &filename) { diff --git a/src/Core/LogManager.cpp b/src/Core/LogManager.cpp index b255c04..8fe7428 100644 --- a/src/Core/LogManager.cpp +++ b/src/Core/LogManager.cpp @@ -27,24 +27,41 @@ namespace Mad { namespace Core { -void LogManager::ConsoleLogger::logMessage(MessageCategory /*category*/, MessageLevel level, boost::posix_time::ptime /*timestamp*/, const std::string &message) { - if(level != LOG_CRITICAL) {// Critical messages are printed to cerr directly, so don't print them a second time - cerrLock.lock(); - std::cerr << message << std::endl; - cerrLock.unlock(); +void LogManager::ConsoleLogger::logMessage(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source) { + if(!(level == LOG_CRITICAL && source.empty())) {// Critical messages are printed to cerr directly, so don't print them a second time + boost::lock_guard<boost::mutex> lock(cerrMutex); + logMessageDirect(category, level, timestamp, message, source); } } -void LogManager::ConsoleLogger::logMessage(MessageCategory /*category*/, MessageLevel /*level*/, boost::posix_time::ptime /*timestamp*/, const std::string &message, const std::string &messageSource) { - cerrLock.lock(); - std::cerr << message << " from " << messageSource << std::endl; - cerrLock.unlock(); +void LogManager::ConsoleLogger::logMessageDirect(MessageCategory /*category*/, MessageLevel /*level*/, boost::posix_time::ptime /*timestamp*/, const std::string &message, const std::string &source) { + if(source.empty()) + std::cerr << message << std::endl; + else + std::cerr << message << " from " << source << std::endl; } -void LogManager::ConsoleLogger::logMessageDirect(MessageCategory /*category*/, MessageLevel /*level*/, boost::posix_time::ptime /*timestamp*/, const std::string &message) { - cerrLock.lock(); - std::cerr << message << std::endl; - cerrLock.unlock(); + +LogManager::MessageLevel LogManager::parseLevel(const std::string &str) throw (Exception) { + if(str.empty()) + return Logger::LOG_DEFAULT; + + std::string lowerStr = boost::algorithm::to_lower_copy(str); + + if(lowerStr == "debug") + return Logger::LOG_DEBUG; + else if(lowerStr == "verbose") + return Logger::LOG_VERBOSE; + else if(lowerStr == "default") + return Logger::LOG_DEFAULT; + else if(lowerStr == "warning") + return Logger::LOG_WARNING; + else if(lowerStr == "error") + return Logger::LOG_ERROR; + else if(lowerStr == "critical") + return Logger::LOG_CRITICAL; + else + throw Exception(Exception::INVALID_INPUT); } @@ -58,19 +75,30 @@ LogManager::~LogManager() { bool LogManager::handleConfigEntry(const ConfigEntry &entry, bool handled) { - if(handled) - return false; - - if(entry[0].getKey().matches("Logger")) { + if(entry[0].getKey().matches("Log")) { if(entry[0][0].matches("Console")) { if(entry[1].empty()) { - registerLogger(boost::static_pointer_cast<Logger>(consoleLogger)); + registerLogger(consoleLogger); return true; } + else if(entry[1].getKey().matches("Level")) { + if(entry[2].empty()) { + try { + consoleLogger->setLevel(parseLevel(entry[1][0])); + } + catch(Core::Exception e) { + application->logf(Logger::LOG_WARNING, "Unknown log level '%s'.", entry[1][0].c_str()); + } + + return true; + } + } } else if(entry[1].empty()) { - application->logf(Logger::LOG_WARNING, "Unknown logger '%s'.", entry[0][0].c_str()); - return true; + if(!handled) { + application->logf(Logger::LOG_WARNING, "Unknown logger '%s'.", entry[0][0].c_str()); + return true; + } } } @@ -79,38 +107,26 @@ bool LogManager::handleConfigEntry(const ConfigEntry &entry, bool handled) { void LogManager::configFinished() { if(loggers.empty()) - registerLogger(boost::static_pointer_cast<Logger>(consoleLogger)); + registerLogger(consoleLogger); - // TODO Debug - consoleLogger->Logger::setLevel(LoggerBase::LOG_VERBOSE); - queueLock.lock(); + boost::lock_guard<boost::mutex> lock(queueMutex); configured = true; - queueLock.unlock(); queueCond.notify_one(); } -void LogManager::log(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message) { - if(level == LoggerBase::LOG_CRITICAL) - consoleLogger->logMessageDirect(category, level, timestamp, message); +void LogManager::log(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source) { + if(level == Logger::LOG_CRITICAL && source.empty()) + consoleLogger->logMessageDirect(category, level, timestamp, message, source); - queueLock.lock(); - Message m = {category, level, timestamp, message}; + boost::lock_guard<boost::mutex> lock(queueMutex); + Message m = {category, level, timestamp, message, source}; messageQueue.push(m); - queueLock.unlock(); queueCond.notify_one(); } -void LogManager::log(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source) { - queueLock.lock(); - RemoteMessage m = {category, level, timestamp, message, source}; - remoteMessageQueue.push(m); - queueLock.unlock(); - queueCond.notify_one(); -} - void LogManager::loggerThread() { - boost::unique_lock<boost::mutex> lock(queueLock); + boost::unique_lock<boost::mutex> lock(queueMutex); running = true; @@ -123,27 +139,13 @@ void LogManager::loggerThread() { messageQueue.pop(); lock.unlock(); - loggerLock.lock(); - for(std::set<boost::shared_ptr<Logger> >::iterator logger = loggers.begin(); logger != loggers.end(); ++logger) { - if((*logger)->getLevel() >= message.level && (*logger)->isCategorySet(message.category)) - (*logger)->logMessage(message.category, message.level, message.timestamp, message.message); - } - loggerLock.unlock(); - - lock.lock(); - } - - while(!remoteMessageQueue.empty()) { - RemoteMessage message = remoteMessageQueue.front(); - remoteMessageQueue.pop(); - lock.unlock(); - - remoteLoggerLock.lock(); - for(std::set<boost::shared_ptr<RemoteLogger> >::iterator logger = remoteLoggers.begin(); logger != remoteLoggers.end(); ++logger) { - if((*logger)->getLevel() >= message.level && (*logger)->isCategorySet(message.category)) - (*logger)->logMessage(message.category, message.level, message.timestamp, message.message, message.source); + { + boost::lock_guard<boost::mutex> loggerLock(loggerMutex); + for(std::set<boost::shared_ptr<Logger> >::iterator logger = loggers.begin(); logger != loggers.end(); ++logger) { + if((*logger)->getLevel() >= message.level && (*logger)->isCategorySet(message.category)) + (*logger)->logMessage(message.category, message.level, message.timestamp, message.message, message.source); + } } - remoteLoggerLock.unlock(); lock.lock(); } diff --git a/src/Core/LogManager.h b/src/Core/LogManager.h index 3aab49e..c569238 100644 --- a/src/Core/LogManager.h +++ b/src/Core/LogManager.h @@ -23,8 +23,8 @@ #include "export.h" #include "Configurable.h" +#include "Exception.h" #include "Logger.h" -#include "RemoteLogger.h" #include <queue> #include <set> @@ -43,38 +43,30 @@ class MAD_CORE_EXPORT LogManager : public Configurable { friend class Application; friend class ThreadManager; - typedef LoggerBase::MessageCategory MessageCategory; - typedef LoggerBase::MessageLevel MessageLevel; + typedef Logger::MessageCategory MessageCategory; + typedef Logger::MessageLevel MessageLevel; struct Message { MessageCategory category; MessageLevel level; boost::posix_time::ptime timestamp; std::string message; - }; - - struct RemoteMessage { - MessageCategory category; - MessageLevel level; - boost::posix_time::ptime timestamp; - std::string message; std::string source; }; - class ConsoleLogger : public Logger, public RemoteLogger { + class ConsoleLogger : public Logger { private: // For long messages, writing to cerr is not atomic // -> lock cerr to prevent messages mixing up - boost::mutex cerrLock; + boost::mutex cerrMutex; protected: - virtual void logMessage(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message); - virtual void logMessage(MessageCategory category, MessageLevel, boost::posix_time::ptime timestamp, const std::string &message, const std::string &messageSource); + virtual void logMessage(MessageCategory category, MessageLevel, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source); public: ConsoleLogger() {} - void logMessageDirect(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message); + void logMessageDirect(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source); }; @@ -83,23 +75,19 @@ class MAD_CORE_EXPORT LogManager : public Configurable { boost::shared_ptr<ConsoleLogger> consoleLogger; std::set<boost::shared_ptr<Logger> > loggers; - std::set<boost::shared_ptr<RemoteLogger> > remoteLoggers; bool configured, running; - boost::mutex queueLock; + boost::mutex queueMutex; boost::condition_variable queueCond; - boost::mutex loggerLock; - boost::mutex remoteLoggerLock; + boost::mutex loggerMutex; std::queue<Message> messageQueue; - std::queue<RemoteMessage> remoteMessageQueue; void loggerThread(); void stopLoggerThread() { - queueLock.lock(); + boost::lock_guard<boost::mutex> lock(queueMutex); running = false; - queueLock.unlock(); queueCond.notify_one(); } @@ -111,31 +99,18 @@ class MAD_CORE_EXPORT LogManager : public Configurable { virtual void configFinished(); public: - void log(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message); - void log(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source); + static MessageLevel parseLevel(const std::string &str) throw (Exception); + + void log(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source = std::string()); void registerLogger(boost::shared_ptr<Logger> logger) { - loggerLock.lock(); + boost::lock_guard<boost::mutex> lock(loggerMutex); loggers.insert(logger); - loggerLock.unlock(); } void unregisterLogger(boost::shared_ptr<Logger> logger) { - loggerLock.lock(); + boost::lock_guard<boost::mutex> lock(loggerMutex); loggers.erase(logger); - loggerLock.unlock(); - } - - void registerLogger(boost::shared_ptr<RemoteLogger> logger) { - remoteLoggerLock.lock(); - remoteLoggers.insert(logger); - remoteLoggerLock.unlock(); - } - - void unregisterLogger(boost::shared_ptr<RemoteLogger> logger) { - remoteLoggerLock.lock(); - remoteLoggers.erase(logger); - remoteLoggerLock.unlock(); } }; diff --git a/src/Core/Logger.h b/src/Core/Logger.h index 53ec665..24582bc 100644 --- a/src/Core/Logger.h +++ b/src/Core/Logger.h @@ -20,10 +20,7 @@ #ifndef MAD_CORE_LOGGER_H_ #define MAD_CORE_LOGGER_H_ -#include "export.h" - -#include "LoggerBase.h" - +#include <bitset> #include <string> #include <boost/date_time/posix_time/ptime.hpp> @@ -32,12 +29,56 @@ namespace Core { class LogManager; -class Logger : public LoggerBase { - protected: +class Logger { + public: friend class LogManager; - virtual void logMessage(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message) = 0; + enum MessageLevel { + LOG_CRITICAL, LOG_ERROR, LOG_WARNING, LOG_DEFAULT, LOG_VERBOSE, LOG_DEBUG + }; + + enum MessageCategory { + LOG_SYSTEM, LOG_NETWORK, LOG_DAEMON, LOG_USER, LOG_DISK, LOG_PROGRAM, LOG_GENERAL + }; + + private: + std::bitset<16> categories; + MessageLevel level; + + protected: + Logger() : level(LOG_DEFAULT) {setAllCategories();} + virtual ~Logger() {} + + virtual void logMessage(MessageCategory category, MessageLevel level, boost::posix_time::ptime timestamp, const std::string &message, const std::string &source) = 0; + + public: + void setCategory(MessageCategory newCategory) { + categories.set(newCategory); + } + + void unsetCategory(MessageCategory oldCategory) { + categories.reset(oldCategory); + } + + void setAllCategories() { + categories.set(); + } + + void unsetAllCategories() { + categories.reset(); + } + + bool isCategorySet(MessageCategory category) const { + return categories.test(category); + } + + MessageLevel getLevel() const { + return level; + } + void setLevel(MessageLevel newLevel) { + level = newLevel; + } }; } diff --git a/src/Core/LoggerBase.h b/src/Core/LoggerBase.h deleted file mode 100644 index a2df969..0000000 --- a/src/Core/LoggerBase.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * LoggerBase.h - * - * Copyright (C) 2008 Johannes Thorn <dante@g4t3.de> - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef MAD_CORE_LOGGERBASE_H_ -#define MAD_CORE_LOGGERBASE_H_ - -#include "export.h" - -#include <bitset> -#include <list> - -namespace Mad { -namespace Core { - -class LoggerBase { - public: - enum MessageLevel { - LOG_CRITICAL, LOG_ERROR, LOG_WARNING, LOG_DEFAULT, LOG_VERBOSE, LOG_DEBUG - }; - - enum MessageCategory { - LOG_SYSTEM, LOG_NETWORK, LOG_DAEMON, LOG_USER, LOG_DISK, LOG_PROGRAM, LOG_GENERAL - }; - - protected: - std::bitset<16> categories; - MessageLevel level; - - LoggerBase() : level(LOG_DEFAULT) {setAllCategories();} - virtual ~LoggerBase() {} - - public: - void setCategory(MessageCategory newCategory) { - categories.set(newCategory); - } - - void unsetCategory(MessageCategory oldCategory) { - categories.reset(oldCategory); - } - - void setAllCategories() { - categories.set(); - } - - void unsetAllCategories() { - categories.reset(); - } - - bool isCategorySet(MessageCategory category) const { - return categories.test(category); - } - - MessageLevel getLevel() const { - return level; - } - - void setLevel(MessageLevel newLevel) { - level = newLevel; - } -}; - -} -} - -#endif /* MAD_CORE_LOGGERBASE_H_ */ diff --git a/src/Core/RemoteLogger.h b/src/Core/RemoteLogger.h deleted file mode 100644 index 8dedb7a..0000000 --- a/src/Core/RemoteLogger.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * LogRequestLogger.h - * - * Copyright (C) 2008 Johannes Thorn <dante@g4t3.de> - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef MAD_CORE_REMOTELOGGER_H_ -#define MAD_CORE_REMOTELOGGER_H_ - -#include "export.h" - -#include "LoggerBase.h" - -#include <string> -#include <boost/date_time/posix_time/ptime.hpp> - -namespace Mad { -namespace Core { - -class LogManager; - -class RemoteLogger : public LoggerBase { - protected: - friend class LogManager; - - virtual void logMessage(MessageCategory category, MessageLevel level, boost::posix_time::ptime messageTimestamp, const std::string &message, const std::string &messageSource) = 0; -}; - -} -} - -#endif /* MAD_CORE_REMOTELOGGER_H_ */ |