[Box Backup-commit] COMMIT r1293 - box/chris/general/lib/common

boxbackup-dev@fluffy.co.uk boxbackup-dev@fluffy.co.uk
Tue, 20 Feb 2007 23:37:32 +0000


Author: chris
Date: 2007-02-20 23:37:32 +0000 (Tue, 20 Feb 2007)
New Revision: 1293

Added:
   box/chris/general/lib/common/Logging.cpp
   box/chris/general/lib/common/Logging.h
Log:
Added logging framework from merge tree


Copied: box/chris/general/lib/common/Logging.cpp (from rev 1292, box/chris/merge/lib/common/Logging.cpp)
===================================================================
--- box/chris/general/lib/common/Logging.cpp	                        (rev 0)
+++ box/chris/general/lib/common/Logging.cpp	2007-02-20 23:37:32 UTC (rev 1293)
@@ -0,0 +1,236 @@
+// --------------------------------------------------------------------------
+//
+// File
+//		Name:    Logging.cpp
+//		Purpose: Generic logging core routines implementation
+//		Created: 2006/12/16
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#ifdef HAVE_SYSLOG_H
+	#include <syslog.h>
+#endif
+
+#include "Logging.h"
+
+bool Logging::sLogToSyslog  = false;
+bool Logging::sLogToConsole = false;
+bool Logging::sContextSet   = false;
+
+std::vector<Logger*> Logging::sLoggers;
+std::string Logging::sContext;
+Console*    Logging::spConsole = NULL;
+Syslog*     Logging::spSyslog  = NULL;
+Log::Level  Logging::sGlobalLevel = Log::EVERYTHING;
+Logging     Logging::sGlobalLogging; //automatic initialisation
+
+Logging::Logging()
+{
+	ASSERT(!spConsole);
+	ASSERT(!spSyslog);
+	spConsole = new Console();
+	spSyslog  = new Syslog();
+	sLogToConsole = true;
+	sLogToSyslog  = true;
+}
+
+Logging::~Logging()
+{
+	sLogToConsole = false;
+	sLogToSyslog  = false;
+	delete spConsole;
+	delete spSyslog;
+	spConsole = NULL;
+	spSyslog  = NULL;
+}
+
+void Logging::ToSyslog(bool enabled)
+{
+	if (!sLogToSyslog && enabled)
+	{
+		Add(spSyslog);
+	}
+	
+	if (sLogToSyslog && !enabled)
+	{
+		Remove(spSyslog);
+	}
+	
+	sLogToSyslog = enabled;
+}
+
+void Logging::ToConsole(bool enabled)
+{
+	if (!sLogToConsole && enabled)
+	{
+		Add(spConsole);
+	}
+	
+	if (sLogToConsole && !enabled)
+	{
+		Remove(spConsole);
+	}
+	
+	sLogToConsole = enabled;
+}
+
+void Logging::FilterConsole(Log::Level level)
+{
+	spConsole->Filter(level);
+}
+
+void Logging::FilterSyslog(Log::Level level)
+{
+	spSyslog->Filter(level);
+}
+
+void Logging::Add(Logger* pNewLogger)
+{
+	for (std::vector<Logger*>::iterator i = sLoggers.begin();
+		i != sLoggers.end(); i++)
+	{
+		if (*i == pNewLogger)
+		{
+			return;
+		}
+	}
+	
+	sLoggers.insert(sLoggers.begin(), pNewLogger);
+}
+
+void Logging::Remove(Logger* pOldLogger)
+{
+	for (std::vector<Logger*>::iterator i = sLoggers.begin();
+		i != sLoggers.end(); i++)
+	{
+		if (*i == pOldLogger)
+		{
+			sLoggers.erase(i);
+			return;
+		}
+	}
+}
+
+void Logging::Log(Log::Level level, const std::string& rFile, 
+	int line, const std::string& rMessage)
+{
+	if (level > sGlobalLevel)
+	{
+		return;
+	}
+
+	std::string newMessage;
+	
+	if (sContextSet)
+	{
+		newMessage += "[" + sContext + "] ";
+	}
+	
+	newMessage += rMessage;
+	
+	for (std::vector<Logger*>::iterator i = sLoggers.begin();
+		i != sLoggers.end(); i++)
+	{
+		bool result = (*i)->Log(level, rFile, line, newMessage);
+		if (!result)
+		{
+			return;
+		}
+	}
+}
+
+void Logging::SetContext(std::string context)
+{
+	sContext = context;
+	sContextSet = true;
+}
+
+void Logging::ClearContext()
+{
+	sContextSet = false;
+}
+
+void Logging::SetProgramName(const std::string& rProgramName)
+{
+	for (std::vector<Logger*>::iterator i = sLoggers.begin();
+		i != sLoggers.end(); i++)
+	{
+		(*i)->SetProgramName(rProgramName);
+	}
+}
+
+Logger::Logger() 
+: mCurrentLevel(Log::EVERYTHING) 
+{
+	Logging::Add(this);
+}
+
+Logger::~Logger() 
+{
+	Logging::Remove(this);
+}
+
+bool Console::Log(Log::Level level, const std::string& rFile, 
+	int line, std::string& rMessage)
+{
+	if (level > GetLevel())
+	{
+		return true;
+	}
+	
+	FILE* target = stdout;
+	
+	if (level <= Log::WARNING)
+	{
+		target = stderr;
+	}
+	
+	fprintf(target, "%s\n", rMessage.c_str());
+	
+	return true;
+}
+
+bool Syslog::Log(Log::Level level, const std::string& rFile, 
+	int line, std::string& rMessage)
+{
+	if (level > GetLevel())
+	{
+		return true;
+	}
+	
+	int syslogLevel = LOG_ERR;
+	
+	switch(level)
+	{
+		case Log::NOTHING:    /* fall through */
+		case Log::FATAL:      syslogLevel = LOG_CRIT;    break;
+		case Log::ERROR:      syslogLevel = LOG_ERR;     break;
+		case Log::WARNING:    syslogLevel = LOG_WARNING; break;
+		case Log::NOTICE:     syslogLevel = LOG_NOTICE;  break;
+		case Log::INFO:       syslogLevel = LOG_INFO;    break;
+		case Log::TRACE:      /* fall through */
+		case Log::EVERYTHING: syslogLevel = LOG_DEBUG;   break;
+	}
+		
+	syslog(syslogLevel, "%s", rMessage.c_str());
+	
+	return true;
+}
+
+Syslog::Syslog()
+{
+	::openlog("Box Backup", LOG_PID, LOG_LOCAL6);
+}
+
+Syslog::~Syslog()
+{
+	::closelog();
+}
+
+void Syslog::SetProgramName(const std::string& rProgramName)
+{
+	::closelog();
+	::openlog(rProgramName.c_str(), LOG_PID, LOG_LOCAL6);
+}

