summaryrefslogtreecommitdiff
path: root/src/base/Logger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/Logger.cpp')
-rw-r--r--src/base/Logger.cpp280
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");
+}
+
+}