From 70a70e39b98ffd0a065229ec4a14606939c01eae Mon Sep 17 00:00:00 2001
From: ralfulrich <ralf.ulrich@kit.edu>
Date: Fri, 10 Aug 2018 16:04:25 +0200
Subject: [PATCH] refactoredd logging into sub-files

---
 Documentation/Examples/logger_example.cc |  19 +--
 Framework/Logging/BufferedSink.h         |  65 +++++++++
 Framework/Logging/CMakeLists.txt         |   2 +-
 Framework/Logging/Logger.h               | 174 +++++++----------------
 Framework/Logging/MessageOff.h           |  19 +++
 Framework/Logging/MessageOn.h            |  54 +++++++
 Framework/Logging/NoSink.h               |  16 +++
 Framework/Logging/Sink.h                 |  37 +++++
 8 files changed, 251 insertions(+), 135 deletions(-)
 create mode 100644 Framework/Logging/BufferedSink.h
 create mode 100644 Framework/Logging/MessageOff.h
 create mode 100644 Framework/Logging/MessageOn.h
 create mode 100644 Framework/Logging/NoSink.h
 create mode 100644 Framework/Logging/Sink.h

diff --git a/Documentation/Examples/logger_example.cc b/Documentation/Examples/logger_example.cc
index 5455f7d5..d8212e66 100644
--- a/Documentation/Examples/logger_example.cc
+++ b/Documentation/Examples/logger_example.cc
@@ -2,6 +2,7 @@
 
 #include <string>
 #include <iostream>
+#include <fstream>
 
 #include <boost/format.hpp>
 
@@ -13,10 +14,10 @@ main()
   {
     cout << "writing to \"another.log\"" << endl;
     ofstream logfile("another.log");
-    typedef Sink<ofstream, StdBuffer> SinkFile;
-    SinkFile sink(logfile, StdBuffer(10000));
-    logger<SinkFile, messageconst> info("\033[32m", "info", sink);
-    logger<SinkFile, messageconst> err("\033[31m", "error", sink);
+    logger::sink::SinkStream unbuffered_sink(logfile);
+    logger::sink::BufferedSinkStream sink(logfile, logger::sink::StdBuffer(10000));
+    logger::Logger<logger::MessageOn, logger::sink::BufferedSinkStream> info("\033[32m", "info", sink);
+    logger::Logger<logger::MessageOn, logger::sink::BufferedSinkStream> err("\033[31m", "error", sink);
     //logger<ostream,messageconst,StdBuffer> info(std::cout, StdBuffer(10000));
     
     /*
@@ -26,14 +27,14 @@ main()
     */
     
     for (int i=0; i<100000; ++i) {
-    LOG(info, "irgendwas"," ", string("and more")," ", boost::format("error: %i message: %s. done."), i, "stupido");
-    LOG(err, "Fehler");
+      LOG(info, "irgendwas"," ", string("and more")," ", boost::format("error: %i message: %s. done."), i, "stupido");
+      LOG(err, "Fehler");
     }
   }
