xref: /openbmc/ibm-logging/policy_table.cpp (revision c57aa4b9)
1 /**
2  * Copyright © 2018 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 "policy_table.hpp"
17 
18 #include <experimental/filesystem>
19 #include <fstream>
20 #include <nlohmann/json.hpp>
21 #include <phosphor-logging/log.hpp>
22 
23 namespace ibm
24 {
25 namespace logging
26 {
27 namespace policy
28 {
29 
30 namespace fs = std::experimental::filesystem;
31 using namespace phosphor::logging;
32 
33 Table::Table(const std::string& jsonFile)
34 {
35     if (fs::exists(jsonFile))
36     {
37         load(jsonFile);
38     }
39     else
40     {
41         log<level::INFO>("Policy table JSON file does not exist",
42                          entry("FILE=%s", jsonFile.c_str()));
43     }
44 }
45 
46 void Table::load(const std::string& jsonFile)
47 {
48     try
49     {
50         std::ifstream file{jsonFile};
51 
52         auto json = nlohmann::json::parse(file, nullptr, true);
53 
54         for (const auto& policy : json)
55         {
56             DetailsList detailsList;
57 
58             for (const auto& details : policy["dtls"])
59             {
60                 Details d;
61                 d.modifier = details["mod"];
62                 d.msg = details["msg"];
63                 d.ceid = details["CEID"];
64                 detailsList.emplace_back(std::move(d));
65             }
66             policies.emplace(policy["err"], std::move(detailsList));
67         }
68 
69         loaded = true;
70     }
71     catch (std::exception& e)
72     {
73         log<level::ERR>("Failed loading policy table json file",
74                         entry("FILE=%s", jsonFile.c_str()),
75                         entry("ERROR=%s", e.what()));
76         loaded = false;
77     }
78 }
79 
80 FindResult Table::find(const std::string& error,
81                        const std::string& modifier) const
82 {
83     // First find the entry based on the error, and then find which
84     // underlying details object it is with the help of the modifier.
85 
86     auto policy = policies.find(error);
87 
88     if (policy != policies.end())
89     {
90         // If there is no exact modifier match, then look for an entry with
91         // an empty modifier - it is the catch-all for that error.
92         auto details = std::find_if(
93             policy->second.begin(), policy->second.end(),
94             [&modifier](const auto& d) { return modifier == d.modifier; });
95 
96         if ((details == policy->second.end()) && !modifier.empty())
97         {
98             details =
99                 std::find_if(policy->second.begin(), policy->second.end(),
100                              [](const auto& d) { return d.modifier.empty(); });
101         }
102 
103         if (details != policy->second.end())
104         {
105             return DetailsReference(*details);
106         }
107     }
108 
109     return {};
110 }
111 } // namespace policy
112 } // namespace logging
113 } // namespace ibm
114