blob: 273b0cc239fce74be15a0bdd445bc7f5f3003245 [file] [log] [blame]
Daniel Leunga5ab1a72021-04-02 12:54:53 -07001#!/usr/bin/env python3
2#
3# Copyright (c) 2021 Intel Corporation
4#
5# SPDX-License-Identifier: Apache-2.0
6
7"""
8Log Parser for Dictionary-based Logging
9
10This uses the JSON database file to decode the input binary
11log data and print the log messages.
12"""
13
14import argparse
15import binascii
16import logging
17import sys
18
David Leachf5b0f922021-06-23 15:18:22 -050019import dictionary_parser
20from dictionary_parser.log_database import LogDatabase
Daniel Leunga5ab1a72021-04-02 12:54:53 -070021
22
23LOGGER_FORMAT = "%(message)s"
24logger = logging.getLogger("parser")
25
26LOG_HEX_SEP = "##ZLOGV1##"
27
28
29def parse_args():
30 """Parse command line arguments"""
31 argparser = argparse.ArgumentParser()
32
33 argparser.add_argument("dbfile", help="Dictionary Logging Database file")
34 argparser.add_argument("logfile", help="Log Data file")
35 argparser.add_argument("--hex", action="store_true",
36 help="Log Data file is in hexadecimal strings")
37 argparser.add_argument("--rawhex", action="store_true",
38 help="Log file only contains hexadecimal log data")
39 argparser.add_argument("--debug", action="store_true",
40 help="Print extra debugging information")
41
42 return argparser.parse_args()
43
44
45def main():
46 """Main function of log parser"""
47 args = parse_args()
48
49 # Setup logging for parser
50 logging.basicConfig(format=LOGGER_FORMAT)
51 if args.debug:
52 logger.setLevel(logging.DEBUG)
53 else:
54 logger.setLevel(logging.INFO)
55
56 # Read from database file
57 database = LogDatabase.read_json_database(args.dbfile)
58 if database is None:
59 logger.error("ERROR: Cannot open database file: %s, exiting...", args.dbfile)
60 sys.exit(1)
61
62 # Open log data file for reading
63 if args.hex:
64 if args.rawhex:
65 # Simply log file with only hexadecimal data
David Leachf5b0f922021-06-23 15:18:22 -050066 logdata = dictionary_parser.utils.convert_hex_file_to_bin(args.logfile)
Daniel Leunga5ab1a72021-04-02 12:54:53 -070067 else:
68 hexdata = ''
69
70 with open(args.logfile, "r") as hexfile:
71 for line in hexfile.readlines():
72 hexdata += line.strip()
73
74 if LOG_HEX_SEP not in hexdata:
75 logger.error("ERROR: Cannot find start of log data, exiting...")
76 sys.exit(1)
77
78 idx = hexdata.index(LOG_HEX_SEP) + len(LOG_HEX_SEP)
79 hexdata = hexdata[idx:]
80
81 if len(hexdata) % 2 != 0:
82 # Make sure there are even number of characters
83 idx = int(len(hexdata) / 2) * 2
84 hexdata = hexdata[:idx]
85
86 idx = 0
87 while idx < len(hexdata):
88 # When running QEMU via west or ninja, there may be additional
89 # strings printed by QEMU, west or ninja (for example, QEMU
90 # is terminated, or user interrupted, etc). So we need to
91 # figure out where the end of log data stream by
92 # trying to convert from hex to bin.
93 idx += 2
94
95 try:
96 binascii.unhexlify(hexdata[:idx])
97 except binascii.Error:
98 idx -= 2
99 break
100
101 logdata = binascii.unhexlify(hexdata[:idx])
102 else:
103 logfile = open(args.logfile, "rb")
104 if not logfile:
105 logger.error("ERROR: Cannot open binary log data file: %s, exiting...", args.logfile)
106 sys.exit(1)
107
108 logdata = logfile.read()
109
110 logfile.close()
111
David Leachf5b0f922021-06-23 15:18:22 -0500112 log_parser = dictionary_parser.get_parser(database)
Daniel Leunga5ab1a72021-04-02 12:54:53 -0700113 if log_parser is not None:
114 logger.debug("# Build ID: %s", database.get_build_id())
115 logger.debug("# Target: %s, %d-bit", database.get_arch(), database.get_tgt_bits())
116 if database.is_tgt_little_endian():
117 logger.debug("# Endianness: Little")
118 else:
119 logger.debug("# Endianness: Big")
120
121 ret = log_parser.parse_log_data(logdata, debug=args.debug)
122 if not ret:
123 logger.error("ERROR: there were error(s) parsing log data")
124 sys.exit(1)
125 else:
126 logger.error("ERROR: Cannot find a suitable parser matching database version!")
127 sys.exit(1)
128
129
130if __name__ == "__main__":
131 main()