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