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