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