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 = "org.openbmc.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 = sdbusplus::message::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 = 64 sdbusplus::message::variant_ns::get<EndpointList>(endpoints); 65 66 // Resolve each log entry 67 for (const auto& logEntry : logEntries) 68 { 69 resolve(logEntry); 70 } 71 } 72 catch (const std::exception& e) 73 { 74 log<level::ERR>("Failed getting callout fault associations", 75 entry("CALLOUT=%s", callout.c_str()), 76 entry("ERROR=%s", e.what())); 77 } 78 } 79 80 void ResolveCallout::resolve(const std::string& logEntry) 81 { 82 try 83 { 84 static std::string busName; 85 if (busName.empty()) 86 { 87 busName = SDBusPlus::getBusName(logEntry, LOGGING_IFACE); 88 if (busName.empty()) 89 { 90 return; 91 } 92 } 93 94 sdbusplus::message::variant<bool> resolved = true; 95 96 auto response = 97 SDBusPlus::callMethod(busName, logEntry, PROPERTY_IFACE, "Set", 98 LOGGING_IFACE, RESOLVED_PROPERTY, resolved); 99 100 if (response.is_method_error()) 101 { 102 log<level::ERR>( 103 "Failed to set Resolved property on an error log entry", 104 entry("ENTRY=%s", logEntry.c_str())); 105 } 106 } 107 catch (const std::exception& e) 108 { 109 log<level::ERR>("Unable to resolve error log entry", 110 entry("ENTRY=%s", logEntry.c_str()), 111 entry("ERROR=%s", e.what())); 112 } 113 } 114 115 } // namespace monitoring 116 } // namespace dbus 117 } // namespace phosphor 118