xref: /openbmc/phosphor-logging/lib/lg2_commit.cpp (revision 6eb96bf73ca5f59e027808e80528720880cc436e)
1 #include "config.h"
2 
3 #include "lg2_commit.hpp"
4 
5 #include <sys/syslog.h>
6 
7 #include <nlohmann/json.hpp>
8 #include <phosphor-logging/lg2.hpp>
9 #include <phosphor-logging/lg2/commit.hpp>
10 #include <sdbusplus/async.hpp>
11 #include <sdbusplus/exception.hpp>
12 #include <xyz/openbmc_project/Logging/Create/client.hpp>
13 #include <xyz/openbmc_project/Logging/Entry/client.hpp>
14 
15 namespace lg2::details
16 {
17 
18 using Create = sdbusplus::client::xyz::openbmc_project::logging::Create<>;
19 using Entry = sdbusplus::client::xyz::openbmc_project::logging::Entry<>;
20 
21 /* Convert syslog severity to Entry::Level */
22 static auto severity_from_syslog(int s) -> Entry::Level
23 {
24     switch (s)
25     {
26         case LOG_DEBUG:
27             return Entry::Level::Debug;
28 
29         case LOG_INFO:
30             return Entry::Level::Informational;
31 
32         case LOG_NOTICE:
33             return Entry::Level::Notice;
34 
35         case LOG_WARNING:
36             return Entry::Level::Warning;
37 
38         case LOG_ERR:
39             return Entry::Level::Error;
40 
41         case LOG_CRIT:
42             return Entry::Level::Critical;
43 
44         case LOG_ALERT:
45             return Entry::Level::Alert;
46 
47         case LOG_EMERG:
48             return Entry::Level::Emergency;
49     }
50     return Entry::Level::Emergency;
51 }
52 
53 using AdditionalData_t = std::map<std::string, std::string>;
54 
55 /* Create AdditionalData from the sdbusplus event json. */
56 static auto data_from_json(sdbusplus::exception::generated_event_base& t)
57     -> AdditionalData_t
58 {
59     AdditionalData_t result{};
60 
61     auto j = t.to_json()[t.name()];
62     for (const auto& item : j.items())
63     {
64         // Special cases for the "_SOURCE" fields, which contain debug
65         // information about the origin of the event.
66         if (item.key() == "_SOURCE")
67         {
68             for (const auto& source_item : item.value().items())
69             {
70                 if (source_item.key() == "PID")
71                 {
72                     result.emplace("_PID", source_item.value().dump());
73                     continue;
74                 }
75                 if (source_item.key() == "FILE")
76                 {
77                     result.emplace("_CODE_FILE", source_item.value());
78                     continue;
79                 }
80                 if (source_item.key() == "FUNCTION")
81                 {
82                     result.emplace("_CODE_FUNC", source_item.value());
83                     continue;
84                 }
85                 if (source_item.key() == "LINE")
86                 {
87                     result.emplace("_CODE_LINE", source_item.value().dump());
88                     continue;
89                 }
90             }
91             continue;
92         }
93 
94         result.emplace(item.key(), item.value().dump());
95     }
96 
97     return result;
98 }
99 
100 auto commit(sdbusplus::exception::generated_event_base&& t)
101     -> sdbusplus::message::object_path
102 {
103     if constexpr (LG2_COMMIT_JOURNAL)
104     {
105         lg2::error("OPENBMC_MESSAGE_ID={DATA}", "DATA", t.to_json().dump());
106     }
107 
108     if constexpr (LG2_COMMIT_DBUS)
109     {
110         auto b = sdbusplus::bus::new_default();
111         auto m =
112             b.new_method_call(Create::default_service, Create::instance_path,
113                               Create::interface, "Create");
114 
115         m.append(t.name(), severity_from_syslog(t.severity()),
116                  data_from_json(t));
117 
118         auto reply = b.call(m);
119 
120         return reply.unpack<sdbusplus::message::object_path>();
121     }
122 
123     return {};
124 }
125 
126 auto commit(sdbusplus::async::context& ctx,
127             sdbusplus::exception::generated_event_base&& t)
128     -> sdbusplus::async::task<sdbusplus::message::object_path>
129 {
130     if constexpr (LG2_COMMIT_JOURNAL)
131     {
132         lg2::error("OPENBMC_MESSAGE_ID={DATA}", "DATA", t.to_json().dump());
133     }
134 
135     if constexpr (LG2_COMMIT_DBUS)
136     {
137         co_return co_await Create(ctx)
138             .service(Create::default_service)
139             .path(Create::instance_path)
140             .create(t.name(), severity_from_syslog(t.severity()),
141                     data_from_json(t));
142     }
143     co_return {};
144 }
145 
146 auto extractEvent(sdbusplus::exception::generated_event_base&& t)
147     -> std::tuple<std::string, Entry::Level, std::vector<std::string>>
148 {
149     auto data = data_from_json(t);
150     std::vector<std::string> additional_data = {};
151 
152     for (auto& [key, data] : data)
153     {
154         additional_data.emplace_back(key + "=" + data);
155     }
156 
157     return {t.name(), severity_from_syslog(t.severity()),
158             std::move(additional_data)};
159 }
160 
161 } // namespace lg2::details
162