xref: /openbmc/telemetry/src/trigger_actions.cpp (revision f763c9e3bbe0f86a4a41e7bb0dc70bffde0af9b2)
1 #include "trigger_actions.hpp"
2 
3 #include <phosphor-logging/log.hpp>
4 
5 #include <ctime>
6 
7 namespace action
8 {
9 
10 namespace
11 {
12 std::string timestampToString(uint64_t timestamp)
13 {
14     std::time_t t = static_cast<time_t>(timestamp);
15     std::array<char, sizeof("YYYY-MM-DDThh:mm:ssZ")> buf = {};
16     size_t size =
17         std::strftime(buf.data(), buf.size(), "%FT%TZ", std::gmtime(&t));
18     if (size == 0)
19     {
20         throw std::runtime_error("Failed to parse timestamp to string");
21     }
22     return std::string(buf.data(), size);
23 }
24 } // namespace
25 
26 namespace numeric
27 {
28 
29 static const char* getDirection(double value, double threshold)
30 {
31     if (value < threshold)
32     {
33         return "decreasing";
34     }
35     if (value > threshold)
36     {
37         return "increasing";
38     }
39     throw std::runtime_error("Invalid value");
40 }
41 
42 const char* LogToJournal::getType() const
43 {
44     switch (type)
45     {
46         case ::numeric::Type::upperCritical:
47             return "UpperCritical";
48         case ::numeric::Type::lowerCritical:
49             return "LowerCritical";
50         case ::numeric::Type::upperWarning:
51             return "UpperWarning";
52         case ::numeric::Type::lowerWarning:
53             return "LowerWarning";
54     }
55     throw std::runtime_error("Invalid type");
56 }
57 
58 void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
59                           double value)
60 {
61     std::string msg = std::string(getType()) +
62                       " numeric threshold condition is met on sensor " +
63                       sensorName + ", recorded value " + std::to_string(value) +
64                       ", timestamp " + timestampToString(timestamp) +
65                       ", direction " +
66                       std::string(getDirection(value, threshold));
67 
68     phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
69 }
70 
71 const char* LogToRedfish::getMessageId() const
72 {
73     switch (type)
74     {
75         case ::numeric::Type::upperCritical:
76             return "OpenBMC.0.1.0.NumericThresholdUpperCritical";
77         case ::numeric::Type::lowerCritical:
78             return "OpenBMC.0.1.0.NumericThresholdLowerCritical";
79         case ::numeric::Type::upperWarning:
80             return "OpenBMC.0.1.0.NumericThresholdUpperWarning";
81         case ::numeric::Type::lowerWarning:
82             return "OpenBMC.0.1.0.NumericThresholdLowerWarning";
83     }
84     throw std::runtime_error("Invalid type");
85 }
86 
87 void LogToRedfish::commit(const std::string& sensorName, uint64_t timestamp,
88                           double value)
89 {
90     phosphor::logging::log<phosphor::logging::level::INFO>(
91         "Threshold value is exceeded",
92         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", getMessageId()),
93         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu,%s",
94                                  sensorName.c_str(), value, timestamp,
95                                  getDirection(value, threshold)));
96 }
97 
98 } // namespace numeric
99 
100 namespace discrete
101 {
102 const char* LogToJournal::getSeverity() const
103 {
104     switch (severity)
105     {
106         case ::discrete::Severity::ok:
107             return "OK";
108         case ::discrete::Severity::warning:
109             return "Warning";
110         case ::discrete::Severity::critical:
111             return "Critical";
112     }
113     throw std::runtime_error("Invalid severity");
114 }
115 
116 void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
117                           double value)
118 {
119     std::string msg = std::string(getSeverity()) +
120                       " discrete threshold condition is met on sensor " +
121                       sensorName + ", recorded value " + std::to_string(value) +
122                       ", timestamp " + timestampToString(timestamp);
123 
124     phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
125 }
126 
127 const char* LogToRedfish::getMessageId() const
128 {
129     switch (severity)
130     {
131         case ::discrete::Severity::ok:
132             return "OpenBMC.0.1.0.DiscreteThresholdOk";
133         case ::discrete::Severity::warning:
134             return "OpenBMC.0.1.0.DiscreteThresholdWarning";
135         case ::discrete::Severity::critical:
136             return "OpenBMC.0.1.0.DiscreteThresholdCritical";
137     }
138     throw std::runtime_error("Invalid severity");
139 }
140 
141 void LogToRedfish::commit(const std::string& sensorName, uint64_t timestamp,
142                           double value)
143 {
144     phosphor::logging::log<phosphor::logging::level::INFO>(
145         "Discrete treshold condition is met",
146         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", getMessageId()),
147         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu",
148                                  sensorName.c_str(), value, timestamp));
149 }
150 
151 namespace onChange
152 {
153 void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
154                           double value)
155 {
156     std::string msg = "Value changed on sensor " + sensorName +
157                       ", recorded value " + std::to_string(value) +
158                       ", timestamp " + timestampToString(timestamp);
159 
160     phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
161 }
162 
163 void LogToRedfish::commit(const std::string& sensorName, uint64_t timestamp,
164                           double value)
165 {
166     const char* messageId = "OpenBMC.0.1.0.DiscreteThresholdOnChange";
167     phosphor::logging::log<phosphor::logging::level::INFO>(
168         "Uncondtional discrete threshold triggered",
169         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
170         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu",
171                                  sensorName.c_str(), value, timestamp));
172 }
173 } // namespace onChange
174 } // namespace discrete
175 
176 void UpdateReport::commit(const std::string&, uint64_t, double)
177 {
178     for (const auto& name : reportNames)
179     {
180         reportManager.updateReport(name);
181     }
182 }
183 } // namespace action
184