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