diff --git a/src/logging.h b/src/logging.h
index acfb00fa76096447ba92fce8b07196633a31cf94..eea75fcc522654ab8d302634c432e267249be632 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -19,6 +19,9 @@
 
 namespace wolf {
 namespace internal {
+namespace do_not_enter_where_the_wolf_lives {
+
+#define __INTERNAL_WOLF_MAIN_LOGGER_NAME_ "wolf_main_console"
 
 static const auto repeated_brace = std::make_tuple("{}",
                                                    "{}{}",
@@ -44,49 +47,51 @@ static const auto repeated_brace = std::make_tuple("{}",
                                                    "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
                                                    "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
                                                    "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
-                                                   "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}"); // up to 25 args.
-
-class Logger : public Singleton<Logger>
+                                                   "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}"); // up to 25 args. Should be fine
+class Logger
 {
-  friend class Singleton<Logger>;
+public:
 
-protected:
+  Logger(const std::string& name);
 
-  Logger();
-  ~Logger();
+  Logger(std::string&& name);
 
-// It is counter intuitive to have those functions
-// public but that for the sake of the macros below
-public:
+  ~Logger();
 
-  Logger(Logger&)         = delete;
-  void operator=(Logger&) = delete;
+  // Not copyable/movable
+  Logger(Logger&)          = delete;
+  void operator=(Logger&)  = delete;
+  Logger(Logger&&)         = delete;
+  void operator=(Logger&&) = delete;
 
   template<typename... Args>
-  void info(Args&&... args);
+  void info(Args&&... args) const;
 
   template<typename... Args>
-  void warn(Args&&... args);
+  void warn(Args&&... args) const;
 
   template<typename... Args>
-  void error(Args&&... args);
+  void error(Args&&... args) const;
 
   template<typename... Args>
-  void debug(Args&&... args);
+  void debug(Args&&... args) const;
 
   template<typename... Args>
-  void trace(Args&&... args);
+  void trace(Args&&... args) const;
 
   bool set_async_queue(const std::size_t q_size);
 
+  void set_pattern(const std::string& p);
+
 protected:
 
-  const std::string log_name_ = "wolf_main_console";
+  const std::string log_name_;
 
   std::shared_ptr<spdlog::logger> console_;
 };
 
-inline Logger::Logger()
+inline Logger::Logger(const std::string& name) :
+  log_name_(name)
 {
   // Create main logger
   console_ = spdlog::stdout_color_mt(log_name_);
@@ -99,9 +104,46 @@ inline Logger::Logger()
   // Queue size must be a power of 2
   spdlog::set_async_mode(4096);
 
-  // Logging pattern is :
-  // [thread num][hour:minutes:seconds.nanoseconds][log type] #log-content
-  console_->set_pattern("[%t][%H:%M:%S.%F][%l] %v");
+  if (log_name_ == __INTERNAL_WOLF_MAIN_LOGGER_NAME_)
+    // Logging pattern is :
+    // [thread num][hour:minutes:seconds.nanoseconds][log type] #log-content
+    //set_pattern("[%t][%H:%M:%S.%F][%l] %v");
+    // [log type][MM/DD/YY - hour:minutes:seconds.nanoseconds] #log-content
+    set_pattern("[%l][%x - %H:%M:%S.%F] %v");
+  else
+    // Logging pattern is :
+    // [logger name][thread num][hour:minutes:seconds.nanoseconds][log type] #log-content
+    //set_pattern("[" + log_name_ + "]" +"[%t][%H:%M:%S.%F][%l] %v");
+    // [log type][MM/DD/YY - hour:minutes:seconds.nanoseconds][logger name] #log-content
+    set_pattern("[%l][%x - %H:%M:%S.%F][" + log_name_ + "] %v");
+}
+
+inline Logger::Logger(std::string&& name) :
+  log_name_(std::forward<std::string>(name))
+{
+  // Create main logger
+  console_ = spdlog::stdout_color_mt(log_name_);
+
+#ifdef _WOLF_TRACE
+  console_->set_level(spdlog::level::trace);
+#endif
+
+  // Enable asynchronous logging
+  // Queue size must be a power of 2
+  spdlog::set_async_mode(4096);
+
+  if (log_name_ == __INTERNAL_WOLF_MAIN_LOGGER_NAME_)
+    // Logging pattern is :
+    // [thread num][hour:minutes:seconds.nanoseconds][log type] #log-content
+    //set_pattern("[%t][%H:%M:%S.%F][%l] %v");
+    // [log type][MM/DD/YY - hour:minutes:seconds.nanoseconds] #log-content
+    set_pattern("[%l][%x - %H:%M:%S.%F] %v");
+  else
+    // Logging pattern is :
+    // [logger name][thread num][hour:minutes:seconds.nanoseconds][log type] #log-content
+    //set_pattern("[" + log_name_ + "]" +"[%t][%H:%M:%S.%F][%l] %v");
+    // [log type][MM/DD/YY - hour:minutes:seconds.nanoseconds][logger name] #log-content
+    set_pattern("[%l][%x - %H:%M:%S.%F][" + log_name_ + "] %v");
 }
 
 inline Logger::~Logger()
@@ -110,31 +152,31 @@ inline Logger::~Logger()
 }
 
 template<typename... Args>
-void Logger::info(Args&&... args)
+void Logger::info(Args&&... args) const
 {
   console_->info(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
 }
 
 template<typename... Args>
-void Logger::warn(Args&&... args)
+void Logger::warn(Args&&... args) const
 {
   console_->warn(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
 }
 
 template<typename... Args>
-void Logger::error(Args&&... args)
+void Logger::error(Args&&... args) const
 {
   console_->error(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
 }
 
 template<typename... Args>
-void Logger::debug(Args&&... args)
+void Logger::debug(Args&&... args) const
 {
   console_->debug(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
 }
 
 template<typename... Args>
-void Logger::trace(Args&&... args)
+void Logger::trace(Args&&... args) const
 {
   console_->trace(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
 }
@@ -148,38 +190,140 @@ inline bool Logger::set_async_queue(const std::size_t q_size)
   return q_size;
 }
 
+inline void Logger::set_pattern(const std::string& p)
+{
+  console_->set_pattern(p);
+}
+
+using LoggerPtr = std::unique_ptr<Logger>;
+
+/// dummy namespace to avoid colision with c++14
+/// @todo use std version once we move to cxx14
+namespace not_std {
+template <typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args&&... args)
+{
+  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+} /* namespace not_std */
+
+class LoggerManager
+{
+public:
+
+  LoggerManager()  = default;
+  ~LoggerManager() = default;
+
+  bool exists(const std::string& name) const
+  {
+    std::lock_guard<std::mutex> lock(mut_);
+    return existsImpl(name);
+  }
+
+  const Logger& getLogger(const std::string& name) /*const*/
+  {
+    std::lock_guard<std::mutex> lock(mut_);
+
+    if (!existsImpl(name)) addLogger(name);
+
+    return *(logger_map_.at(name));
+  }
+
+protected:
+
+  mutable std::mutex mut_;
+
+  std::map<const std::string, const LoggerPtr> logger_map_;
+
+  bool addLogger(const std::string& name)
+  {
+    /// @note would be easier with cpp17 map.try_emplace...
+    const bool created = existsImpl(name) ?
+                          false :
+                          logger_map_.emplace(name, not_std::make_unique<Logger>(name)).second;
+    return created;
+  }
+
+  bool existsImpl(const std::string& name) const
+  {
+    return (logger_map_.find(name) != logger_map_.end());
+    //return (spdlog::get(name) != nullptr);
+  }
+};
+
+} /* namespace do_not_enter_where_the_wolf_lives */
+
+using WolfLogger = Singleton<do_not_enter_where_the_wolf_lives::Logger>;
+using WolfLoggerManager = Singleton<do_not_enter_where_the_wolf_lives::LoggerManager>;
+
+} /* namespace internal */
+} /* namespace wolf */
+
 #define WOLF_STRINGIFY(x) #x
 #define WOLF_STR_HELPER(x) WOLF_STRINGIFY(x)
 
-#define WOLF_INFO(...) \
-  wolf::internal::Logger::get().info(__VA_ARGS__);
+/// @brief NAMED LOGGING
+
+#define WOLF_ASYNC_QUEUE_LOG_NAMED(name, ...) wolf::internal::WolfLoggerManager::get().getLogger(name).set_async_queue(x);
 
-#define WOLF_WARN(...) \
-  wolf::internal::Logger::get().warn(__VA_ARGS__);
+#define WOLF_INFO_NAMED(name, ...) wolf::internal::WolfLoggerManager::get().getLogger(name).info(__VA_ARGS__);
+#define WOLF_INFO_NAMED_COND(name, cond, ...) if (cond) WOLF_INFO_NAMED(name, __VA_ARGS__);
 
-#define WOLF_ERROR(...) \
-  wolf::internal::Logger::get().error(__VA_ARGS__);
+#define WOLF_WARN_NAMED(name, ...) wolf::internal::WolfLoggerManager::get().getLogger(name).warn(__VA_ARGS__);
+#define WOLF_WARN_NAMED_COND(name, cond, ...) if (cond) WOLF_WARN_NAMED(name, __VA_ARGS__);
+
+#define WOLF_ERROR_NAMED(name, ...) wolf::internal::WolfLoggerManager::get().getLogger(name).error(__VA_ARGS__);
+#define WOLF_ERROR_NAMED_COND(name, cond, ...) if (cond) WOLF_ERROR_NAMED(name, __VA_ARGS__);
 
 #ifdef _WOLF_DEBUG
-  #define WOLF_DEBUG(...) \
-    wolf::internal::Logger::get().debug(__VA_ARGS__);
+  #define WOLF_DEBUG_NAMED(name, ...) wolf::internal::WolfLoggerManager::get().getLogger(name).debug(__VA_ARGS__);
+  #define WOLF_DEBUG_NAMED_COND(name, cond, ...) if (cond) WOLF_DEBUG_NAMED(name, __VA_ARGS__);
 #else
-  #define WOLF_DEBUG(...)
+  #define WOLF_DEBUG_NAMED(name, ...)
+  #define WOLF_DEBUG_NAMED_COND(cond, name, ...)
 #endif
 
-#define WOLF_ASYNC_QUEUE_LOG(x) \
-  wolf::internal::Logger::get().set_async_queue(x);
+#ifdef _WOLF_TRACE
+  #define WOLF_TRACE_NAMED(name, ...) \
+    {char this_file[] = __FILE__;\
+    wolf::internal::WolfLoggerManager::get().getLogger(name).trace("[", basename(this_file), " L", __LINE__, \
+              " : ", __FUNCTION__, "] ", __VA_ARGS__);}
+  #define WOLF_TRACE_NAMED_COND(name, cond, ...) if (cond) WOLF_TRACE_NAMED_COND(name, __VA_ARGS__);
+#else
+  #define WOLF_TRACE_NAMED(...)
+  #define WOLF_TRACE_NAMED_cond(name, cond, ...)
+#endif
+
+/// @brief MAIN LOGGING
+
+#define WOLF_ASYNC_QUEUE_LOG(x) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).set_async_queue(x);
+
+#define WOLF_INFO(...) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).info(__VA_ARGS__);
+#define WOLF_INFO_COND(cond, ...) if (cond) WOLF_INFO(__VA_ARGS__);
+
+#define WOLF_WARN(...) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).warn(__VA_ARGS__);
+#define WOLF_WARN_COND(cond, ...) if (cond) WOLF_WARN(__VA_ARGS__);
+
+#define WOLF_ERROR(...) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).error(__VA_ARGS__);
+#define WOLF_ERROR_COND(cond, ...) if (cond) WOLF_ERROR(__VA_ARGS__);
+
+#ifdef _WOLF_DEBUG
+  #define WOLF_DEBUG(...) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).debug(__VA_ARGS__);
+  #define WOLF_DEBUG_COND(cond, ...) if (cond) WOLF_DEBUG(__VA_ARGS__);
+#else
+  #define WOLF_DEBUG(...)
+  #define WOLF_DEBUG_COND(cond, ...)
+#endif
 
 #ifdef _WOLF_TRACE
   #define WOLF_TRACE(...) \
     {char this_file[] = __FILE__;\
-    wolf::internal::Logger::get().trace("[", basename(this_file), " L", __LINE__, \
+    wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).trace("[", basename(this_file), " L", __LINE__, \
               " : ", __FUNCTION__, "] ", __VA_ARGS__);}
+  #define WOLF_TRACE_COND(cond, ...) if (cond) WOLF_TRACE(__VA_ARGS__);
 #else
   #define WOLF_TRACE(...)
+  #define WOLF_TRACE_COND(cond, ...)
 #endif
 
-} // namespace internal
-} // namespace wolf
-
 #endif /* WOLF_LOGGING_H_ */
diff --git a/src/processor_logging.h b/src/processor_logging.h
new file mode 100644
index 0000000000000000000000000000000000000000..167beb892bb2dfe777426d14d535daf7e28cd1ac
--- /dev/null
+++ b/src/processor_logging.h
@@ -0,0 +1,31 @@
+/**
+ * \file processor_logging.h
+ *
+ *  Created on: Oct 5, 2017
+ *  \author: Jeremie Deray
+ */
+
+#ifndef _WOLF_PROCESSOR_LOGGING_H_
+#define _WOLF_PROCESSOR_LOGGING_H_
+
+/// @brief un-comment for IDE highlights.
+//#include "logging.h"
+
+#define __INTERNAL_WOLF_ASSERT_PROCESSOR \
+  static_assert(std::is_base_of<ProcessorBase, \
+   typename std::remove_pointer<decltype(this)>::type>::value, \
+    "This macro can be used only within the body of a " \
+    "non-static " \
+    "ProcessorBase (and derived) function !");
+
+#define WOLF_PROCESSOR_INFO(...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_INFO_NAMED(getType(),  __VA_ARGS__);
+#define WOLF_PROCESSOR_WARN(...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_WARN_NAMED(getType(),  __VA_ARGS__);
+#define WOLF_PROCESSOR_ERROR(...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_ERROR_NAMED(getType(), __VA_ARGS__);
+#define WOLF_PROCESSOR_DEBUG(...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_DEBUG_NAMED(getType(), __VA_ARGS__);
+
+#define WOLF_PROCESSOR_INFO_COND(cond, ...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_INFO_NAMED_COND(getType(),  cond, __VA_ARGS__);
+#define WOLF_PROCESSOR_WARN_COND(cond, ...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_WARN_NAMED_COND(getType(),  cond, __VA_ARGS__);
+#define WOLF_PROCESSOR_ERROR_COND(cond, ...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_ERROR_NAMED_COND(getType(), cond, __VA_ARGS__);
+#define WOLF_PROCESSOR_DEBUG_COND(cond, ...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_DEBUG_NAMED_COND(getType(), cond, __VA_ARGS__);
+
+#endif /* _WOLF_PROCESSOR_LOGGING_H_ */
diff --git a/src/singleton.h b/src/singleton.h
index 56450acaf4a738890eb3c98a9aca5d7c0e5dddb5..c50a8da39306e521c11caa3d098a524184b63a75 100644
--- a/src/singleton.h
+++ b/src/singleton.h
@@ -14,49 +14,34 @@ namespace wolf {
 namespace internal {
 
 /**
- * \brief A thread-safer Singleton implementation with
+ * \brief A thread-safer (?) Singleton implementation with
  * argument forwarding.
  **/
 template <class T>
 class Singleton
 {
-  /**
-   * \brief Custom deleter to by-pass private destructor issue.
-   **/
-  struct Deleter;
-
-  using SingletonOPtr = std::unique_ptr<T, Deleter>;
+  using SingletonOPtr = std::unique_ptr<T>;
 
 public:
 
   template <typename... Args>
   static T& get(Args&&... args)
   {
-    static SingletonOPtr instance_(new T(args...));
+    static SingletonOPtr instance_(new T(std::forward<Args>(args)...));
 
     return *instance_;
   }
 
-  constexpr Singleton(const Singleton&)       = delete;
-  //constexpr Singleton(const Singleton&&)      = delete;
+  constexpr Singleton(const Singleton&)  = delete;
+  constexpr Singleton(const Singleton&&) = delete;
 
   constexpr Singleton& operator=(const Singleton&) const = delete;
-  //constexpr Singleton& operator=(const Singleton&&) = delete;
+  constexpr Singleton& operator=(const Singleton&&) = delete;
 
 protected:
 
-  Singleton() = default;
-
-  virtual ~Singleton() = default;
-};
-
-template <class T>
-struct Singleton<T>::Deleter
-{
-  void operator()( const T* const p )
-  {
-    delete p;
-  }
+  constexpr Singleton() = default;
+  virtual ~Singleton()  = default;
 };
 
 } // namespace internal