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 <phosphor-logging/log.hpp> 17 #include "resolve_errors.hpp" 18 #include "sdbusplus.hpp" 19 20 namespace phosphor 21 { 22 namespace dbus 23 { 24 namespace monitoring 25 { 26 27 constexpr auto LOGGING_IFACE = "xyz.openbmc_project.Logging.Entry"; 28 constexpr auto PROPERTY_IFACE = "org.freedesktop.DBus.Properties"; 29 constexpr auto ASSOCIATION_IFACE = "org.openbmc.Association"; 30 constexpr auto ENDPOINTS_PROPERTY = "endpoints"; 31 constexpr auto RESOLVED_PROPERTY = "Resolved"; 32 33 using namespace phosphor::logging; 34 using EndpointList = std::vector<std::string>; 35 using EndpointsProperty = sdbusplus::message::variant<EndpointList>; 36 37 void ResolveCallout::operator()(Context ctx) 38 { 39 // Resolve all errors for this callout: 40 // 1) Read the 'endpoints' property for the callout/fault object 41 // 42 // 2) Follow each endpoint to its log entry 43 // 44 // 3) Set the Resolved property to true on the entry 45 46 try 47 { 48 auto path = callout + "/fault"; 49 auto busName = SDBusPlus::getBusName(path, ASSOCIATION_IFACE); 50 51 if (busName.empty()) 52 { 53 // Just means there are no error logs with this callout 54 return; 55 } 56 57 auto endpoints = SDBusPlus::callMethodAndRead<EndpointsProperty>( 58 busName, path, PROPERTY_IFACE, "Get", ASSOCIATION_IFACE, 59 ENDPOINTS_PROPERTY); 60 61 const auto& logEntries = endpoints.get<EndpointList>(); 62 63 // Resolve each log entry 64 for (const auto& logEntry : logEntries) 65 { 66 resolve(logEntry); 67 } 68 } 69 catch (const std::exception& e) 70 { 71 log<level::ERR>("Failed getting callout fault associations", 72 entry("CALLOUT=%s", callout.c_str()), 73 entry("MESSAGE=%s", e.what())); 74 } 75 } 76 77 void ResolveCallout::resolve(const std::string& logEntry) 78 { 79 try 80 { 81 static std::string busName; 82 if (busName.empty()) 83 { 84 busName = SDBusPlus::getBusName(logEntry, LOGGING_IFACE); 85 if (busName.empty()) 86 { 87 return; 88 } 89 } 90 91 sdbusplus::message::variant<bool> resolved = true; 92 93 auto response = 94 SDBusPlus::callMethod(busName, logEntry, PROPERTY_IFACE, "Set", 95 LOGGING_IFACE, RESOLVED_PROPERTY, resolved); 96 97 if (response.is_method_error()) 98 { 99 log<level::ERR>( 100 "Failed to set Resolved property on an error log entry", 101 entry("ENTRY=%s", logEntry.c_str())); 102 } 103 } 104 catch (const std::exception& e) 105 { 106 log<level::ERR>("Unable to resolve error log entry", 107 entry("ENTRY=%s", logEntry.c_str()), 108 entry("MESSAGE=%s", e.what())); 109 } 110 } 111 112 } // namespace monitoring 113 } // namespace dbus 114 } // namespace phosphor 115