From 6af6cbf2cbd0d521f3c4300f94923138470f4540 Mon Sep 17 00:00:00 2001
From: Nick Draper <nick.draper@stfc.ac.uk>
Date: Tue, 27 Nov 2007 10:38:09 +0000
Subject: [PATCH] re #63 Added stream interfaces to the logger class

---
 Code/Mantid/Kernel/inc/MantidKernel/Logger.h | 26 ++++--
 Code/Mantid/Kernel/src/Logger.cpp            | 92 +++++++++++++++-----
 Code/Mantid/Kernel/test/ConfigServiceTest.h  | 11 ++-
 3 files changed, 101 insertions(+), 28 deletions(-)

diff --git a/Code/Mantid/Kernel/inc/MantidKernel/Logger.h b/Code/Mantid/Kernel/inc/MantidKernel/Logger.h
index 5b60af2ba76..22a4c3bcbe0 100755
--- a/Code/Mantid/Kernel/inc/MantidKernel/Logger.h
+++ b/Code/Mantid/Kernel/inc/MantidKernel/Logger.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <exception>
 #include <map>
+#include <ostream>
+#include <streambuf>
 
 //----------------------------------------------------------------------
 // Forward declaration
@@ -16,6 +18,7 @@
 namespace Poco
 {
 	class Logger;
+	class LogStream;
 }
 /// @endcond
 
@@ -29,6 +32,11 @@ namespace Kernel
     various channels. The static methods on the class are responsible for the creation
     of Logger objects on request. This class currently uses the Logging functionality
     provided through the POCO (portable components) library.
+
+	Usage example:
+	    Logger ls(someLogger);
+	    ls.error("Some informational message");
+	    ls.error() << "Some error message" << std::endl;
     
     @author Nicholas Draper, Tessella Support Services plc
     @date 12/10/2007
@@ -53,14 +61,13 @@ namespace Kernel
     File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-	class DLLExport Logger
