Useful in automated unit tests, to create a logger singleton that is associated with an output stream _before_ it starts logging anything. The existing implementation will output a few lines to the console from within the logger constructor, before you can attach the singleton to an ostream.
If the logger singleton already exists, then this patch does not change it. You could modify that behaviour to instead associate the logger with the given stream. Thoughts?
To use the new functionality, do the following before the logger is used. This will sink all logger output to the string stream, instead of to the console.
...
// stream that Orocos logger is associated with
std::ostringstream str;
// Force creation of the singleton logger, and associate it with the
// above strstream instead of having the logger output to console
// The logger still outputs to the "orocos.log" file.
(void)RTT::Logger::Instance(str);
...
By the way, how do you attach files to a forum post from a web browser? Just attach it as an image???
Feedback appreciated
S
Index: Logger.hpp
===================================================================
--- Logger.hpp (revision 29209)
+++ Logger.hpp (working copy)
@@ -173,6 +173,17 @@
static Logger* Instance();
/**
+ * Get the singleton logger.
+ * \post If the singleton did not alreay exist then the new
+ * instance is associated with the given stream. Otherwise
+ * no change in the existing instance, and the given stream is
+ * ignored.
+ */
+#ifndef OROSEM_PRINTF_LOGGING
+ static Logger* Instance(std::ostream& str);
+#endif
+
+ /**
* Delete the singleton logger.
*/
static void Release();
@@ -284,6 +295,9 @@
bool mayLog() const;
Logger();
+#ifndef OROSEM_PRINTF_LOGGING
+ Logger(std::ostream& str);
+#endif
~Logger();
static Logger* _instance;
Index: Logger.cpp
===================================================================
--- Logger.cpp (revision 29209)
+++ Logger.cpp (working copy)
@@ -74,6 +74,14 @@
return _instance;
}
+ Logger* Logger::Instance(std::ostream& str) {
+ if (_instance == 0) {
+ _instance = new Logger(str);
+ }
+ // else ignore attempted use of ostream
+ return _instance;
+ }
+
void Logger::Release() {
if (_instance) {
_instance->shutdown();
@@ -118,6 +126,29 @@
#endif
}
+#ifndef OROSEM_PRINTF_LOGGING
+ D(std::ostream& str) :
+#ifndef OROSEM_PRINTF_LOGGING
+ stdoutput(&str),
+#endif
+#ifdef OROSEM_REMOTE_LOGGING
+ messagecnt(0),
+#endif
+#if defined(OROSEM_FILE_LOGGING) && !defined(OROSEM_PRINTF_LOGGING)
+ logfile("orocos.log"),
+#endif
+ inloglevel(Info),
+ outloglevel(Warning),
+ timestamp(0),
+ started(false), showtime(true), allowRT(false),
+ loggermodule("Logger"), moduleptr(loggermodule)
+ {
+#if defined(OROSEM_FILE_LOGGING) && defined(OROSEM_PRINTF_LOGGING)
+ logfile = fopen("orocos.log","w");
+#endif
+ }
+#endif
+
bool maylog() const {
if (!started || (outloglevel == RealTime && allowRT == false))
return false;
@@ -294,6 +325,14 @@
this->startup();
}
+#ifndef OROSEM_PRINTF_LOGGING
+ Logger::Logger(std::ostream& str)
+ :d ( new Logger::D(str) )
+ {
+ this->startup();
+ }
+#endif
+
Logger::~Logger()
{
delete d;