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