summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--elog-gen-template.mako.hpp48
-rw-r--r--elog-gen.hpp88
-rw-r--r--elog-gen.py96
-rw-r--r--elog.yaml23
-rwxr-xr-xelog_parser.py16
-rw-r--r--logging_test.cpp56
6 files changed, 254 insertions, 73 deletions
diff --git a/elog-gen-template.mako.hpp b/elog-gen-template.mako.hpp
new file mode 100644
index 0000000..8461f70
--- /dev/null
+++ b/elog-gen-template.mako.hpp
@@ -0,0 +1,48 @@
+## Note that this file is not auto generated, it is what generates the
+## elog-gen.hpp file
+// This file was autogenerated. Do not edit!
+// See elog-gen.py for more details
+#pragma once
+
+#include <tuple>
+#include <type_traits>
+#include "log.hpp"
+
+namespace phosphor
+{
+
+namespace logging
+{
+
+ % for a in errors:
+namespace _${errors[a]}
+{
+ % for b in meta[a]:
+struct ${b}
+{
+ static constexpr auto str = "${meta_data[b]['str']}";
+ static constexpr auto str_short = "${meta_data[b]['str_short']}";
+ using type = std::tuple<std::decay_t<decltype(str)>,${meta_data[b]['type']}>;
+ explicit constexpr ${b}(${meta_data[b]['type']} a) : _entry(entry(str, a)) {};
+ type _entry;
+};
+ % endfor
+
+} // namespace _${errors[a]}
+<% meta_string = ', '.join(meta[a]) %>
+struct ${errors[a]}
+{
+ static constexpr auto err_code = "xyz.openbmc_project.logging.${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]:
+ using ${b} = _${errors[a]}::${b};
+ % endfor
+ using metadata_types = std::tuple<${meta_string}>;
+};
+
+ % endfor
+
+} // namespace logging
+
+} // namespace phosphor
diff --git a/elog-gen.hpp b/elog-gen.hpp
index 3aba8fb..07d0757 100644
--- a/elog-gen.hpp
+++ b/elog-gen.hpp
@@ -1,4 +1,5 @@
-// this file was autogenerated. do not edit.
+// This file was autogenerated. Do not edit!
+// See elog-gen.py for more details
#pragma once
#include <tuple>
@@ -11,52 +12,87 @@ namespace phosphor
namespace logging
{
-namespace _file_not_found
+namespace _GETSCOM
{
-struct errnum
+struct DEV_ADDR
{
- static constexpr auto str = "ERRNO=%d";
- static constexpr auto str_short = "ERRNO";
+ static constexpr auto str = "DEV_ADDR=0x%.8X";
+ static constexpr auto str_short = "DEV_ADDR";
using type = std::tuple<std::decay_t<decltype(str)>,int>;
- explicit constexpr errnum(int a) : _entry(entry(str, a)) {};
+ explicit constexpr DEV_ADDR(int a) : _entry(entry(str, a)) {};
type _entry;
};
+struct DEV_ID
+{
+ static constexpr auto str = "DEV_ID=%u";
+ static constexpr auto str_short = "DEV_ID";
+ using type = std::tuple<std::decay_t<decltype(str)>,int>;
+ explicit constexpr DEV_ID(int a) : _entry(entry(str, a)) {};
+ type _entry;
+};
+struct DEV_NAME
+{
+ static constexpr auto str = "DEV_NAME=%s";
+ static constexpr auto str_short = "DEV_NAME";
+ using type = std::tuple<std::decay_t<decltype(str)>,const char *>;
+ explicit constexpr DEV_NAME(const char * a) : _entry(entry(str, a)) {};
+ type _entry;
+};
+
+} // namespace _GETSCOM
+
+struct GETSCOM
+{
+ static constexpr auto err_code = "xyz.openbmc_project.logging.GETSCOM";
+ static constexpr auto err_msg = "Getscom call failed";
+ static constexpr auto L = level::ERR;
+ using DEV_ADDR = _GETSCOM::DEV_ADDR;
+ using DEV_ID = _GETSCOM::DEV_ID;
+ using DEV_NAME = _GETSCOM::DEV_NAME;
+ using metadata_types = std::tuple<DEV_ADDR, DEV_ID, DEV_NAME>;
+};
-struct file_path
+namespace _FILE_NOT_FOUND
+{
+struct ERRNUM
+{
+ static constexpr auto str = "ERRNUM=0x%.4X";
+ static constexpr auto str_short = "ERRNUM";
+ using type = std::tuple<std::decay_t<decltype(str)>,int>;
+ explicit constexpr ERRNUM(int a) : _entry(entry(str, a)) {};
+ type _entry;
+};
+struct FILE_PATH
{
static constexpr auto str = "FILE_PATH=%s";
static constexpr auto str_short = "FILE_PATH";
- using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
- explicit constexpr file_path(const char *a) : _entry(entry(str,a)) {};
+ using type = std::tuple<std::decay_t<decltype(str)>,const char *>;
+ explicit constexpr FILE_PATH(const char * a) : _entry(entry(str, a)) {};
type _entry;
};
-
-struct file_name
+struct FILE_NAME
{
- static constexpr auto str = "FILE_NAME=%s";
- static constexpr auto str_short = "FILE_NAME";
- using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
- explicit constexpr file_name(const char *a) : _entry(entry(str,a)) {};
- type _entry;
+ static constexpr auto str = "FILE_NAME=%s";
+ static constexpr auto str_short = "FILE_NAME";
+ using type = std::tuple<std::decay_t<decltype(str)>,const char *>;
+ explicit constexpr FILE_NAME(const char * a) : _entry(entry(str, a)) {};
+ type _entry;
};
-} // namespace _file_not_found
+} // namespace _FILE_NOT_FOUND
-struct file_not_found
+struct FILE_NOT_FOUND
{
- static constexpr auto err_code = "xyz.openbmc_project.logging.FILE_NOT_FOUND_ERROR";
+ static constexpr auto err_code = "xyz.openbmc_project.logging.FILE_NOT_FOUND";
static constexpr auto err_msg = "A required file was not found";
static constexpr auto L = level::INFO;
-
- using errnum = _file_not_found::errnum;
- using file_path = _file_not_found::file_path;
- using file_name = _file_not_found::file_name;
-
- using metadata_types = std::tuple<errnum, file_path, file_name>;
+ using ERRNUM = _FILE_NOT_FOUND::ERRNUM;
+ using FILE_PATH = _FILE_NOT_FOUND::FILE_PATH;
+ using FILE_NAME = _FILE_NOT_FOUND::FILE_NAME;
+ using metadata_types = std::tuple<ERRNUM, FILE_PATH, FILE_NAME>;
};
-
} // namespace logging
} // namespace phosphor
diff --git a/elog-gen.py b/elog-gen.py
new file mode 100644
index 0000000..61cceac
--- /dev/null
+++ b/elog-gen.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+r"""
+This script will parse the input error log yaml file 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.
+
+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
+from optparse import OptionParser
+import yaml
+import sys
+import os
+
+def gen_elog_hpp(i_elog_yaml, i_output_hpp):
+ r"""
+ Read the input yaml file, grab the relevant data and call the mako
+ template to generate the header file.
+
+ Description of arguments:
+ i_elog_yaml yaml file describing the error logs
+ i_output_hpp header file to output the generated code to
+ """
+
+ # Input parameters to mako template
+ errors = dict() # 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(i_elog_yaml))
+ err_count = 0;
+ for i in ifile['SW'].keys():
+ # Grab the main error
+ errors[err_count] = i
+ # Grab it's sub-items
+ prop = ifile['SW'][i]
+ error_msg[i] = prop['msg']
+ error_lvl[i] = prop['level']
+ tmp_meta=[]
+ # grab all the meta data fields and info
+ for j in prop['meta']:
+ str_short = j['str'].split('=')[0]
+ tmp_meta.append(str_short)
+ meta_data[str_short] = {}
+ meta_data[str_short]['str'] = j['str']
+ meta_data[str_short]['str_short'] = str_short
+ meta_data[str_short]['type'] = j['type']
+ meta.append(tmp_meta)
+ err_count+=1
+
+ # Debug
+ #for i in errors:
+ # print "ERROR: " + errors[i]
+ # print " MSG: " + error_msg[errors[i]]
+ # print " LVL: " + error_lvl[errors[i]]
+ # print " META: "
+ # print meta[i]
+
+ # Load the mako template and call it with the required data
+ mytemplate = Template(filename='elog-gen-template.mako.hpp')
+ 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))
+ f.close()
+
+
+def main(i_args):
+ parser = OptionParser()
+
+ parser.add_option("-e","--elog",dest="elog_yaml",default="elog.yaml",
+ help="input error yaml file to parse");
+
+ parser.add_option("-o","--output",dest="output_hpp", default="elog-gen.hpp",
+ help="output hpp to generate, elog-gen.hpp is default");
+
+ (options, args) = parser.parse_args(i_args)
+
+ if (not (os.path.isfile(options.elog_yaml))):
+ print "Can not find input yaml file " + options.elog_yaml
+ exit(1);
+
+ gen_elog_hpp(options.elog_yaml,options.output_hpp)
+
+# Only run if it's a script
+if __name__ == '__main__':
+ main(sys.argv[1:]) \ No newline at end of file
diff --git a/elog.yaml b/elog.yaml
index 79307a3..0dd21e3 100644
--- a/elog.yaml
+++ b/elog.yaml
@@ -1,13 +1,22 @@
---
SW:
- FILE_NOT_FOUND_ERROR:
+ FILE_NOT_FOUND:
msg: "A required file was not found"
level: INFO
- meta_i: [ ERRNUM ]
- meta_s: [ FILE_PATH, FILE_NAME ]
- GETSCOM_ERROR:
+ meta:
+ - str: "ERRNUM=0x%.4X"
+ type: int
+ - str: FILE_PATH=%s
+ type: const char*
+ - str: FILE_NAME=%s
+ type: const char*
+ GETSCOM:
msg: "Getscom call failed"
level: ERR
- meta_i: [ DEV_ADDR,
- DEV_ID ]
- meta_s: [ DEV_NAME ]
+ meta:
+ - str: DEV_ADDR=0x%.8X
+ type: int
+ - str: DEV_ID=%u
+ type: int
+ - str: DEV_NAME=%s
+ type: const char* \ No newline at end of file
diff --git a/elog_parser.py b/elog_parser.py
deleted file mode 100755
index 4896700..0000000
--- a/elog_parser.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/python -u
-
-import uuid
-import yaml
-
-with open('elog.yaml') as f:
- ifile = yaml.safe_load(f)
-
-with open('elog-gen.hpp', 'w') as ofile:
- ofile.write('namespace phosphor\n{\n\n')
- ofile.write('namespace logging\n{\n\n')
-
- # TBD
-
-if __name__ == '__main__':
- print "TODO\n"
diff --git a/logging_test.cpp b/logging_test.cpp
index 9a638c3..c5f622c 100644
--- a/logging_test.cpp
+++ b/logging_test.cpp
@@ -1,9 +1,11 @@
// A basic unit test that runs on a BMC (qemu or hardware)
#include <iostream>
-#include <elog.hpp>
-#include <log.hpp>
#include <systemd/sd-journal.h>
+#include <sstream>
+#include "elog.hpp"
+#include "log.hpp"
+#include "elog-gen.hpp"
using namespace phosphor;
using namespace logging;
@@ -44,7 +46,8 @@ int validate_journal(const char *i_entry, const char *i_value)
rc = (validated) ? 0 : 1;
if(rc)
{
- std::cerr << "Failed to find " << i_entry << " in journal!" << "\n";
+ std::cerr << "Failed to find " << i_entry << " with value " << i_value
+ <<" in journal!" << "\n";
}
return rc;
@@ -72,56 +75,61 @@ int main()
const char *test_string = "/tmp/test_string/";
try
{
- elog<file_not_found>(file_not_found::errnum(number),
- file_not_found::file_path(test_string),
- file_not_found::file_name("elog_test_3.txt"));
+ elog<FILE_NOT_FOUND>(FILE_NOT_FOUND::ERRNUM(number),
+ FILE_NOT_FOUND::FILE_PATH(test_string),
+ FILE_NOT_FOUND::FILE_NAME("elog_test_3.txt"));
}
- catch (elogException<file_not_found>& e)
+ catch (elogException<FILE_NOT_FOUND>& e)
{
std::cout << "elog exception caught: " << e.what() << std::endl;
}
// Now read back and verify our data made it into the journal
- rc = validate_journal(file_not_found::errnum::str_short,
- std::to_string(number).c_str());
+ std::stringstream stream;
+ stream << std::hex << number;
+ rc = validate_journal(FILE_NOT_FOUND::ERRNUM::str_short,
+ std::string(stream.str()).c_str());
if(rc)
return(rc);
- rc = validate_journal(file_not_found::file_path::str_short,
+ rc = validate_journal(FILE_NOT_FOUND::FILE_PATH::str_short,
test_string);
if(rc)
return(rc);
- rc = validate_journal(file_not_found::file_name::str_short,
+ rc = validate_journal(FILE_NOT_FOUND::FILE_NAME::str_short,
"elog_test_3.txt");
if(rc)
return(rc);
// TEST 4 - Create error log with previous entry use
- number = 0xFEDC;
+ number = 0x9876;
try
{
- elog<file_not_found>(file_not_found::errnum(number),
- prev_entry<file_not_found::file_path>(),
- file_not_found::file_name("elog_test_4.txt"));
+ elog<FILE_NOT_FOUND>(FILE_NOT_FOUND::ERRNUM(number),
+ prev_entry<FILE_NOT_FOUND::FILE_PATH>(),
+ FILE_NOT_FOUND::FILE_NAME("elog_test_4.txt"));
}
catch (elogExceptionBase& e)
{
std::cout << "elog exception caught: " << e.what() << std::endl;
}
+
// Now read back and verify our data made it into the journal
- rc = validate_journal(file_not_found::errnum::str_short,
- std::to_string(number).c_str());
+ stream.str("");
+ stream << std::hex << number;
+ rc = validate_journal(FILE_NOT_FOUND::ERRNUM::str_short,
+ std::string(stream.str()).c_str());
if(rc)
return(rc);
// This should just be equal to what we put in test 3
- rc = validate_journal(file_not_found::file_path::str_short,
+ rc = validate_journal(FILE_NOT_FOUND::FILE_PATH::str_short,
test_string);
if(rc)
return(rc);
- rc = validate_journal(file_not_found::file_name::str_short,
+ rc = validate_journal(FILE_NOT_FOUND::FILE_NAME::str_short,
"elog_test_4.txt");
if(rc)
return(rc);
@@ -129,13 +137,13 @@ int main()
// Compile fail tests
// Simple test to prove we fail to compile due to missing param
- //elog<file_not_found>(file_not_found::errnum(1),
- // file_not_found::file_path("test"));
+ //elog<FILE_NOT_FOUND>(FILE_NOT_FOUND::ERRNUM(1),
+ // FILE_NOT_FOUND::FILE_PATH("test"));
// Simple test to prove we fail to compile due to invalid param
- //elog<file_not_found>(file_not_found::errnum(1),
- // file_not_found::file_path("test"),
- // file_not_found::file_name(1));
+ //elog<FILE_NOT_FOUND>(FILE_NOT_FOUND::ERRNUM(1),
+ // FILE_NOT_FOUND::FILE_PATH("test"),
+ // FILE_NOT_FOUND::FILE_NAME(1));
return 0;
}
OpenPOWER on IntegriCloud