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/lg2.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 EndpointList = std::vector<std::string>; 36 using EndpointsProperty = std::variant<EndpointList>; 37 38 void ResolveCallout::operator()(Context /* ctx */) 39 { 40 // Resolve all errors for this callout: 41 // 1) Read the 'endpoints' property for the callout/fault object 42 // 43 // 2) Follow each endpoint to its log entry 44 // 45 // 3) Set the Resolved property to true on the entry 46 47 try 48 { 49 auto path = callout + "/fault"; 50 auto busName = SDBusPlus::getBusName(path, ASSOCIATION_IFACE); 51 52 if (busName.empty()) 53 { 54 // Just means there are no error logs with this callout 55 return; 56 } 57 58 auto endpoints = SDBusPlus::callMethodAndRead<EndpointsProperty>( 59 busName, path, PROPERTY_IFACE, "Get", ASSOCIATION_IFACE, 60 ENDPOINTS_PROPERTY); 61 62 const auto& logEntries = std::get<EndpointList>(endpoints); 63 64 // Resolve each log entry 65 for (const auto& logEntry : logEntries) 66 { 67 resolve(logEntry); 68 } 69 } 70 catch (const std::exception& e) 71 { 72 lg2::error("Failed getting callout fault associations: {ERROR}, {PATH}", 73 "ERROR", e, "PATH", callout); 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 std::variant<bool> resolved = true; 92 93 SDBusPlus::callMethod(busName, logEntry, PROPERTY_IFACE, "Set", 94 LOGGING_IFACE, RESOLVED_PROPERTY, resolved); 95 } 96 catch (const std::exception& e) 97 { 98 lg2::error("Unable to resolve error log entry {ENTRY}: {ERROR}", 99 "ENTRY", logEntry, "ERROR", e); 100 } 101 } 102 103 } // namespace monitoring 104 } // namespace dbus 105 } // namespace phosphor 106