+	class DLLExport Logger 
 	{
 	public:	
 		/// An emuration of the priority levels of a log message.
 		enum Priority
 		{
-			PRIO_FATAL = 1,		    /// A fatal error. The application will most likely terminate. This is the highest priority.
-			PRIO_CRITICAL = 2,    /// A critical error. The application might not be able to continue running successfully.
+			PRIO_FATAL = 1,		  /// A fatal error. The application will most likely terminate. This is the highest priority.
 			PRIO_ERROR = 3,       /// An error. An operation did not complete successfully, but the application as a whole is not affected.
 			PRIO_WARNING = 4,     /// A warning. An operation completed with an unexpected result.
 			PRIO_INFORMATION = 6, /// An informational message, usually denoting the successful completion of an operation.
@@ -68,12 +75,18 @@ namespace Kernel
 		};
 
 		void fatal(const std::string& msg);
-		void critical(const std::string& msg);
 		void error(const std::string& msg);
 		void warning(const std::string& msg);
 		void information(const std::string& msg);
 		void debug(const std::string& msg);
 
+		std::ostream& fatal();
+		std::ostream& critical();
+		std::ostream& error();
+		std::ostream& warning();
+		std::ostream& information();
+		std::ostream& debug();
+
 		/// Logs the given message at debug level, followed by the data in buffer.
 		void dump(const std::string& msg, const void* buffer, std::size_t length);
 			
@@ -92,14 +105,17 @@ namespace Kernel
 		/// Protected constructor called by static get method
 		Logger(const std::string& name);
 		
+		
 	private:
 		Logger();
 
 		/// Overload of = operator
 		Logger& operator= (const Logger&);
 
-		/// Internal handle to third party logging object
+		/// Internal handle to third party logging objects
 		Poco::Logger& _log;
+		///This pointer is owned by this class, initialized in the constructor and deleted in the destructor
+		Poco::LogStream* _logStream;
 		
 		/// Name of this logging object
 		std::string _name;
diff --git a/Code/Mantid/Kernel/src/Logger.cpp b/Code/Mantid/Kernel/src/Logger.cpp
index 43062232dd4..4e945e9b389 100755
--- a/Code/Mantid/Kernel/src/Logger.cpp
+++ b/Code/Mantid/Kernel/src/Logger.cpp
@@ -1,16 +1,24 @@
 #include "MantidKernel/Logger.h"
 #include <Poco/Logger.h>
+#include <Poco/LogStream.h>
 #include <Poco/Message.h>
 #include <iostream>
+#include <sstream>
 
 namespace Mantid
 {
 namespace Kernel
 {
-  /// No argument constructor
-  Logger::Logger(const std::string& name): _log(Poco::Logger::get(name))
+	/// No argument constructor
+	Logger::Logger(const std::string& name): _log(Poco::Logger::get(name))
 	{  
 		_name = name;
+		_logStream = new Poco::LogStream(_log);
+	}
+
+	Logger::~Logger()
+	{
+		delete (_logStream);
 	}
 
   /** If the Logger's log level is at least PRIO_FATAL, creates a Message with 
@@ -31,24 +39,6 @@ namespace Kernel
 		}
 	}
 		
-  /** If the Logger's log level is at least PRIO_CRITICAL, creates a Message with priority
-   *  PRIO_CRITICAL and the given message text and sends it to the attached channel.
-   * 
-   *  @param msg The message to log.
-   */
-	void Logger::critical(const std::string& msg)
-	{
-		try
-		{
-			_log.critical(msg);
-		} 
-		catch (std::exception& e)
-		{
-			//failures in logging are not allowed to throw exceptions out of the logging class
-			std::cerr << e.what();
-		}
-	}
-
   /** If the Logger's log level is at least PRIO_ERROR, creates a Message with priority
    *  PRIO_ERROR and the given message text and sends it to the attached channel.
    * 
@@ -167,6 +157,67 @@ namespace Kernel
 		return retVal;
 	}
 
+  /** This class implements an ostream interface to the Logger for fatal messages.
+	*
+	* The stream's buffer appends all characters written to it
+	* to a string. As soon as a CR or LF (std::endl) is written,
+	* the string is sent to the Logger.
+	* @returns an std::ostream reference.
+	*/
+	std::ostream& Logger::fatal()
+	{
+		return _logStream->fatal();
+	}
+
+	/** This class implements an ostream interface to the Logger for error messages.
+	*
+	* The stream's buffer appends all characters written to it
+	* to a string. As soon as a CR or LF (std::endl) is written,
+	* the string is sent to the Logger.
+	* @returns an std::ostream reference.
+	*/
+	std::ostream& Logger::error()
+	{
+		return _logStream->error();
+	}
+
+	/** This class implements an ostream interface to the Logger for warning messages.
+	*
+	* The stream's buffer appends all characters written to it
+	* to a string. As soon as a CR or LF (std::endl) is written,
+	* the string is sent to the Logger.
+	* @returns an std::ostream reference.
+	*/
+	std::ostream& Logger::warning()
+	{
+		return _logStream->warning();
+	}
+
+	/** This class implements an ostream interface to the Logger for information messages.
+	*
+	* The stream's buffer appends all characters written to it
+	* to a string. As soon as a CR or LF (std::endl) is written,
+	* the string is sent to the Logger.
+	* @returns an std::ostream reference.
+	*/
+	std::ostream& Logger::information()
+	{
+		return _logStream->information();
+	}
+
+	/** This class implements an ostream interface to the Logger for debug messages.
+	*
+	* The stream's buffer appends all characters written to it
+	* to a string. As soon as a CR or LF (std::endl) is written,
+	* the string is sent to the Logger.
+	* @returns an std::ostream reference.
+	*/
+	std::ostream& Logger::debug()
+	{
+		return _logStream->debug();
+	}
+
+
   /// Shuts down the logging framework and releases all Loggers.  
 	void Logger::shutdown()
 	{
@@ -192,6 +243,7 @@ namespace Kernel
 		return *pLogger;
 	}
 
+
 } // namespace Kernel
 } // Namespace Mantid
 
diff --git a/Code/Mantid/Kernel/test/ConfigServiceTest.h b/Code/Mantid/Kernel/test/ConfigServiceTest.h
index 95b1c2bc27e..df56b2922a4 100644
--- a/Code/Mantid/Kernel/test/ConfigServiceTest.h
+++ b/Code/Mantid/Kernel/test/ConfigServiceTest.h
@@ -6,7 +6,6 @@
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Logger.h"
 #include <string>
-#include <iostream>
 
 using namespace Mantid::Kernel;
 
@@ -29,16 +28,22 @@ public:
 	  TS_ASSERT_THROWS_NOTHING(log1.information("an information string"));
 	  TS_ASSERT_THROWS_NOTHING(log1.warning("a warning string"));
 	  TS_ASSERT_THROWS_NOTHING(log1.error("an error string"));
-	  TS_ASSERT_THROWS_NOTHING(log1.critical("a critical string"));
 	  TS_ASSERT_THROWS_NOTHING(log1.fatal("a fatal string"));
 
+	  TS_ASSERT_THROWS_NOTHING(
+		log1.fatal()<<"A fatal message from the stream operators " << 4.5 << std::endl;
+		log1.error()<<"A error message from the stream operators " << -0.2 << std::endl;
+		log1.warning()<<"A warning message from the stream operators " << 999.99 << std::endl;
+		log1.information()<<"A information message from the stream operators " << -999.99 << std::endl;
+		log1.debug()<<"A debug message from the stream operators " << 5684568 << std::endl;
+	  );
+
 	  //checking the level - this should be set to debug in the config file
 	  //therefore this should only return false for debug
 	  TS_ASSERT(log1.is(Logger::PRIO_DEBUG) == false); //debug
 	  TS_ASSERT(log1.is(Logger::PRIO_INFORMATION)); //information
 	  TS_ASSERT(log1.is(Logger::PRIO_WARNING)); //warning
 	  TS_ASSERT(log1.is(Logger::PRIO_ERROR)); //error
-	  TS_ASSERT(log1.is(Logger::PRIO_CRITICAL)); //critical
 	  TS_ASSERT(log1.is(Logger::PRIO_FATAL)); //fatal
 
   }
-- 
GitLab