xref: /openbmc/ibm-logging/condense_policy.py (revision c4bc11e8)
1#!/usr/bin/env python3
2
3"""Condenses the error policy table down to only the fields used by
4   the BMC Code.
5
6This script pulls the following 4 fields out of the full JSON policy
7table and arranges them for easier searching:
8
9    Error:         The OpenBMC error.
10                   e.g. xyz.openbmc_project.Thermal.Error.PowerSupplyHot
11    CommonEventID: Used to index into the online documentation.
12                   e.g. FQPSPCA0065M
13    Modifier:      Used in combination with the error to locate a
14                   table entry.
15                   e.g. <an inventory callout>
16    Message:       A short message describing the error.
17                   e.g. "Power supply 0 is too hot"
18
19There may be multiple CommonEventID/Modifier/Message groups per Error,
20which is why both the error and modifier are needed to find an entry.
21
22Example condensed entry, prettified:
23    {
24      "dtls":[
25        {
26          "CEID":"FQPSPCA0065M",
27          "mod":"/xyz/openbmc_project/inventory/system/ps0",
28          "msg":"Power supply 0 is too hot"
29        },
30        {
31          "CEID":"FQPSPCA0066M",
32          "mod":"/xyz/openbmc_project/inventory/system/ps1",
33          "msg":"Power supply 1 is too hot"
34        }
35      ],
36      "err":"xyz.openbmc_project.Thermal.Error.PowerSupplyHot"
37    }
38"""
39
40import argparse
41import json
42
43
44def add_details(error, details, condensed):
45    """Adds a details entry to an error"""
46
47    found = False
48    for errors in condensed:
49        if errors["err"] == error:
50            errors["dtls"].append(details)
51            found = True
52            break
53
54    if not found:
55        group = {}
56        group["err"] = error
57        group["dtls"] = []
58        group["dtls"].append(details)
59        condensed.append(group)
60
61
62if __name__ == "__main__":
63    parser = argparse.ArgumentParser(description="Error log policy condenser")
64
65    parser.add_argument(
66        "-p",
67        "--policy",
68        dest="policy_file",
69        default="policyTable.json",
70        help="Policy Table in JSON",
71    )
72    parser.add_argument(
73        "-c",
74        "--condensed_policy",
75        dest="condensed_file",
76        default="condensed.json",
77        help="Condensed policy output file in JSON",
78    )
79    parser.add_argument(
80        "-t",
81        "--prettify_json",
82        dest="prettify",
83        default=False,
84        action="store_true",
85        help="Prettify the output JSON",
86    )
87
88    args = parser.parse_args()
89
90    with open(args.policy_file, "r") as table:
91        contents = json.load(table)
92        policytable = contents["events"]
93
94    condensed = []
95
96    for name in policytable:
97        details = {}
98
99        # Parse the error||modifer line. The modifier is optional.
100        separatorPos = name.find("||")
101        if separatorPos != -1:
102            error = name[0:separatorPos]
103            modifier = name[separatorPos + 2 :]
104            details["mod"] = modifier
105        else:
106            error = name
107            details["mod"] = ""
108
109        # The table has some nonBMC errors - they have spaces - skip them
110        if " " in error:
111            print("Skipping error %s because of spaces" % error)
112            continue
113
114        details["msg"] = policytable[name]["Message"]
115        details["CEID"] = policytable[name]["CommonEventID"]
116
117        add_details(error, details, condensed)
118
119    # if prettified there will be newlines
120    indent_value = 2 if args.prettify else None
121
122    with open(args.condensed_file, "w") as outfile:
123        json.dump(
124            condensed, outfile, separators=(",", ":"), indent=indent_value
125        )
126