Add support for metadata

Added support for metadata in elog.hpp, elog mako file, and pdmgen.
This metadata will be added with the error log.

Change-Id: Iaf0fe24d71f6bdd02b51df208b2c1d66c68319d3
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/src/elog.hpp b/src/elog.hpp
index f138b0b..e4f5456 100644
--- a/src/elog.hpp
+++ b/src/elog.hpp
@@ -3,6 +3,7 @@
 #include <phosphor-logging/elog.hpp>
 #include "callback.hpp"
 #include <sdbusplus/exception.hpp>
+#include <experimental/tuple>
 
 namespace phosphor
 {
@@ -26,7 +27,7 @@
         ElogBase& operator=(ElogBase&&) = default;
         virtual ~ElogBase() = default;
         ElogBase() :
-            Callback(){}
+            Callback() {}
 
         /** @brief Callback interface implementation. */
         void operator()() override;
@@ -36,13 +37,35 @@
         virtual void log() const = 0;
 };
 
+namespace detail
+{
+
+/** @class CallElog
+ *  @brief Provide explicit call forwarding to phosphor::logging::report.
+ *
+ *  @tparam T - Error log type
+ *  @tparam Args - Metadata fields types.
+ */
+template <typename T, typename ...Args>
+struct CallElog
+{
+    static void op(Args&& ...args)
+    {
+        phosphor::logging::report<T>(std::forward<Args>(args)...);
+    }
+};
+
+} // namespace detail
 
 /** @class Elog
  *  @brief C++ type specific logic for the elog callback.
+ *         The elog callback logs the elog and elog metadata.
  *
  *  @tparam T - Error log type
+ *  @tparam Args - Metadata fields types.
+ *  @param[in] arguments - Metadata fields to be added to the error log
  */
-template <typename T>
+template <typename T, typename ...Args>
 class Elog : public ElogBase
 {
     public:
@@ -51,19 +74,34 @@
         Elog& operator=(const Elog&) = delete;
         Elog& operator=(Elog&&) = default;
         ~Elog() = default;
-        Elog() :
-            ElogBase() {}
+        Elog(Args&& ... arguments) :
+            ElogBase(), args(std::forward<Args>(arguments)...) {}
 
     private:
         /** @brief elog interface implementation. */
         void log() const override
         {
-
-            using namespace phosphor::logging;
-            report<T>();
+            std::experimental::apply(
+                detail::CallElog<T, Args...>::op,
+                std::tuple_cat(args));
         }
+        std::tuple<Args...> args;
+
 };
 
+/** @brief Argument type deduction for constructing Elog instances.
+ *
+ *  @tparam T - Error log type
+ *  @tparam Args - Metadata fields types.
+ *  @param[in] arguments - Metadata fields to be added to the error log
+ */
+template <typename T, typename ...Args>
+auto makeElog(Args&& ... arguments)
+{
+    return std::make_unique<Elog<T, Args...>>(
+               std::forward<Args>(arguments)...);
+}
+
 } // namespace monitoring
 } // namespace dbus
 } // namespace phosphor