diff options
Diffstat (limited to 'src/base/Logger.cpp')
-rw-r--r-- | src/base/Logger.cpp | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/src/base/Logger.cpp b/src/base/Logger.cpp new file mode 100644 index 0000000..dd7efe1 --- /dev/null +++ b/src/base/Logger.cpp @@ -0,0 +1,280 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library 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 2 of the License, or (at your option) any later version. +// +// This library 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 library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// + +#include "Logger.h" +#include "Exception.h" +#include "StandardLogSink.h" +#include "OSHelper.h" + +#include <boost/algorithm/string.hpp> + +#ifdef _WIN32 +#include <Winsock2.h> +#include <time.h> +#include <Mmsystem.h> +#undef ERROR +#else +#include <sys/time.h> +#include <syslog.h> +#endif +#include <iostream> +#include <iomanip> + +using namespace std; +namespace ba = boost::algorithm; + +namespace avg { + const severity_t Logger::severity::CRITICAL = 50; + const severity_t Logger::severity::ERROR = 40; + const severity_t Logger::severity::WARNING = 30; + const severity_t Logger::severity::INFO = 20; + const severity_t Logger::severity::DEBUG = 10; + const severity_t Logger::severity::NONE = 0; + + const category_t Logger::category::NONE = UTF8String("NONE"); + const category_t Logger::category::PROFILE = UTF8String("PROFILE"); + const category_t Logger::category::PROFILE_VIDEO = UTF8String("PROFILE_V"); + const category_t Logger::category::EVENTS = UTF8String("EVENTS"); + const category_t Logger::category::CONFIG = UTF8String("CONFIG"); + const category_t Logger::category::MEMORY = UTF8String("MEMORY"); + const category_t Logger::category::APP = UTF8String("APP"); + const category_t Logger::category::PLUGIN = UTF8String("PLUGIN"); + const category_t Logger::category::PLAYER = UTF8String("PLAYER"); + const category_t Logger::category::SHADER = UTF8String("SHADER"); + const category_t Logger::category::DEPRECATION = UTF8String("DEPREC"); + +namespace { + Logger* s_pLogger = 0; + boost::mutex s_logMutex; + boost::mutex s_traceMutex; + boost::mutex s_sinkMutex; + boost::mutex s_removeStdSinkMutex; +} + +boost::mutex Logger::m_CategoryMutex; + +Logger * Logger::get() +{ + lock_guard lock(s_logMutex); + if (!s_pLogger) { + s_pLogger = new Logger; + } + return s_pLogger; +} + +Logger::Logger() +{ + m_Severity = severity::WARNING; + string sEnvSeverity; + bool bEnvSeveritySet = getEnv("AVG_LOG_SEVERITY", sEnvSeverity); + if(bEnvSeveritySet) { + m_Severity = Logger::stringToSeverity(sEnvSeverity); + } + setupCategory(); + + string sEnvCategories; + bool bEnvSet = getEnv("AVG_LOG_CATEGORIES", sEnvCategories); + if (bEnvSet) { + vector<string> sCategories; + ba::split(sCategories, sEnvCategories, ba::is_any_of(" "), ba::token_compress_on); + vector<string>::iterator it; + for(it=sCategories.begin(); it!=sCategories.end(); it++) { + string::size_type pos = (*it).find(":"); + string sCategory; + string sSeverity = "NONE"; + if(pos == string::npos) { + sCategory = *it; + } else { + vector<string> tmpValues; + ba::split( tmpValues, *it, ba::is_any_of(":"), ba::token_compress_on); + sCategory = tmpValues.at(0); + sSeverity = tmpValues.at(1); + } + severity_t severity = stringToSeverity(sSeverity); + configureCategory(sCategory, severity); + } + } + + string sDummy; + bool bEnvOmitStdErr = getEnv("AVG_LOG_OMIT_STDERR", sDummy); + if (!bEnvOmitStdErr) { + m_pStdSink = LogSinkPtr(new StandardLogSink); + addLogSink(m_pStdSink); + } +} + +Logger::~Logger() +{ +} + +void Logger::addLogSink(const LogSinkPtr& logSink) +{ + lock_guard lock(s_sinkMutex); + m_pSinks.push_back(logSink); +} + +void Logger::removeLogSink(const LogSinkPtr& logSink) +{ + lock_guard lock(s_sinkMutex); + std::vector<LogSinkPtr>::iterator it; + it = find(m_pSinks.begin(), m_pSinks.end(), logSink); + if ( it != m_pSinks.end() ) { + m_pSinks.erase(it); + } +} + +void Logger::removeStdLogSink() +{ + lock_guard lock(s_removeStdSinkMutex); + if ( m_pStdSink.get()) { + removeLogSink(m_pStdSink); + m_pStdSink = LogSinkPtr(); + } +} + +category_t Logger::configureCategory(category_t category, severity_t severity) +{ + lock_guard lock(m_CategoryMutex); + severity = (severity == Logger::severity::NONE) ? m_Severity : severity; + UTF8String sCategory = boost::to_upper_copy(string(category)); + CatToSeverityMap::iterator it; + it = m_CategorySeverities.find(sCategory); + if ( it != m_CategorySeverities.end()) { + m_CategorySeverities.erase(sCategory); + } + pair<const category_t, const severity_t> element(sCategory, severity); + m_CategorySeverities.insert(element); + return sCategory; +} + +CatToSeverityMap Logger::getCategories() +{ + return m_CategorySeverities; +} + +void Logger::trace(const UTF8String& sMsg, const category_t& category, + severity_t severity) const +{ + lock_guard lock(s_traceMutex); + struct tm* pTime; + #ifdef _WIN32 + __int64 now; + _time64(&now); + pTime = _localtime64(&now); + DWORD tms = timeGetTime(); + unsigned millis = unsigned(tms % 1000); + #else + struct timeval time; + gettimeofday(&time, NULL); + pTime = localtime(&time.tv_sec); + unsigned millis = time.tv_usec/1000; + #endif + lock_guard lockHandler(s_sinkMutex); + std::vector<LogSinkPtr>::const_iterator it; + for(it=m_pSinks.begin(); it!=m_pSinks.end(); ++it){ + (*it)->logMessage(pTime, millis, category, severity, sMsg); + } +} + +void Logger::logDebug(const UTF8String& msg, const category_t& category) const +{ + log(msg, category, Logger::severity::DEBUG); +} + +void Logger::logInfo(const UTF8String& msg, const category_t& category) const +{ + log(msg, category, Logger::severity::INFO); +} + +void Logger::logWarning(const UTF8String& msg, const category_t& category) const +{ + log(msg, category, Logger::severity::WARNING); +} + +void Logger::logError(const UTF8String& msg, const category_t& category) const +{ + log(msg, category, Logger::severity::ERROR); +} + +void Logger::logCritical(const UTF8String& msg, const category_t& category) const +{ + log(msg, category, Logger::severity::CRITICAL); +} + +void Logger::log(const UTF8String& msg, const category_t& category, + severity_t severity) const +{ + if(shouldLog(category, severity)) { + Logger::trace(msg, category, severity); + } +} + +void Logger::setupCategory() +{ + configureCategory(category::NONE); + configureCategory(category::PROFILE); + configureCategory(category::PROFILE_VIDEO); + configureCategory(category::EVENTS); + configureCategory(category::CONFIG); + configureCategory(category::MEMORY); + configureCategory(category::APP); + configureCategory(category::PLUGIN); + configureCategory(category::PLAYER); + configureCategory(category::SHADER); + configureCategory(category::DEPRECATION); +} + +severity_t Logger::stringToSeverity(const string& sSeverity) +{ + string severity = boost::to_upper_copy(string(sSeverity)); + if (severity == "CRIT") { + return Logger::severity::CRITICAL; + } else if (severity == "ERR") { + return Logger::severity::ERROR; + } else if (severity == "WARN") { + return Logger::severity::WARNING; + } else if (severity == "INFO") { + return Logger::severity::INFO; + } else if (severity == "DBG") { + return Logger::severity::DEBUG; + } else if (severity == "NONE") { + return Logger::severity::NONE; + } + throw Exception(AVG_ERR_INVALID_ARGS, severity + " is an invalid log severity"); +} + +const char * Logger::severityToString(severity_t severity) +{ + if(severity == Logger::severity::CRITICAL) { + return "CRIT"; + } else if(severity == Logger::severity::ERROR) { + return "ERR"; + } else if(severity == Logger::severity::WARNING) { + return "WARN"; + } else if(severity == Logger::severity::INFO) { + return "INFO"; + } else if(severity == Logger::severity::DEBUG) { + return "DBG"; + } + throw Exception(AVG_ERR_UNKNOWN, "Unkown log severity"); +} + +} |