1#!/usr/bin/env python
2
3r"""
4Provide useful error log utility keywords.
5"""
6
7import gen_print as gp
8import sys
9import os
10import imp
11base_path = os.path.dirname(os.path.dirname(
12                            imp.find_module("gen_robot_print")[1])) + os.sep
13sys.path.append(base_path + "data/")
14import variables as var
15from robot.libraries.BuiltIn import BuiltIn
16import gen_robot_utils as gru
17gru.my_import_resource("logging_utils.robot")
18
19
20def print_error_logs(error_logs, key_list=None):
21    r"""
22    Print the error logs to the console screen.
23
24    This function provides the following benefits:
25    - It will specify print_var parms for the caller (e.g. hex=1).
26    - It is much easier to call this function than to generate the desired code
27      directly from a robot script.
28
29    Description of argument(s):
30    error_logs                      An error log dictionary such as the one
31                                    returned by the 'Get Error Logs' keyword.
32    key_list                        The list of keys to be printed.  This may
33                                    be specified as either a python list
34                                    or a space-delimited string.  In the
35                                    latter case, this function will convert
36                                    it to a python list. See the sprint_varx
37                                    function prolog for additionatl details.
38
39    Example use from a python script:
40
41    ${error_logs}=  Get Error Logs
42    Print Error Logs  ${error_logs}  Message Timestamp
43
44    Sample output:
45
46    error_logs:
47      [/xyz/openbmc_project/logging/entry/3]:
48        [Timestamp]:                                  1521738335735
49        [Message]:
50        xyz.openbmc_project.Inventory.Error.Nonfunctional
51      [/xyz/openbmc_project/logging/entry/2]:
52        [Timestamp]:                                  1521738334637
53        [Message]:
54        xyz.openbmc_project.Inventory.Error.Nonfunctional
55      [/xyz/openbmc_project/logging/entry/1]:
56        [Timestamp]:                                  1521738300696
57        [Message]:
58        xyz.openbmc_project.Inventory.Error.Nonfunctional
59      [/xyz/openbmc_project/logging/entry/4]:
60        [Timestamp]:                                  1521738337915
61        [Message]:
62        xyz.openbmc_project.Inventory.Error.Nonfunctional
63
64    Another example call using a robot list:
65    ${error_logs}=  Get Error Logs
66    ${key_list}=  Create List  Message  Timestamp  Severity
67    Print Error Logs  ${error_logs}  ${key_list}
68    """
69
70    if key_list is not None:
71        try:
72            key_list = key_list.split(" ")
73        except AttributeError:
74            pass
75        key_list.insert(0, var.BMC_LOGGING_ENTRY + ".*")
76
77    gp.print_var(error_logs, hex=1, key_list=key_list)
78
79
80def get_esels(error_logs=None):
81    r"""
82    Get all available extended Service Event Logs (eSELs) and return as a list.
83
84    Example robot code:
85    ${esels}=  Get Esels
86    Rprint Vars  esels
87
88    Example output (excerpt):
89    esels:
90      esels[0]:                  ESEL=00 00 df 00 00...
91      esels[1]:                  ESEL=00 00 df 00 00...
92
93    Description of argument(s):
94    error_logs                      The error_log data, which can be obtained
95                                    from 'Get Error Logs'.  If this value is
96                                    None, then this function will call 'Get
97                                    Error Logs' on the caller's behalf.
98    """
99
100    if error_logs is None:
101        error_logs = BuiltIn().run_keyword('Get Error Logs')
102
103    # Look for any error log entries containing the 'AdditionalData' field
104    # which in turn has an entry starting with "ESEL=".  Here is an excerpt of
105    # the error_logs that contains such an entry.
106    # error_logs:
107    #   [/xyz/openbmc_project/logging/entry/1]:
108    #     [AdditionalData]:
109    #       [AdditionalData][0]:   CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/mot...
110    #       [AdditionalData][1]:   ESEL=00 00 df 00 00 00 00 20 00 04...
111    esels = []
112    for error_log in error_logs.values():
113        if 'AdditionalData' in error_log:
114            for additional_data in error_log['AdditionalData']:
115                if additional_data.startswith('ESEL='):
116                    esels.append(additional_data)
117
118    return esels
119