blob: b445a0eecd3087e9c4017406bec496943a3f9e62 [file] [log] [blame]
Adriana Kobylakf855c3e2016-09-29 20:48:08 -05001#pragma once
2
3#include <tuple>
4#include <utility>
5#include "elog-gen.hpp"
6
7namespace phosphor
8{
9
10namespace logging
11{
12
13/**
14 * @brief Structure used by callers to indicate they want to use the last value
15 * put in the journal for input parameter.
16*/
17template <typename T>
18struct prev_entry
19{
20 using type = T;
21};
22
23
24
25namespace details
26{
27/**
28 * @brief Used to return the generated tuple for the error code meta data
29 *
30 * The prev_entry (above) and deduce_entry_type structures below are used
31 * to verify at compile time the required parameters have been passed to
32 * the elog interface and then to forward on the appropriate tuple to the
33 * log interface.
34 */
35template <typename T>
36struct deduce_entry_type
37{
38
39 using type = T;
40 auto get() { return value._entry; }
41
42 T value;
43};
44
45/**
46 * @brief Used to return an empty tuple for prev_entry parameters
47 *
48 * This is done so we can still call the log() interface with the variable
49 * arg parameters to elog. The log() interface will simply ignore the empty
50 * tuples which is what we want for prev_entry parameters.
51 */
52template <typename T>
53struct deduce_entry_type<prev_entry<T>>
54{
55 using type = T;
56 auto get() { return std::make_tuple(); }
57
58 prev_entry<T> value;
59};
60
61/**
62 * @brief Typedef for above structure usage
63 */
64template <typename T> using deduce_entry_type_t =
65 typename deduce_entry_type<T>::type;
66
67} // namespace details
68
Andrew Geissler6d910ad2016-10-16 20:49:14 -050069/**
70 * @brief Error log exception base class
71 *
72 * This allows people to capture all error log exceptions if desired
73 */
74class elogExceptionBase : public std::exception {};
75
76/**
77 * @brief Error log exception class
78 *
79 * This is for capturing specific error log exceptions
80 */
81template <typename T> class elogException : public elogExceptionBase
82{
83public:
84 const char* what() const noexcept override { return T::err_code; }
85};
86
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050087/** @fn commit()
88 * @brief Create an error log entry based on journal
89 * entry with a specified MSG_ID
90 * @tparam E - Error log struct
91 */
92template <typename E>
93void commit()
94{
95 // TODO placeholder function call
96 // to call the new error log server to create
97 // an error log on the BMC flash
98 // dbus_commit(E.msgid); // call server
99}
100
101/** @fn elog()
102 * @brief Create a journal log entry based on predefined
103 * error log information
104 * @tparam T - Error log type
105 * @param[in] i_args - Metadata fields to be added to the journal entry
106 */
107template <typename T, typename ...Args>
108void elog(Args... i_args)
109{
110 // Validate the caller passed in the required parameters
111 static_assert(std::is_same<typename T::metadata_types,
112 std::tuple<
113 details::deduce_entry_type_t<Args>...>>
114 ::value,
115 "You are not passing in required arguments for this error");
116
117 log<T::L>(T::err_msg,
118 details::deduce_entry_type<Args>{i_args}.get()...);
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500119
120 // Now throw an exception for this error
121 throw elogException<T>();
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500122}
123
124} // namespace logging
125
126} // namespace phosphor
127