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