]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
clang-format pass
authorCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Tue, 8 Jun 2021 13:33:18 +0000 (15:33 +0200)
committerCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Tue, 8 Jun 2021 13:52:14 +0000 (15:52 +0200)
pdns/recursordist/logging.cc
pdns/recursordist/logging.hh
pdns/recursordist/logr.hh

index 60c363357ef582e4ddaf6af3c6da65ca9cb2c398..840f786e93b23998c997b4c505ec282d03f4d6ed 100644 (file)
 namespace Logging
 {
 
-  std::shared_ptr<const Logger> Logger::getptr() const
-  {
-    return shared_from_this();
-  }
-
-  bool Logger::enabled(Logr::Priority p) const
-  {
-    return _level <= _verbosity || p != Logr::Absent;
-  }
-
-  void Logger::info(const std::string& msg) const
-  {
-    logMessage(msg, Logr::Absent, boost::none);
-  }
-
-  void Logger::info(Logr::Priority p, const std::string& msg) const
-  {
-    logMessage(msg, p, boost::none);
-  }
+std::shared_ptr<const Logger> Logger::getptr() const
+{
+  return shared_from_this();
+}
 
-  void Logger::logMessage(const std::string& msg, boost::optional<const std::string> err) const
-  {
-    return logMessage(msg, Logr::Absent, err);
-  }
+bool Logger::enabled(Logr::Priority p) const
+{
+  return _level <= _verbosity || p != Logr::Absent;
+}
 
-  void Logger::logMessage(const std::string& msg, Logr::Priority p, boost::optional<const std::string> err) const
-  {
-    if (!enabled(p)) {
-      return ;
-    }
-    Entry entry;
-    entry.level = _level;
-    entry.d_priority = p;
-    Utility::gettimeofday(&entry.d_timestamp);
-    entry.name = _name;
-    entry.message = msg;
-    entry.error = err;
-    auto parent = _parent;
-    entry.values.insert(_values.begin(), _values.end());
-    while (parent) {
-      entry.values.insert(parent->_values.begin(), parent->_values.end());
-      parent = parent->_parent;
-    }
-    _callback(entry);
-  }
+void Logger::info(const std::string& msg) const
+{
+  logMessage(msg, Logr::Absent, boost::none);
+}
 
-  void Logger::error(Logr::Priority p, int err, const std::string& msg) const
-  {
-    logMessage(msg, p, std::string(std::strerror(err)));
-  }
+void Logger::info(Logr::Priority p, const std::string& msg) const
+{
+  logMessage(msg, p, boost::none);
+}
 
-  void Logger::error(Logr::Priority p, const std::string& err, const std::string& msg) const
-  {
-    logMessage(msg, p, err);
-  }
+void Logger::logMessage(const std::string& msg, boost::optional<const std::string> err) const
+{
+  return logMessage(msg, Logr::Absent, err);
+}
 
-  void Logger::error(int err, const std::string& msg) const
-  {
-    logMessage(msg, Logr::Absent, std::string(std::strerror(err)));
-  }
+void Logger::logMessage(const std::string& msg, Logr::Priority p, boost::optional<const std::string> err) const
+{
+  if (!enabled(p)) {
+    return;
+  }
+  Entry entry;
+  entry.level = _level;
+  entry.d_priority = p;
+  Utility::gettimeofday(&entry.d_timestamp);
+  entry.name = _name;
+  entry.message = msg;
+  entry.error = err;
+  auto parent = _parent;
+  entry.values.insert(_values.begin(), _values.end());
+  while (parent) {
+    entry.values.insert(parent->_values.begin(), parent->_values.end());
+    parent = parent->_parent;
+  }
+  _callback(entry);
+}
+
+void Logger::error(Logr::Priority p, int err, const std::string& msg) const
+{
+  logMessage(msg, p, std::string(std::strerror(err)));
+}
 
-  void Logger::error(const std::string& err, const std::string& msg) const
-  {
-    logMessage(msg, Logr::Absent, err);
-  }
+void Logger::error(Logr::Priority p, const std::string& err, const std::string& msg) const
+{
+  logMessage(msg, p, err);
+}
 
-  std::shared_ptr<Logr::Logger> Logger::v(size_t level) const
-  {
-    auto res = std::make_shared<Logger>(getptr(), boost::none, getVerbosity(), level + _level, _callback);
-    return res;
-  }
+void Logger::error(int err, const std::string& msg) const
+{
+  logMessage(msg, Logr::Absent, std::string(std::strerror(err)));
+}
 
-  std::shared_ptr<Logr::Logger> Logger::withValues(const std::map<std::string, std::string>& values) const
-  {
-    auto res = std::make_shared<Logger>(getptr(), _name, getVerbosity(), _level, _callback);
-    res->_values = values;
-    return res;
-  }
+void Logger::error(const std::string& err, const std::string& msg) const
+{
+  logMessage(msg, Logr::Absent, err);
+}
 
-  template struct Loggable<DNSName>;
-  template struct Loggable<ComboAddress>;
-  template struct Loggable<std::string>;
-  template struct Loggable<size_t>;
+std::shared_ptr<Logr::Logger> Logger::v(size_t level) const
+{
+  auto res = std::make_shared<Logger>(getptr(), boost::none, getVerbosity(), level + _level, _callback);
+  return res;
+}
 
-  template <>
-  std::string Loggable<DNSName>::to_string() const {
-    return _t.toLogString();
-  }
-  template <>
-  std::string Loggable<ComboAddress>::to_string() const {
-    return _t.toLogString();
-  }
-  template <>
-  std::string Loggable<std::string>::to_string() const {
-    return _t;
-  }
+std::shared_ptr<Logr::Logger> Logger::withValues(const std::map<std::string, std::string>& values) const
+{
+  auto res = std::make_shared<Logger>(getptr(), _name, getVerbosity(), _level, _callback);
+  res->_values = values;
+  return res;
+}
+
+template struct Loggable<DNSName>;
+template struct Loggable<ComboAddress>;
+template struct Loggable<std::string>;
+template struct Loggable<size_t>;
+
+template <>
+std::string Loggable<DNSName>::to_string() const
+{
+  return _t.toLogString();
+}
+template <>
+std::string Loggable<ComboAddress>::to_string() const
+{
+  return _t.toLogString();
+}
+template <>
+std::string Loggable<std::string>::to_string() const
+{
+  return _t;
+}
 
-  std::shared_ptr<Logr::Logger> Logger::withName(const std::string& name) const
-  {
-    std::shared_ptr<Logger> res;
-    if (_name) {
-      res = std::make_shared<Logger>(getptr(), _name.get() + "." + name, getVerbosity(), _level, _callback);
-    } else {
-      res = std::make_shared<Logger>(getptr(), name, getVerbosity(), _level, _callback);
-    }
-    res->setVerbosity(getVerbosity());
-    return res;
-  }
-  std::shared_ptr<Logger> Logger::create(EntryLogger callback)
-  {
-    return std::make_shared<Logger>(callback);
+std::shared_ptr<Logr::Logger> Logger::withName(const std::string& name) const
+{
+  std::shared_ptr<Logger> res;
+  if (_name) {
+    res = std::make_shared<Logger>(getptr(), _name.get() + "." + name, getVerbosity(), _level, _callback);
   }
-  std::shared_ptr<Logger> Logger::create(EntryLogger callback, const std::string& name)
-  {
-    return std::make_shared<Logger>(callback, name);
+  else {
+    res = std::make_shared<Logger>(getptr(), name, getVerbosity(), _level, _callback);
   }
+  res->setVerbosity(getVerbosity());
+  return res;
+}
+std::shared_ptr<Logger> Logger::create(EntryLogger callback)
+{
+  return std::make_shared<Logger>(callback);
+}
+std::shared_ptr<Logger> Logger::create(EntryLogger callback, const std::string& name)
+{
+  return std::make_shared<Logger>(callback, name);
+}
 
-  size_t Logger::getVerbosity() const
-  {
-    return _verbosity;
-  }
+size_t Logger::getVerbosity() const
+{
+  return _verbosity;
+}
 
-  void Logger::setVerbosity(size_t verbosity)
-  {
-    _verbosity = verbosity;
-  }
+void Logger::setVerbosity(size_t verbosity)
+{
+  _verbosity = verbosity;
+}
 
-  Logger::Logger(EntryLogger callback) : _callback(callback)
-  {
-  }
-  Logger::Logger(EntryLogger callback, boost::optional<std::string> name) : _callback(callback), _name(name)
-  {
-  }
-  Logger::Logger(std::shared_ptr<const Logger> parent, boost::optional<std::string> name, size_t verbosity, size_t lvl,  EntryLogger callback) : _parent(parent), _callback(callback), _name(name), _level(lvl), _verbosity(verbosity)
-  {
-  }
+Logger::Logger(EntryLogger callback) :
+  _callback(callback)
+{
+}
+Logger::Logger(EntryLogger callback, boost::optional<std::string> name) :
+  _callback(callback), _name(name)
+{
+}
+Logger::Logger(std::shared_ptr<const Logger> parent, boost::optional<std::string> name, size_t verbosity, size_t lvl, EntryLogger callback) :
+  _parent(parent), _callback(callback), _name(name), _level(lvl), _verbosity(verbosity)
+{
+}
 
-  Logger::~Logger()
-  {
-  }
+Logger::~Logger()
+{
+}
 };
 
 std::shared_ptr<Logging::Logger> g_slog{nullptr};
index 25127fb8974a94d713f0a773376f32143632d414..fe5ad1f4fa9f102d05a42fd88f3fbf6c7fd87a86 100644 (file)
 #include "dnsname.hh"
 #include "iputils.hh"
 
-namespace Logging {
-
-  struct Entry
-  {
-    boost::optional<std::string> name;   // name parts joined with '.'
-    std::string message;                 // message as send to log call
-    boost::optional<std::string> error;  // error if .Error() was called
-    struct timeval d_timestamp;          // time of entry generation
-    std::map<std::string, std::string> values; // key-value pairs
-    size_t level;               // level at which this was logged
-    Logr::Priority d_priority;  // (syslog) priority)
-  };
-
-  template <typename T>
-  struct Loggable : public Logr::Loggable
+namespace Logging
+{
+
+struct Entry
+{
+  boost::optional<std::string> name; // name parts joined with '.'
+  std::string message; // message as send to log call
+  boost::optional<std::string> error; // error if .Error() was called
+  struct timeval d_timestamp; // time of entry generation
+  std::map<std::string, std::string> values; // key-value pairs
+  size_t level; // level at which this was logged
+  Logr::Priority d_priority; // (syslog) priority)
+};
+
+template <typename T>
+struct Loggable : public Logr::Loggable
+{
+  const T& _t;
+  Loggable(const T& v) :
+    _t(v)
   {
-    const T& _t;
-    Loggable(const T& v): _t(v) {
-    }
-    std::string to_string() const {
-      std::ostringstream oss;
-      oss << _t;
-      return oss.str();
-    }
-  };
-  template <>
-  std::string Loggable<DNSName>::to_string() const;
-  template <>
-  std::string Loggable<ComboAddress>::to_string() const;
-  template <>
-  std::string Loggable<std::string>::to_string() const;
-
-  // Loggable<std::string>::Loggable(const std::string& v): _t(v) {}
-
-  typedef void(*EntryLogger)(const Entry&);
-
-  class Logger: public Logr::Logger, public std::enable_shared_from_this<const Logger>
+  }
+  std::string to_string() const
   {
-  public:
-    bool enabled(Logr::Priority) const override;
-
-    void info(const std::string& msg) const override;
-    void info(Logr::Priority, const std::string& msg) const override;
-    void error(int err, const std::string& msg) const override;
-    void error(const std::string& err, const std::string& msg) const override;
-    void error(Logr::Priority, int err, const std::string& msg) const override;
-    void error(Logr::Priority, const std::string& err, const std::string& msg) const override;
-
-    std::shared_ptr<Logr::Logger> v(size_t level) const override;
-    std::shared_ptr<Logr::Logger> withValues(const std::map<std::string, std::string>& values) const override;
-    virtual std::shared_ptr<Logr::Logger> withName(const std::string& name) const override;
-
-    static std::shared_ptr<Logger> create(EntryLogger callback);
-    static std::shared_ptr<Logger> create(EntryLogger callback, const std::string& name);
-
-    Logger(EntryLogger callback);
-    Logger(EntryLogger callback, boost::optional<std::string> name);
-    Logger(std::shared_ptr<const Logger> parent, boost::optional<std::string> name, size_t verbosity, size_t lvl,  EntryLogger callback);
-    virtual ~Logger();
-
-    size_t getVerbosity() const;
-    void setVerbosity(size_t verbosity);
-  private:
-    void logMessage(const std::string& msg, boost::optional<const std::string> err) const;
-    void logMessage(const std::string& msg, Logr::Priority p, boost::optional<const std::string> err) const;
-    std::shared_ptr<const Logger> getptr() const;
-
-    std::shared_ptr<const Logger> _parent{nullptr};
-    EntryLogger _callback;
-    boost::optional<std::string> _name;
-    std::map<std::string, std::string> _values;
-    // current Logger's level. the higher the more verbose.
-    size_t _level{0};
-    // verbosity settings. messages with level higher's than verbosity won't appear
-    size_t _verbosity{0};
-  };
+    std::ostringstream oss;
+    oss << _t;
+    return oss.str();
+  }
+};
+template <>
+std::string Loggable<DNSName>::to_string() const;
+template <>
+std::string Loggable<ComboAddress>::to_string() const;
+template <>
+std::string Loggable<std::string>::to_string() const;
+
+// Loggable<std::string>::Loggable(const std::string& v): _t(v) {}
+
+typedef void (*EntryLogger)(const Entry&);
+
+class Logger : public Logr::Logger, public std::enable_shared_from_this<const Logger>
+{
+public:
+  bool enabled(Logr::Priority) const override;
+
+  void info(const std::string& msg) const override;
+  void info(Logr::Priority, const std::string& msg) const override;
+  void error(int err, const std::string& msg) const override;
+  void error(const std::string& err, const std::string& msg) const override;
+  void error(Logr::Priority, int err, const std::string& msg) const override;
+  void error(Logr::Priority, const std::string& err, const std::string& msg) const override;
+
+  std::shared_ptr<Logr::Logger> v(size_t level) const override;
+  std::shared_ptr<Logr::Logger> withValues(const std::map<std::string, std::string>& values) const override;
+  virtual std::shared_ptr<Logr::Logger> withName(const std::string& name) const override;
+
+  static std::shared_ptr<Logger> create(EntryLogger callback);
+  static std::shared_ptr<Logger> create(EntryLogger callback, const std::string& name);
+
+  Logger(EntryLogger callback);
+  Logger(EntryLogger callback, boost::optional<std::string> name);
+  Logger(std::shared_ptr<const Logger> parent, boost::optional<std::string> name, size_t verbosity, size_t lvl, EntryLogger callback);
+  virtual ~Logger();
+
+  size_t getVerbosity() const;
+  void setVerbosity(size_t verbosity);
+
+private:
+  void logMessage(const std::string& msg, boost::optional<const std::string> err) const;
+  void logMessage(const std::string& msg, Logr::Priority p, boost::optional<const std::string> err) const;
+  std::shared_ptr<const Logger> getptr() const;
+
+  std::shared_ptr<const Logger> _parent{nullptr};
+  EntryLogger _callback;
+  boost::optional<std::string> _name;
+  std::map<std::string, std::string> _values;
+  // current Logger's level. the higher the more verbose.
+  size_t _level{0};
+  // verbosity settings. messages with level higher's than verbosity won't appear
+  size_t _verbosity{0};
+};
 }
 
 extern std::shared_ptr<Logging::Logger> g_slog;
index 1583dc9c7407d839b2dd1458ac12d82b15e853bb..ff2da228c7a6bfbbb069743d02d94670a8d99b3d 100644 (file)
 
 // Minimal logging API based on https://github.com/go-logr/logr
 
-namespace Logr {
-  struct Loggable {
-    virtual std::string to_string() const = 0;
-  };
-
-  // In addition to level which specifies the amount of detail and is
-  // structered so that a derived logger always has a higher level
-  // than its parent we also have a priority/urgency field that maps
-  // to the same field of the old logger which in turns has a direct
-  // mapping to syslog priority. This is done to make it easier to
-  // move step by step to structured logging. We consider both level
-  // and priorty to select which messages are logged, amnd a backend
-  // can further use priority to pass to syslog.
-
-  enum Priority: uint8_t {
-    Absent = 0, Alert = 1, Critical = 2, Error = 3, Warning = 4, Notice = 5, Info = 6, Debug = 7
-  };
-
-  class Logger {
-  public:
-    // Enabled tests whether this Logger is enabled.  For example, commandline
-    // flags might be used to set the logging verbosity and disable some info
-    // logs.
-    virtual bool enabled(Priority) const = 0;
-
-    // Info logs a non-error message with the given key/value pairs as context.
-    //
-    // The msg argument should be used to add some constant description to
-    // the log line.  The key/value pairs can then be used to add additional
-    // variable information.  The key/value pairs should alternate string
-    // keys and arbitrary values.
-    virtual void info(const std::string& msg) const = 0;
-    virtual void info(Logr::Priority, const std::string& msg) const = 0;
-
-    template<typename... Args>
-    void info(const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      auto logger = this->withValues(key, value, args...);
-      logger->info(msg);
-    }
-
-    template<typename... Args>
-    void info(Priority p, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      auto logger = this->withValues(key, value, args...);
-      logger->info(p, msg);
-    }
-
-    // Error logs an error, with the given message and key/value pairs as context.
-    // It functions similarly to calling Info with the "error" named value, but may
-    // have unique behavior, and should be preferred for logging errors (see the
-    // package documentations for more information).
-    //
-    // The msg field should be used to add context to any underlying error,
-    // while the err field should be used to attach the actual error that
-    // triggered this log line, if present.
-    virtual void error(const std::string& err, const std::string& msg) const = 0;
-    virtual void error(int err, const std::string& msg) const = 0;
-    virtual void error(Logr::Priority, const std::string& err, const std::string& msg) const = 0;
-    virtual void error(Logr::Priority, int err, const std::string& msg) const = 0;
-
-    template<typename... Args>
-    void error(const std::string& err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      auto logger = this->withValues(key, value, args...);
-      logger->error(Logr::Absent, err, msg);
-    }
-
-    template<typename... Args>
-    void error(int err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      auto logger = this->withValues(key, value, args...);
-      logger->error(Logr::Absent, err, msg);
-    }
-
-    template<typename... Args>
-    void error(Priority p, const std::string& err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      auto logger = this->withValues(key, value, args...);
-      logger->error(p, err, msg);
-    }
-
-    template<typename... Args>
-    void error(Priority p, int err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      auto logger = this->withValues(key, value, args...);
-      logger->error(p, err, msg);
-    }
-
-    // V returns an Logger value for a specific verbosity level, relative to
-    // this Logger.  In other words, V values are additive.  V higher verbosity
-    // level means a log message is less important.  It's illegal to pass a log
-    // level less than zero.
-    virtual std::shared_ptr<Logger> v(size_t level) const = 0;
-
-    template<typename... Args>
-    std::shared_ptr<Logger> withValues(const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      std::map<std::string, std::string> map = {};
-      this->mapArguments(map, key, value, args...);
-      return this->withValues(map);
-    }
-
-    // WithValues adds some key-value pairs of context to a logger.
-    // See Info for documentation on how key/value pairs work.
-    virtual std::shared_ptr<Logger> withValues(const std::map<std::string, std::string>& values) const = 0;
-
-
-    // WithName adds a new element to the logger's name.
-    // Successive calls with WithName continue to append
-    // suffixes to the logger's name.  It's strongly recommended
-    // that name segments contain only letters, digits, and hyphens
-    // (see the package documentation for more information).
-    virtual std::shared_ptr<Logger> withName(const std::string& name) const = 0;
-
-  private:
-
-    template<typename... Args>
-    void mapArguments(std::map<std::string, std::string>& map, const std::string& key, const Loggable& value, const Args&... args) const
-    {
-      map.emplace(key, value.to_string());
-      mapArguments(map, args...);
-    }
-    void mapArguments(std::map<std::string, std::string>& map) const {
-      return ;
-    }
-  };
+namespace Logr
+{
+struct Loggable
+{
+  virtual std::string to_string() const = 0;
+};
+
+// In addition to level which specifies the amount of detail and is
+// structered so that a derived logger always has a higher level
+// than its parent we also have a priority/urgency field that maps
+// to the same field of the old logger which in turns has a direct
+// mapping to syslog priority. This is done to make it easier to
+// move step by step to structured logging. We consider both level
+// and priorty to select which messages are logged, amnd a backend
+// can further use priority to pass to syslog.
+
+enum Priority : uint8_t
+{
+  Absent = 0,
+  Alert = 1,
+  Critical = 2,
+  Error = 3,
+  Warning = 4,
+  Notice = 5,
+  Info = 6,
+  Debug = 7
+};
+
+class Logger
+{
+public:
+  // Enabled tests whether this Logger is enabled.  For example, commandline
+  // flags might be used to set the logging verbosity and disable some info
+  // logs.
+  virtual bool enabled(Priority) const = 0;
+
+  // Info logs a non-error message with the given key/value pairs as context.
+  //
+  // The msg argument should be used to add some constant description to
+  // the log line.  The key/value pairs can then be used to add additional
+  // variable information.  The key/value pairs should alternate string
+  // keys and arbitrary values.
+  virtual void info(const std::string& msg) const = 0;
+  virtual void info(Logr::Priority, const std::string& msg) const = 0;
+
+  template <typename... Args>
+  void info(const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    auto logger = this->withValues(key, value, args...);
+    logger->info(msg);
+  }
+
+  template <typename... Args>
+  void info(Priority p, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    auto logger = this->withValues(key, value, args...);
+    logger->info(p, msg);
+  }
+
+  // Error logs an error, with the given message and key/value pairs as context.
+  // It functions similarly to calling Info with the "error" named value, but may
+  // have unique behavior, and should be preferred for logging errors (see the
+  // package documentations for more information).
+  //
+  // The msg field should be used to add context to any underlying error,
+  // while the err field should be used to attach the actual error that
+  // triggered this log line, if present.
+  virtual void error(const std::string& err, const std::string& msg) const = 0;
+  virtual void error(int err, const std::string& msg) const = 0;
+  virtual void error(Logr::Priority, const std::string& err, const std::string& msg) const = 0;
+  virtual void error(Logr::Priority, int err, const std::string& msg) const = 0;
+
+  template <typename... Args>
+  void error(const std::string& err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    auto logger = this->withValues(key, value, args...);
+    logger->error(Logr::Absent, err, msg);
+  }
+
+  template <typename... Args>
+  void error(int err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    auto logger = this->withValues(key, value, args...);
+    logger->error(Logr::Absent, err, msg);
+  }
+
+  template <typename... Args>
+  void error(Priority p, const std::string& err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    auto logger = this->withValues(key, value, args...);
+    logger->error(p, err, msg);
+  }
+
+  template <typename... Args>
+  void error(Priority p, int err, const std::string& msg, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    auto logger = this->withValues(key, value, args...);
+    logger->error(p, err, msg);
+  }
+
+  // V returns an Logger value for a specific verbosity level, relative to
+  // this Logger.  In other words, V values are additive.  V higher verbosity
+  // level means a log message is less important.  It's illegal to pass a log
+  // level less than zero.
+  virtual std::shared_ptr<Logger> v(size_t level) const = 0;
+
+  template <typename... Args>
+  std::shared_ptr<Logger> withValues(const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    std::map<std::string, std::string> map = {};
+    this->mapArguments(map, key, value, args...);
+    return this->withValues(map);
+  }
+
+  // WithValues adds some key-value pairs of context to a logger.
+  // See Info for documentation on how key/value pairs work.
+  virtual std::shared_ptr<Logger> withValues(const std::map<std::string, std::string>& values) const = 0;
+
+  // WithName adds a new element to the logger's name.
+  // Successive calls with WithName continue to append
+  // suffixes to the logger's name.  It's strongly recommended
+  // that name segments contain only letters, digits, and hyphens
+  // (see the package documentation for more information).
+  virtual std::shared_ptr<Logger> withName(const std::string& name) const = 0;
+
+private:
+  template <typename... Args>
+  void mapArguments(std::map<std::string, std::string>& map, const std::string& key, const Loggable& value, const Args&... args) const
+  {
+    map.emplace(key, value.to_string());
+    mapArguments(map, args...);
+  }
+  void mapArguments(std::map<std::string, std::string>& map) const
+  {
+    return;
+  }
+};
 }