blob: 83f35e79b634f7d69d30d4350b4586c6c161533b [file] [log] [blame]
Adriana Kobylakf855c3e2016-09-29 20:48:08 -05001#pragma once
Patrick Venturef18bf832018-10-26 18:14:00 -07002#include "xyz/openbmc_project/Logging/Entry/server.hpp"
3
Saqib Khan2bb15192017-02-13 13:19:55 -06004#include <phosphor-logging/log.hpp>
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -05005#include <sdbusplus/exception.hpp>
Patrick Venturef18bf832018-10-26 18:14:00 -07006#include <tuple>
7#include <utility>
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -05008
Adriana Kobylakf855c3e2016-09-29 20:48:08 -05009namespace phosphor
10{
11
12namespace logging
13{
14
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -050015using namespace sdbusplus::xyz::openbmc_project::Logging::server;
16
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050017/**
18 * @brief Structure used by callers to indicate they want to use the last value
19 * put in the journal for input parameter.
Patrick Venturef18bf832018-10-26 18:14:00 -070020 */
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050021template <typename T>
22struct prev_entry
23{
24 using type = T;
25};
26
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050027namespace details
28{
29/**
30 * @brief Used to return the generated tuple for the error code meta data
31 *
32 * The prev_entry (above) and deduce_entry_type structures below are used
33 * to verify at compile time the required parameters have been passed to
34 * the elog interface and then to forward on the appropriate tuple to the
35 * log interface.
36 */
37template <typename T>
38struct deduce_entry_type
39{
40
41 using type = T;
Patrick Venturef18bf832018-10-26 18:14:00 -070042 auto get()
43 {
44 return value._entry;
45 }
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050046
47 T value;
48};
49
50/**
51 * @brief Used to return an empty tuple for prev_entry parameters
52 *
53 * This is done so we can still call the log() interface with the variable
54 * arg parameters to elog. The log() interface will simply ignore the empty
55 * tuples which is what we want for prev_entry parameters.
56 */
57template <typename T>
58struct deduce_entry_type<prev_entry<T>>
59{
60 using type = T;
Patrick Venturef18bf832018-10-26 18:14:00 -070061 auto get()
62 {
63 return std::make_tuple();
64 }
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050065
66 prev_entry<T> value;
67};
68
69/**
70 * @brief Typedef for above structure usage
71 */
Patrick Venturef18bf832018-10-26 18:14:00 -070072template <typename T>
73using deduce_entry_type_t = typename deduce_entry_type<T>::type;
Adriana Kobylakf855c3e2016-09-29 20:48:08 -050074
Andrew Geissler6d910ad2016-10-16 20:49:14 -050075/**
Deepak Kodihalli15331102017-03-09 23:50:43 -060076 * @brief Used to map an sdbusplus error to a phosphor-logging error type
Andrew Geissler6d910ad2016-10-16 20:49:14 -050077 *
Deepak Kodihalli15331102017-03-09 23:50:43 -060078 * Users log errors via the sdbusplus error name, and the execption that's
79 * thrown is the corresponding sdbusplus exception. However, there's a need
80 * to map the sdbusplus error name to the phosphor-logging error name, in order
81 * to verify the error metadata at compile-time.
Andrew Geissler6d910ad2016-10-16 20:49:14 -050082 */
Deepak Kodihalli15331102017-03-09 23:50:43 -060083template <typename T>
84struct map_exception_type
Andrew Geissler6d910ad2016-10-16 20:49:14 -050085{
Deepak Kodihalli15331102017-03-09 23:50:43 -060086 using type = T;
Andrew Geissler6d910ad2016-10-16 20:49:14 -050087};
88
Deepak Kodihalli15331102017-03-09 23:50:43 -060089/**
90 * @brief Typedef for above structure usage
91 */
Patrick Venturef18bf832018-10-26 18:14:00 -070092template <typename T>
93using map_exception_type_t = typename map_exception_type<T>::type;
Deepak Kodihalli15331102017-03-09 23:50:43 -060094
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -050095/** @fn commit()
96 * @brief Create an error log entry based on journal
97 * entry with a specified exception name
98 * @param[in] name - name of the error exception
Lei YUb50c7052021-01-21 16:02:26 +080099 *
100 * @return The entry ID
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500101 */
Lei YUb50c7052021-01-21 16:02:26 +0800102uint32_t commit(const char* name);
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500103
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500104/** @fn commit() - override that accepts error level
Lei YUb50c7052021-01-21 16:02:26 +0800105 *
106 * @return The entry ID
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500107 */
Lei YUb50c7052021-01-21 16:02:26 +0800108uint32_t commit(const char* name, Entry::Level level);
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500109
Deepak Kodihalli15331102017-03-09 23:50:43 -0600110} // namespace details
111
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500112/** @fn commit()
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500113 * \deprecated use commit<T>()
114 * @brief Create an error log entry based on journal
115 * entry with a specified MSG_ID
116 * @param[in] name - name of the error exception
Lei YUb50c7052021-01-21 16:02:26 +0800117 *
118 * @return The entry ID
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500119 */
Lei YUb50c7052021-01-21 16:02:26 +0800120uint32_t commit(std::string&& name);
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500121
122/** @fn commit()
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500123 * @brief Create an error log entry based on journal
124 * entry with a specified MSG_ID
Lei YUb50c7052021-01-21 16:02:26 +0800125 *
126 * @return The entry ID
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500127 */
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500128template <typename T>
Lei YUb50c7052021-01-21 16:02:26 +0800129uint32_t commit()
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500130{
131 // Validate if the exception is derived from sdbusplus::exception.
Patrick Venturef18bf832018-10-26 18:14:00 -0700132 static_assert(std::is_base_of<sdbusplus::exception::exception, T>::value,
133 "T must be a descendant of sdbusplus::exception::exception");
Lei YUb50c7052021-01-21 16:02:26 +0800134 return details::commit(T::errName);
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500135}
136
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500137/** @fn commit()
138 * @brief Create an error log entry based on journal
139 * entry with a specified MSG_ID. This override accepts error level.
140 * @param[in] level - level of the error
Lei YUb50c7052021-01-21 16:02:26 +0800141 *
142 * @return The entry ID
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500143 */
144template <typename T>
Lei YUb50c7052021-01-21 16:02:26 +0800145uint32_t commit(Entry::Level level)
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500146{
147 // Validate if the exception is derived from sdbusplus::exception.
Patrick Venturef18bf832018-10-26 18:14:00 -0700148 static_assert(std::is_base_of<sdbusplus::exception::exception, T>::value,
149 "T must be a descendant of sdbusplus::exception::exception");
Lei YUb50c7052021-01-21 16:02:26 +0800150 return details::commit(T::errName, level);
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500151}
152
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500153/** @fn elog()
154 * @brief Create a journal log entry based on predefined
155 * error log information
156 * @tparam T - Error log type
157 * @param[in] i_args - Metadata fields to be added to the journal entry
158 */
Patrick Venturef18bf832018-10-26 18:14:00 -0700159template <typename T, typename... Args>
Matt Spinlerd8f3c652019-07-01 08:39:03 -0500160[[noreturn]] void elog(Args... i_args)
161{
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500162 // Validate if the exception is derived from sdbusplus::exception.
Patrick Venturef18bf832018-10-26 18:14:00 -0700163 static_assert(std::is_base_of<sdbusplus::exception::exception, T>::value,
164 "T must be a descendant of sdbusplus::exception::exception");
Marri Devender Rao7d0a07b2017-04-04 03:43:00 -0500165
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500166 // Validate the caller passed in the required parameters
Patrick Venturef18bf832018-10-26 18:14:00 -0700167 static_assert(
168 std::is_same<typename details::map_exception_type_t<T>::metadata_types,
169 std::tuple<details::deduce_entry_type_t<Args>...>>::value,
170 "You are not passing in required arguments for this error");
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500171
Deepak Kodihalli15331102017-03-09 23:50:43 -0600172 log<details::map_exception_type_t<T>::L>(
Patrick Venturef18bf832018-10-26 18:14:00 -0700173 T::errDesc, details::deduce_entry_type<Args>{i_args}.get()...);
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500174
175 // Now throw an exception for this error
Deepak Kodihalli15331102017-03-09 23:50:43 -0600176 throw T();
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500177}
178
Marri Devender Raod41e9952017-04-04 04:09:02 -0500179/** @fn report()
180 * @brief Create a journal log entry based on predefined
181 * error log information and commit the error
182 * @tparam T - exception
183 * @param[in] i_args - Metadata fields to be added to the journal entry
Lei YUb50c7052021-01-21 16:02:26 +0800184 *
185 * @return The entry ID
Marri Devender Raod41e9952017-04-04 04:09:02 -0500186 */
Patrick Venturef18bf832018-10-26 18:14:00 -0700187template <typename T, typename... Args>
Lei YUb50c7052021-01-21 16:02:26 +0800188uint32_t report(Args... i_args)
Marri Devender Raod41e9952017-04-04 04:09:02 -0500189{
Patrick Venturef18bf832018-10-26 18:14:00 -0700190 // validate if the exception is derived from sdbusplus::exception.
191 static_assert(std::is_base_of<sdbusplus::exception::exception, T>::value,
192 "T must be a descendant of sdbusplus::exception::exception");
Marri Devender Raod41e9952017-04-04 04:09:02 -0500193
194 // Validate the caller passed in the required parameters
Patrick Venturef18bf832018-10-26 18:14:00 -0700195 static_assert(
196 std::is_same<typename details::map_exception_type_t<T>::metadata_types,
197 std::tuple<details::deduce_entry_type_t<Args>...>>::value,
198 "You are not passing in required arguments for this error");
Marri Devender Raod41e9952017-04-04 04:09:02 -0500199
200 log<details::map_exception_type_t<T>::L>(
Patrick Venturef18bf832018-10-26 18:14:00 -0700201 T::errDesc, details::deduce_entry_type<Args>{i_args}.get()...);
Marri Devender Raod41e9952017-04-04 04:09:02 -0500202
Lei YUb50c7052021-01-21 16:02:26 +0800203 return commit<T>();
Marri Devender Raod41e9952017-04-04 04:09:02 -0500204}
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500205
206/** @fn report()
207 * @brief Create a journal log entry based on predefined
208 * error log information and commit the error. Accepts error
209 * level.
210 * @tparam T - exception
211 * @param[in] level - level of the error
212 * @param[in] i_args - Metadata fields to be added to the journal entry
Lei YUb50c7052021-01-21 16:02:26 +0800213 *
214 * @return The entry ID
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500215 */
Patrick Venturef18bf832018-10-26 18:14:00 -0700216template <typename T, typename... Args>
Lei YUb50c7052021-01-21 16:02:26 +0800217uint32_t report(Entry::Level level, Args... i_args)
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500218{
Patrick Venturef18bf832018-10-26 18:14:00 -0700219 // validate if the exception is derived from sdbusplus::exception.
220 static_assert(std::is_base_of<sdbusplus::exception::exception, T>::value,
221 "T must be a descendant of sdbusplus::exception::exception");
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500222
223 // Validate the caller passed in the required parameters
Patrick Venturef18bf832018-10-26 18:14:00 -0700224 static_assert(
225 std::is_same<typename details::map_exception_type_t<T>::metadata_types,
226 std::tuple<details::deduce_entry_type_t<Args>...>>::value,
227 "You are not passing in required arguments for this error");
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500228
229 log<details::map_exception_type_t<T>::L>(
Patrick Venturef18bf832018-10-26 18:14:00 -0700230 T::errDesc, details::deduce_entry_type<Args>{i_args}.get()...);
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500231
Lei YUb50c7052021-01-21 16:02:26 +0800232 return commit<T>(level);
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500233}
234
Adriana Kobylakf855c3e2016-09-29 20:48:08 -0500235} // namespace logging
236
237} // namespace phosphor