-
+  
   {
-    NoSink off;
-    logger<NoSink, MessageOff> info("", "", off);
+    logger::sink::NoSink off;
+    logger::Logger<logger::MessageOff> info("", "", off);
     
     for (int i=0; i<100000; ++i) {
       LOG(info, "irgendwas", string("and more"), boost::format("error: %i message: %s. done."), i, "stupido", "a-number:", 8.99, "ENDE" );
diff --git a/Framework/Logging/BufferedSink.h b/Framework/Logging/BufferedSink.h
new file mode 100644
index 00000000..9934744d
--- /dev/null
+++ b/Framework/Logging/BufferedSink.h
@@ -0,0 +1,65 @@
+#ifndef _include_BufferedSink_h_
+#define _include_BufferedSink_h_
+
+namespace logger {
+
+  namespace sink {
+    
+
+    /**
+       Output buffer template. NoBuffer does nothingk.
+    */
+    /*
+    struct NoBuffer {
+      inline bool Test(const std::string&) const { return false; }
+      inline std::string GetString() const { return std::string(""); }
+      inline void Clear() {}
+      inline void Add(const std::string&) {}
+    };
+    */
+    /**
+       Output buffer template. StdBuffer records fSize characters in
+       local memeory before passing it on to further output stages. 
+    */
+    
+    struct StdBuffer {
+    StdBuffer(const int size) : fSize(size) {}
+      inline bool Test(const std::string& s) { return int(fBuffer.tellp())+s.length() < fSize; }
+      inline std::string GetString() const { return fBuffer.str(); }
+      inline void Clear() { fBuffer.str(""); }
+      inline void Add(const std::string& s) { fBuffer << s; }
+    private:
+      int fSize;
+      std::ostringstream fBuffer;
+    };
+    
+    
+    /**
+       Definition of Sink for log output. 
+    */  
+    template<typename TStream, typename TBuffer=StdBuffer> 
+    class BufferedSink {
+    public:
+    BufferedSink(TStream& out, TBuffer buffer = {} ) : fOutput(out), fBuffer(std::move(buffer)) {} 
+    void operator<<(const std::string& msg) {
+      if (!fBuffer.Test(msg)) {
+        fOutput << fBuffer.GetString();
+        fBuffer.Clear();
+      }
+      if (!fBuffer.Test(msg))
+        fOutput << msg;
+      else 
+        fBuffer.Add(msg);
+    }
+    void Close() { fOutput << fBuffer.GetString(); }
+    private:
+    TStream& fOutput;
+    TBuffer fBuffer;
+    };
+    
+    typedef BufferedSink<std::ostream, StdBuffer> BufferedSinkStream;
+
+  }// end namespace
+} // end namespace
+  
+#endif
diff --git a/Framework/Logging/CMakeLists.txt b/Framework/Logging/CMakeLists.txt
index 51da77cf..7b684deb 100644
--- a/Framework/Logging/CMakeLists.txt
+++ b/Framework/Logging/CMakeLists.txt
@@ -8,6 +8,6 @@ target_include_directories (CORSIKAlogging INTERFACE $<BUILD_INTERFACE:${PROJECT
                                                      $<INSTALL_INTERFACE:include/Framework>
                                                      )
 
-install (FILES Logger.h
+install (FILES Logger.h Sink.h MessageOn.h MessageOff.h NoSink.h Sink.h BufferedSink.h
          DESTINATION include/Logging)
 
diff --git a/Framework/Logging/Logger.h b/Framework/Logging/Logger.h
index 73275ceb..b98654d3 100644
--- a/Framework/Logging/Logger.h
+++ b/Framework/Logging/Logger.h
@@ -1,142 +1,66 @@
 #ifndef _include_logger_h_
 #define _include_logger_h_
 
+#include <iosfwd>
 #include <string>
 #include <sstream>
-#include <iostream>
 #include <typeinfo>
-#include <fstream>
 
 #include <boost/format.hpp>
- 
-using namespace std;
-using namespace boost;
-
-
-class MessageOff {
- protected:
-  template<typename First, typename ... Strings> std::string message(const First& arg, const Strings&... rest) {
-    return "";
-  }
-};
-  
-class messageconst {
- protected:
-  std::string message() { return "\n"; }
-
-  template<typename First, typename ... Strings> std::string message(const First& arg, const Strings&... rest) {
-    std::ostringstream ss;
-    ss << arg << message(rest...);
-    return ss.str();
-  }
-  
-  template<typename ... Strings> std::string message(const int& arg, const Strings&... rest) {
-    return std::to_string(arg) + message(rest...);
-  }
-
-  template<typename ... Strings> std::string message(const double& arg, const Strings&... rest) {
-    return std::to_string(arg) + message(rest...);
-  }
-  
-  template<typename ... Strings> std::string message(char const * arg, const Strings&... rest) {
-    return std::string(arg) + message(rest...);
-  }
-  
-  template<typename ... Strings> std::string message(const std::string& arg, const Strings&... rest) {
-    return arg + message(rest...);
-  }
-  
-  // ----------------------
-  // boost format
-  template<typename ... Strings> std::string message(const boost::format& fmt, const Strings&... rest) {
-    boost::format FMT(fmt);
-    return bformat(FMT, rest...);
-  }
-  
-  template<typename Arg, typename ... Strings> std::string bformat(boost::format& fmt, const Arg& arg, const Strings&... rest) {
-    fmt % arg;
-    return bformat(fmt, rest...);
-  }
-
-  std::string bformat(boost::format& fmt) { return fmt.str() + "\n"; }
-};
-
-
-struct NoBuffer {
-  inline bool Test(const std::string&) const { return false; }
-  inline std::string GetString() const { return std::string(""); }
-  inline void Clear() {}
-  inline void Add(const std::string&) {}
-};
-
-struct StdBuffer {
-  StdBuffer(const int size) : fSize(size) {}
-  inline bool Test(const std::string& s) { return int(fBuffer.tellp())+s.length() < fSize; }
-  inline std::string GetString() const { return fBuffer.str(); }
-  inline void Clear() { fBuffer.str(""); }
-  inline void Add(const std::string& s) { fBuffer << s; }
-private:
-  int fSize;
-  std::ostringstream fBuffer;
-};
-
-
-template<typename TStream, typename TBuffer=StdBuffer> 
-class Sink {
- public:
-  Sink(TStream& out, TBuffer buffer = {} ) : fOutput(out), fBuffer(std::move(buffer)) {} 
-  void operator<<(const std::string& msg) {
-    if (!fBuffer.Test(msg)) {
-      fOutput << fBuffer.GetString();
-      fBuffer.Clear();
-    }
-    if (!fBuffer.Test(msg))
-      fOutput << msg;
-    else 
-      fBuffer.Add(msg);
-  }
- void Close() { fOutput << fBuffer.GetString(); }
- private:
-  TStream& fOutput;
-  TBuffer fBuffer;
-};
 
+#include <Logging/MessageOn.h>
+#include <Logging/MessageOff.h>
+#include <Logging/Sink.h>
+#include <Logging/NoSink.h>
+#include <Logging/BufferedSink.h>
 
 
-struct NoSink { inline void operator<<(const std::string&) {} inline void Close() {} };
-
+using namespace std;
+using namespace boost;
 
-template<typename TSink=NoSink,typename M=messageconst> 
-class logger : private M {
-  
-  using M::message;
+/**
+   Everything around logfile generation and text output.
+*/
 
- public:
-  // logger() : fName("") {}
-  logger(const std::string color, const std::string name, TSink& sink) : fSink(sink), fName(color+"["+name+"]\033[39m ")  {} 
-  ~logger() { fSink.Close(); }
+namespace logger {
   
-  // logger(const logger&) = delete;
-  
-  template<typename ... Strings>
-  void log(const Strings&... inputs) {
-    fSink << M::message(inputs...);
-  }
-
-  const std::string& GetName() const { return fName; }
-  
- private:
-  TSink& fSink;
-  std::string fName;
-};
-
-
-
-#define LOG(__LOGGER,...) \
-  __LOGGER.log(__LOGGER.GetName(), __FILE__,":", __LINE__, " (", __func__, ") -> ", ##__VA_ARGS__);
-
-
-
+  /**
+     Defines one stream to accept messages, and to wrote those into
+     TSink.  The helper class MessageOn will convert input at
+     compile-time into message strings. The helper class MessageOff,
+     will just do nothing and will be optimized away at compile time.
+  */
+  template<typename MSG=MessageOn, typename TSink=sink::NoSink> 
+  class Logger : private MSG {
+    
+    using MSG::Message;
+    
+  public:
+    // Logger() : fName("") {}
+    Logger(const std::string color, const std::string name, TSink& sink) : fSink(sink), fName(color+"["+name+"]\033[39m ")  {} 
+    ~Logger() { fSink.Close(); }    
+    // Logger(const Logger&) = delete;
+
+    /**
+       Function to add string-concatenation of all inputs to output
+       sink.
+     */
+    template<typename ... Strings>
+    void Log(const Strings&... inputs) {
+      fSink << MSG::Message(inputs...);
+    }
+    
+    const std::string& GetName() const { return fName; }
+    
+  private:
+    TSink& fSink;
+    std::string fName;
+  };
+
+} // end namesapce 
+
+#define LOG(__LOGGER,...)                                               \
+  __LOGGER.Log(__LOGGER.GetName(), __FILE__,":", __LINE__, " (", __func__, ") -> ", ##__VA_ARGS__);
 
 #endif
  
diff --git a/Framework/Logging/MessageOff.h b/Framework/Logging/MessageOff.h
new file mode 100644
index 00000000..ef62e257
--- /dev/null
+++ b/Framework/Logging/MessageOff.h
@@ -0,0 +1,19 @@
+#ifndef _include_MessageOff_h_
+#define _include_MessageOff_h_
+
+namespace logger {
+
+  /**
+     Helper class to ignore all arguments to MessagesOn::Message and
+     always return empty string "".
+   */
+  class MessageOff {
+  protected:
+    template<typename First, typename ... Strings> std::string Message(const First& arg, const Strings&... rest) {
+      return "";
+    }
+  };
+
+} // end namespace
+
+#endif
diff --git a/Framework/Logging/MessageOn.h b/Framework/Logging/MessageOn.h
new file mode 100644
index 00000000..43b84744
--- /dev/null
+++ b/Framework/Logging/MessageOn.h
@@ -0,0 +1,54 @@
+#ifndef _include_MessageOn_h_
+#define _include_MessageOn_h_
+
+
+namespace logger {
+
+  /**
+     Helper class to convert all input arguments of MessageOn::Message
+     into string-concatenated version and return this as string.
+  */
+  class MessageOn {
+  protected:
+    std::string Message() { return "\n"; }
+    
+    template<typename First, typename ... Strings> std::string Message(const First& arg, const Strings&... rest) {
+      std::ostringstream ss;
+      ss << arg << Message(rest...);
+      return ss.str();
+    }
+    
+    template<typename ... Strings> std::string Message(const int& arg, const Strings&... rest) {
+      return std::to_string(arg) + Message(rest...);
+    }
+    
+    template<typename ... Strings> std::string Message(const double& arg, const Strings&... rest) {
+      return std::to_string(arg) + Message(rest...);
+    }
+    
+    template<typename ... Strings> std::string Message(char const * arg, const Strings&... rest) {
+      return std::string(arg) + Message(rest...);
+    }
+    
+    template<typename ... Strings> std::string Message(const std::string& arg, const Strings&... rest) {
+      return arg + Message(rest...);
+    }
+    
+    // ----------------------
+    // boost format
+    template<typename ... Strings> std::string Message(const boost::format& fmt, const Strings&... rest) {
+      boost::format FMT(fmt);
+      return bformat(FMT, rest...);
+    }
+    
+    template<typename Arg, typename ... Strings> std::string bformat(boost::format& fmt, const Arg& arg, const Strings&... rest) {
+      fmt % arg;
+      return bformat(fmt, rest...);
+    }
+    
+    std::string bformat(boost::format& fmt) { return fmt.str() + "\n"; }
+  };
+
+}// end namesapce
+
+#endif
diff --git a/Framework/Logging/NoSink.h b/Framework/Logging/NoSink.h
new file mode 100644
index 00000000..13e37f3b
--- /dev/null
+++ b/Framework/Logging/NoSink.h
@@ -0,0 +1,16 @@
+#ifndef _include_NoSink_h_
+#define _include_NoSink_h_
+
+namespace logger {
+
+  namespace sink {
+
+    struct NoSink {
+      inline void operator<<(const std::string&) {}
+      inline void Close() {}
+    };
+
+  }// end namespace
+} // end namespace
+  
+#endif
diff --git a/Framework/Logging/Sink.h b/Framework/Logging/Sink.h
new file mode 100644
index 00000000..6ee61517
--- /dev/null
+++ b/Framework/Logging/Sink.h
@@ -0,0 +1,37 @@
+#ifndef _include_Sink_h_
+#define _include_Sink_h_
+
+namespace logger {
+
+  /**
+     a sink for the logger must implement the two functions
+     operator<<(const std::string&) 
+     and
+     Close()
+     
+     See example: NoSink
+   */
+  
+  namespace sink {
+    
+    /**
+       Definition of Sink for log output. 
+    */  
+    template<typename TStream> 
+    class Sink {
+    public:
+    Sink(TStream& out) : fOutput(out) {}
+    void operator<<(const std::string& msg) {
+      fOutput << msg;
+    }
+    void Close() {}
+    private:
+    TStream& fOutput;
+    };
+    
+    typedef Sink<std::ostream> SinkStream;
+
+  }// end namespace
+} // end namespace
+  
+#endif
-- 
GitLab