Copied: box/chris/general/lib/common/Logging.h (from rev 1292, box/chris/merge/lib/common/Logging.h)
===================================================================
--- box/chris/general/lib/common/Logging.h	                        (rev 0)
+++ box/chris/general/lib/common/Logging.h	2007-02-20 23:37:32 UTC (rev 1293)
@@ -0,0 +1,161 @@
+// --------------------------------------------------------------------------
+//
+// File
+//		Name:    Logging.h
+//		Purpose: Generic logging core routines declarations and macros
+//		Created: 2006/12/16
+//
+// --------------------------------------------------------------------------
+
+#ifndef LOGGING__H
+#define LOGGING__H
+
+#include <sstream>
+#include <vector>
+
+/*
+#define BOX_LOG(level, stuff) \
+{ \
+    if(Log::sMaxLoggingLevelForAnyOutput >= level) \
+        std::ostringstream line; \
+        line << stuff; \
+        Log::Write(level, __FILE__, __LINE__, line.str()); \
+    } \
+}
+*/
+
+#define BOX_LOG(level, stuff) \
+{ \
+	std::ostringstream line; \
+	line << stuff; \
+	Logging::Log(level, __FILE__, __LINE__, line.str()); \
+}
+
+#define BOX_FATAL(stuff)   BOX_LOG(Log::FATAL,   stuff)
+#define BOX_ERROR(stuff)   BOX_LOG(Log::ERROR,   stuff)
+#define BOX_WARNING(stuff) BOX_LOG(Log::WARNING, stuff)
+#define BOX_NOTICE(stuff)  BOX_LOG(Log::NOTICE,  stuff)
+#define BOX_INFO(stuff)    BOX_LOG(Log::INFO,    stuff)
+#if defined NDEBUG && ! defined COMPILE_IN_TRACES
+        #define BOX_TRACE(stuff)   
+#else
+        #define BOX_TRACE(stuff)   BOX_LOG(Log::TRACE, stuff)
+#endif
+
+namespace Log
+{
+	enum Level { NOTHING = 1, FATAL, ERROR, WARNING, NOTICE, INFO, TRACE, 
+		EVERYTHING };
+}
+
+// --------------------------------------------------------------------------
+//
+// Class
+//		Name:    Logger
+//		Purpose: Abstract base class for log targets
+//		Created: 2006/12/16
+//
+// --------------------------------------------------------------------------
+
+class Logger
+{
+	private:
+	Log::Level mCurrentLevel;
+	
+	public:
+	Logger();
+	virtual ~Logger();
+	
+	virtual bool Log(Log::Level level, const std::string& rFile, 
+		int line, std::string& rMessage) = 0;
+	
+	void Filter(Log::Level level)
+	{
+		mCurrentLevel = level;
+	}
+
+	virtual const char* GetType() = 0;
+	Log::Level GetLevel() { return mCurrentLevel; }
+	
+	virtual void SetProgramName(const std::string& rProgramName) = 0;
+};
+
+// --------------------------------------------------------------------------
+//
+// Class
+//		Name:    Console
+//		Purpose: Console logging target
+//		Created: 2006/12/16
+//
+// --------------------------------------------------------------------------
+
+class Console : public Logger
+{
+	public:
+	virtual bool Log(Log::Level level, const std::string& rFile, 
+		int line, std::string& rMessage);
+	virtual const char* GetType() { return "Console"; }
+	virtual void SetProgramName(const std::string& rProgramName) { }
+};
+
+// --------------------------------------------------------------------------
+//
+// Class
+//		Name:    Syslog
+//		Purpose: Syslog (or Windows Event Viewer) logging target
+//		Created: 2006/12/16
+//
+// --------------------------------------------------------------------------
+
+class Syslog : public Logger
+{
+	public:
+	Syslog();
+	virtual ~Syslog();
+	
+	virtual bool Log(Log::Level level, const std::string& rFile, 
+		int line, std::string& rMessage);
+	virtual const char* GetType() { return "Syslog"; }
+	virtual void SetProgramName(const std::string& rProgramName);
+};
+
+// --------------------------------------------------------------------------
+//
+// Class
+//		Name:    Logging
+//		Purpose: Static logging helper, keeps track of enabled loggers
+//			 and distributes log messages to them.
+//		Created: 2006/12/16
+//
+// --------------------------------------------------------------------------
+
+class Logging
+{
+	private:
+	static std::vector<Logger*> sLoggers;
+	static bool sLogToSyslog, sLogToConsole;
+	static std::string sContext;
+	static bool sContextSet;
+	static Console* spConsole;
+	static Syslog*  spSyslog;
+	static Log::Level sGlobalLevel;
+	static Logging    sGlobalLogging;
+	
+	public:
+	Logging ();
+	~Logging();
+	static void ToSyslog  (bool enabled);
+	static void ToConsole (bool enabled);
+	static void FilterSyslog  (Log::Level level);
+	static void FilterConsole (Log::Level level);
+	static void Add    (Logger* pNewLogger);
+	static void Remove (Logger* pOldLogger);
+	static void Log(Log::Level level, const std::string& rFile, 
+		int line, const std::string& rMessage);
+	static void SetContext(std::string context);
+	static void ClearContext();
+	static void SetGlobalLevel(Log::Level level) { sGlobalLevel = level; }
+	static void SetProgramName(const std::string& rProgramName);
+};
+
+#endif // LOGGING__H