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