diff options
author | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-01-17 04:25:22 -0600 |
---|---|---|
committer | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-01-27 10:42:17 -0600 |
commit | 160d3e0b810f6c5f582c7daf906ce0c99cd4194e (patch) | |
tree | 6c918b816030b51e3c927583002a10d92a7aa66e /tools | |
parent | 9916119f0daad8bd5b3fbd926ada9a023949f311 (diff) | |
download | phosphor-logging-160d3e0b810f6c5f582c7daf906ce0c99cd4194e.tar.gz phosphor-logging-160d3e0b810f6c5f582c7daf906ce0c99cd4194e.zip |
elog-gen.py : read multiple error yaml files
This change enables the elog-gen script to look at more than one error
yaml file (and corresponding metadata yaml file). The input to the
script had to be changed to a yaml directory, containing
error yaml files, instead of a single error yaml file.
The reason to support reading multiple error yaml files is that,
without this, applications have to all dump their errors in a single big
error yaml file. Now it's possible to write application/domain specific
error yaml files; they just need to be exported to the same location,
from where elog-gen.py can pick them.
Change-Id: I9418bf0e0b54a7b7f7701b337649cb8eb4c54913
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Diffstat (limited to 'tools')
5 files changed, 113 insertions, 70 deletions
diff --git a/tools/elog-gen.py b/tools/elog-gen.py index c72aa98..d10c026 100755 --- a/tools/elog-gen.py +++ b/tools/elog-gen.py @@ -1,7 +1,7 @@ #!/usr/bin/env python r""" -This script will parse the input error log yaml file and generate +This script will parse error log yaml file(s) and generate a header file which will then be used by the error logging client and server to collect and validate the error information generated by the openbmc software components. @@ -9,7 +9,6 @@ openbmc software components. This code uses a mako template to provide the basic template of the header file we're going to generate. We then call it with information from the yaml to generate the header file. - """ from mako.template import Template @@ -19,6 +18,20 @@ import sys import os +def get_error_yaml_files(i_yaml_dir): + yaml_files = filter( + lambda file: file.endswith('.errors.yaml'), + os.listdir(i_yaml_dir)) + return yaml_files + + +def get_meta_yaml_file(i_error_yaml_file): + # the meta data will be defined in file name where we replace + # <Interface>.errors.yaml with <Interface>.metadata.yaml + meta_yaml = i_error_yaml_file.replace("errors", "metadata") + return meta_yaml + + def get_cpp_type(i_type): typeMap = { 'int16': 'int16_t', @@ -34,31 +47,83 @@ def get_cpp_type(i_type): return typeMap[i_type] -def gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml, - i_input_mako, i_output_hpp): +def gen_elog_hpp(i_yaml_dir, i_output_hpp, + i_template_dir, i_elog_mako, i_error_namespace): r""" - Read the input yaml file, grab the relevant data and call the mako - template to generate the header file. + Read yaml file(s) under input yaml dir, grab the relevant data and call + the mako template to generate the output header file. Description of arguments: - i_rootdir base directory to search for yaml files - i_elog_yaml yaml file describing the error logs - i_elog_meta_yaml yaml file describing the meta data for elogs - i_input_mako input mako template file to use - i_output_hpp header file to output the generated code to + i_yaml_dir directory containing error yaml files + i_output_hpp name of the to be generated output hpp + i_template_dir directory containing error mako templates + i_elog_mako error mako template to render """ # Input parameters to mako template - errors = dict() # Main error codes + errors = list() # Main error codes error_msg = dict() # Error msg that corresponds to error code error_lvl = dict() # Error code log level (debug, info, error, ...) meta = list() # The meta data names associated (ERRNO, FILE_NAME, ...) meta_data = dict() # The meta data info (type, format) - # see elog.yaml for reference - ifile = yaml.safe_load(open("/".join((i_rootdir, i_elog_yaml)))) + error_yamls = get_error_yaml_files(i_yaml_dir) + + for error_yaml in error_yamls: + # Verify the error yaml file + error_yaml = "/".join((i_yaml_dir, error_yaml)) + if (not (os.path.isfile(error_yaml))): + print "Can not find input yaml file " + error_yaml + exit(1) + + # Verify the metadata yaml file + meta_yaml = get_meta_yaml_file(error_yaml) + if (not (os.path.isfile(meta_yaml))): + print "Can not find meta yaml file " + meta_yaml + exit(1) + + # Verify the input mako file + template_path = "/".join((i_template_dir, i_elog_mako)) + if (not (os.path.isfile(template_path))): + print "Can not find input template file " + template_path + exit(1) + + get_elog_data(error_yaml, + meta_yaml, + # 3rd arg is a tuple + (errors, + error_msg, + error_lvl, + meta, + meta_data)) + + # Load the mako template and call it with the required data + yaml_dir = i_yaml_dir.strip("./") + yaml_dir = yaml_dir.strip("../") + template = Template(filename=template_path) + f = open(i_output_hpp, 'w') + f.write(template.render( + errors=errors, error_msg=error_msg, + error_lvl=error_lvl, meta=meta, + meta_data=meta_data, error_namespace=i_error_namespace)) + f.close() + + +def get_elog_data(i_elog_yaml, + i_elog_meta_yaml, + o_elog_data): + r""" + Parse the error and metadata yaml files in order to pull out + error metadata. + + Description of arguments: + i_elog_yaml error yaml file + i_elog_meta_yaml metadata yaml file + o_elog_data error metadata + """ + errors, error_msg, error_lvl, meta, meta_data = o_elog_data + ifile = yaml.safe_load(open(i_elog_yaml)) mfile = yaml.safe_load(open(i_elog_meta_yaml)) - err_count = 0 for i in ifile: match = None # Find the corresponding meta data for this entry @@ -70,7 +135,7 @@ def gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml, print "Error - Did not find meta data for " + i['name'] exit(1) # Grab the main error and it's info - errors[err_count] = i['name'] + errors.append(i['name']) error_msg[i['name']] = i['description'] error_lvl[i['name']] = match['level'] tmp_meta = [] @@ -83,7 +148,6 @@ def gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml, meta_data[str_short]['str_short'] = str_short meta_data[str_short]['type'] = get_cpp_type(j['type']) meta.append(tmp_meta) - err_count += 1 # Debug # for i in errors: @@ -93,22 +157,10 @@ def gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml, # print " META: " # print meta[i] - # Load the mako template and call it with the required data - mytemplate = Template(filename=i_input_mako) - f = open(i_output_hpp, 'w') - f.write(mytemplate.render(errors=errors, error_msg=error_msg, - error_lvl=error_lvl, meta=meta, - meta_data=meta_data, elog_yaml=i_elog_yaml)) - f.close() - def main(i_args): parser = OptionParser() - parser.add_option("-e", "--elog", dest="elog_yaml", - default="xyz/openbmc_project/Example/Elog.errors.yaml", - help="input error yaml file to parse") - parser.add_option("-m", "--mako", dest="elog_mako", default="elog-gen-template.mako.hpp", help="input mako template file to use") @@ -117,41 +169,25 @@ def main(i_args): default="elog-gen.hpp", help="output hpp to generate, elog-gen.hpp is default") - parser.add_option("-r", "--rootdir", dest="rootdir", - default="example", + parser.add_option("-y", "--yamldir", dest="yamldir", + default="./example/xyz/openbmc_project/Example", help="Base directory of yaml files to process") parser.add_option("-t", "--templatedir", dest="templatedir", default="phosphor-logging/templates/", help="Base directory of files to process") - (options, args) = parser.parse_args(i_args) + parser.add_option("-n", "--namespace", dest="error_namespace", + default="example/xyz/openbmc_project/Example", + help="Error d-bus namespace") - # Verify the input yaml file - yaml_path = "/".join((options.rootdir, options.elog_yaml)) - if (not (os.path.isfile(yaml_path))): - print "Can not find input yaml file " + yaml_path - exit(1) + (options, args) = parser.parse_args(i_args) - # the meta data will be defined in a similar file name where we replace - # <Interface>.errors.yaml with <Interface>.metadata.yaml - meta_file = options.elog_yaml.replace("errors", "metadata") - meta_file = "/".join((options.rootdir, meta_file)) - if (not (os.path.isfile(meta_file))): - print "Can not find meta yaml file " + meta_file - exit(1) - - # Verify the input mako file - template_path = "/".join((options.templatedir, options.elog_mako)) - if (not (os.path.isfile(template_path))): - print "Can not find input template file " + template_path - exit(1) - - gen_elog_hpp(options.rootdir, - options.elog_yaml, - meta_file, - template_path, - options.output_hpp) + gen_elog_hpp(options.yamldir, + options.output_hpp, + options.templatedir, + options.elog_mako, + options.error_namespace) # Only run if it's a script if __name__ == '__main__': diff --git a/tools/example/xyz/openbmc_project/Example/Foo.errors.yaml b/tools/example/xyz/openbmc_project/Example/Foo.errors.yaml new file mode 100644 index 0000000..73fe62b --- /dev/null +++ b/tools/example/xyz/openbmc_project/Example/Foo.errors.yaml @@ -0,0 +1,2 @@ +- name: Foo + description: this is test error Foo diff --git a/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml b/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml new file mode 100644 index 0000000..2ac0532 --- /dev/null +++ b/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml @@ -0,0 +1,5 @@ +- name: Foo + level: INFO + meta: + - str: "FOO_DATA=%s" + type: string diff --git a/tools/phosphor-logging/templates/elog-gen-template.mako.hpp b/tools/phosphor-logging/templates/elog-gen-template.mako.hpp index 5c11c1b..1ff9150 100644 --- a/tools/phosphor-logging/templates/elog-gen-template.mako.hpp +++ b/tools/phosphor-logging/templates/elog-gen-template.mako.hpp @@ -15,21 +15,22 @@ namespace phosphor namespace logging { - % for a in errors: + % for index, name in enumerate(errors): <% - namespaces = elog_yaml.split('/') - namespaces.pop() - classname = errors[a] + namespaces = error_namespace.split('/') + ## In case someone provided a error_namespace ending with '/', remove the + ## last split string, which would be an empty string. + if not namespaces[-1]: + namespaces = namespaces[:-1] + classname = name %>\ % for s in namespaces: namespace ${s} { % endfor -namespace Error -{ namespace _${classname} { - % for b in meta[a]: + % for b in meta[index]: struct ${b} { static constexpr auto str = "${meta_data[b]['str']}"; @@ -41,18 +42,17 @@ struct ${b} % endfor } // namespace _${classname} -<% meta_string = ', '.join(meta[a]) %> +<% meta_string = ', '.join(meta[index]) %> struct ${classname} { - static constexpr auto err_code = "${errors[a]}"; - static constexpr auto err_msg = "${error_msg[errors[a]]}"; - static constexpr auto L = level::${error_lvl[errors[a]]}; - % for b in meta[a]: + static constexpr auto err_code = "${name}"; + static constexpr auto err_msg = "${error_msg[name]}"; + static constexpr auto L = level::${error_lvl[name]}; + % for b in meta[index]: using ${b} = _${classname}::${b}; % endfor using metadata_types = std::tuple<${meta_string}>; }; -} // namespace Error % for s in reversed(namespaces): } // namespace ${s} % endfor diff --git a/tools/phosphor-logging/templates/elog-lookup-template.mako.cpp b/tools/phosphor-logging/templates/elog-lookup-template.mako.cpp index a96760e..be4ff96 100644 --- a/tools/phosphor-logging/templates/elog-lookup-template.mako.cpp +++ b/tools/phosphor-logging/templates/elog-lookup-template.mako.cpp @@ -16,7 +16,7 @@ namespace logging std::map<std::string,std::vector<std::string>> g_errMetaMap = { % for a in errors: <% meta_string = '\",\"'.join(meta[a]) %> \ - {"${errors[a]}",{"${meta_string}"}}, + {"${a}",{"${meta_string}"}}, % endfor }; |