1 /** 2 * Copyright © 2017 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "resolve_errors.hpp" 17 18 #include "sdbusplus.hpp" 19 20 #include <phosphor-logging/log.hpp> 21 22 namespace phosphor 23 { 24 namespace dbus 25 { 26 namespace monitoring 27 { 28 29 constexpr auto LOGGING_IFACE = "xyz.openbmc_project.Logging.Entry"; 30 constexpr auto PROPERTY_IFACE = "org.freedesktop.DBus.Properties"; 31 constexpr auto ASSOCIATION_IFACE = "xyz.openbmc_project.Association"; 32 constexpr auto ENDPOINTS_PROPERTY = "endpoints"; 33 constexpr auto RESOLVED_PROPERTY = "Resolved"; 34 35 using namespace phosphor::logging; 36 using EndpointList = std::vector<std::string>; 37 using EndpointsProperty = std::variant<EndpointList>; 38 39 void ResolveCallout::operator()(Context /* ctx */) 40 { 41 // Resolve all errors for this callout: 42 // 1) Read the 'endpoints' property for the callout/fault object 43 // 44 // 2) Follow each endpoint to its log entry 45 // 46 // 3) Set the Resolved property to true on the entry 47 48 try 49 { 50 auto path = callout + "/fault"; 51 auto busName = SDBusPlus::getBusName(path, ASSOCIATION_IFACE); 52 53 if (busName.empty()) 54 { 55 // Just means there are no error logs with this callout 56 return; 57 } 58 59 auto endpoints = SDBusPlus::callMethodAndRead<EndpointsProperty>( 60 busName, path, PROPERTY_IFACE, "Get", ASSOCIATION_IFACE, 61 ENDPOINTS_PROPERTY); 62 63 const auto& logEntries = std::get<EndpointList>(endpoints); 64 65 // Resolve each log entry 66 for (const auto& logEntry : logEntries) 67 { 68 resolve(logEntry); 69 } 70 } 71 catch (const std::exception& e) 72 { 73 log<level::ERR>("Failed getting callout fault associations", 74 entry("CALLOUT=%s", callout.c_str()), 75 entry("ERROR=%s", e.what())); 76 } 77 } 78 79 void ResolveCallout::resolve(const std::string& logEntry) 80 { 81 try 82 { 83 static std::string busName; 84 if (busName.empty()) 85 { 86 busName = SDBusPlus::getBusName(logEntry, LOGGING_IFACE); 87 if (busName.empty()) 88 { 89 return; 90 } 91 } 92 93 std::variant<bool> resolved = true; 94 95 auto response = 96 SDBusPlus::callMethod(busName, logEntry, PROPERTY_IFACE, "Set", 97 LOGGING_IFACE, RESOLVED_PROPERTY, resolved); 98 99 if (response.is_method_error()) 100 { 101 log<level::ERR>( 102 "Failed to set Resolved property on an error log entry", 103 entry("ENTRY=%s", logEntry.c_str())); 104 } 105 } 106 catch (const std::exception& e) 107 { 108 log<level::ERR>("Unable to resolve error log entry", 109 entry("ENTRY=%s", logEntry.c_str()), 110 entry("ERROR=%s", e.what())); 111 } 112 } 113 114 } // namespace monitoring 115 } // namespace dbus 116 } // namespace phosphor 117