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