xref: /openbmc/phosphor-logging/tools/elog-gen.py (revision 9916119f0daad8bd5b3fbd926ada9a023949f311)
1#!/usr/bin/env python
2
3r"""
4This script will parse the input error log yaml file and generate
5a header file which will then be used by the error logging client and
6server to collect and validate the error information generated by the
7openbmc software components.
8
9This code uses a mako template to provide the basic template of the header
10file we're going to generate.  We then call it with information from the
11yaml to generate the header file.
12
13"""
14
15from mako.template import Template
16from optparse import OptionParser
17import yaml
18import sys
19import os
20
21
22def get_cpp_type(i_type):
23    typeMap = {
24        'int16': 'int16_t',
25        'int32': 'int32_t',
26        'int64': 'int64_t',
27        'uint16': 'uint16_t',
28        'uint32': 'uint32_t',
29        'uint64': 'uint64_t',
30        'double': 'double',
31        # const char* aids usage of constexpr
32        'string': 'const char*'}
33
34    return typeMap[i_type]
35
36
37def gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml,
38                 i_input_mako, i_output_hpp):
39    r"""
40    Read the input yaml file, grab the relevant data and call the mako
41    template to generate the header file.
42
43    Description of arguments:
44    i_rootdir                    base directory to search for yaml files
45    i_elog_yaml                  yaml file describing the error logs
46    i_elog_meta_yaml             yaml file describing the meta data for elogs
47    i_input_mako                 input mako template file to use
48    i_output_hpp                 header file to output the generated code to
49    """
50
51    # Input parameters to mako template
52    errors = dict()  # Main error codes
53    error_msg = dict()  # Error msg that corresponds to error code
54    error_lvl = dict()  # Error code log level (debug, info, error, ...)
55    meta = list()  # The meta data names associated (ERRNO, FILE_NAME, ...)
56    meta_data = dict()  # The meta data info (type, format)
57
58    # see elog.yaml for reference
59    ifile = yaml.safe_load(open("/".join((i_rootdir, i_elog_yaml))))
60    mfile = yaml.safe_load(open(i_elog_meta_yaml))
61    err_count = 0
62    for i in ifile:
63        match = None
64        # Find the corresponding meta data for this entry
65        for m in mfile:
66            if m['name'] == i['name']:
67                match = m
68                break
69        if (match is None):
70            print "Error - Did not find meta data for " + i['name']
71            exit(1)
72        # Grab the main error and it's info
73        errors[err_count] = i['name']
74        error_msg[i['name']] = i['description']
75        error_lvl[i['name']] = match['level']
76        tmp_meta = []
77        # grab all the meta data fields and info
78        for j in match['meta']:
79            str_short = j['str'].split('=')[0]
80            tmp_meta.append(str_short)
81            meta_data[str_short] = {}
82            meta_data[str_short]['str'] = j['str']
83            meta_data[str_short]['str_short'] = str_short
84            meta_data[str_short]['type'] = get_cpp_type(j['type'])
85        meta.append(tmp_meta)
86        err_count += 1
87
88    # Debug
89    # for i in errors:
90    #   print "ERROR: " + errors[i]
91    #   print " MSG:  " + error_msg[errors[i]]
92    #   print " LVL:  " + error_lvl[errors[i]]
93    #   print " META: "
94    #   print meta[i]
95
96    # Load the mako template and call it with the required data
97    mytemplate = Template(filename=i_input_mako)
98    f = open(i_output_hpp, 'w')
99    f.write(mytemplate.render(errors=errors, error_msg=error_msg,
100                              error_lvl=error_lvl, meta=meta,
101                              meta_data=meta_data, elog_yaml=i_elog_yaml))
102    f.close()
103
104
105def main(i_args):
106    parser = OptionParser()
107
108    parser.add_option("-e", "--elog", dest="elog_yaml",
109                      default="xyz/openbmc_project/Example/Elog.errors.yaml",
110                      help="input error yaml file to parse")
111
112    parser.add_option("-m", "--mako", dest="elog_mako",
113                      default="elog-gen-template.mako.hpp",
114                      help="input mako template file to use")
115
116    parser.add_option("-o", "--output", dest="output_hpp",
117                      default="elog-gen.hpp",
118                      help="output hpp to generate, elog-gen.hpp is default")
119
120    parser.add_option("-r", "--rootdir", dest="rootdir",
121                      default="example",
122                      help="Base directory of yaml files to process")
123
124    parser.add_option("-t", "--templatedir", dest="templatedir",
125                      default="phosphor-logging/templates/",
126                      help="Base directory of files to process")
127
128    (options, args) = parser.parse_args(i_args)
129
130    # Verify the input yaml file
131    yaml_path = "/".join((options.rootdir, options.elog_yaml))
132    if (not (os.path.isfile(yaml_path))):
133        print "Can not find input yaml file " + yaml_path
134        exit(1)
135
136    # the meta data will be defined in a similar file name where we replace
137    # <Interface>.errors.yaml with <Interface>.metadata.yaml
138    meta_file = options.elog_yaml.replace("errors", "metadata")
139    meta_file = "/".join((options.rootdir, meta_file))
140    if (not (os.path.isfile(meta_file))):
141        print "Can not find meta yaml file " + meta_file
142        exit(1)
143
144    # Verify the input mako file
145    template_path = "/".join((options.templatedir, options.elog_mako))
146    if (not (os.path.isfile(template_path))):
147        print "Can not find input template file " + template_path
148        exit(1)
149
150    gen_elog_hpp(options.rootdir,
151                 options.elog_yaml,
152                 meta_file,
153                 template_path,
154                 options.output_hpp)
155
156# Only run if it's a script
157if __name__ == '__main__':
158    main(sys.argv[1:])
159