1#!/usr/bin/env python3 2# 3# Copyright (c) 2021 Intel Corporation 4# Copyright (c) 2024 Nordic Semiconductor ASA 5# 6# SPDX-License-Identifier: Apache-2.0 7 8""" 9Log Parser for Dictionary-based Logging 10 11This uses the JSON database file to decode the input binary 12log data and print the log messages. 13""" 14 15import argparse 16import binascii 17import logging 18import sys 19 20import dictionary_parser 21import parserlib 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(allow_abbrev=False) 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 read_log_file(args): 46 """ 47 Read the log from file 48 """ 49 logdata = None 50 hexdata = '' 51 52 # Open log data file for reading 53 if args.hex: 54 if args.rawhex: 55 # Simply log file with only hexadecimal data 56 logdata = dictionary_parser.utils.convert_hex_file_to_bin(args.logfile) 57 else: 58 hexdata = '' 59 60 with open(args.logfile, "r", encoding="iso-8859-1") as hexfile: 61 for line in hexfile.readlines(): 62 hexdata += line.strip() 63 64 if LOG_HEX_SEP not in hexdata: 65 logger.error("ERROR: Cannot find start of log data, exiting...") 66 sys.exit(1) 67 68 idx = hexdata.index(LOG_HEX_SEP) + len(LOG_HEX_SEP) 69 hexdata = hexdata[idx:] 70 71 if len(hexdata) % 2 != 0: 72 # Make sure there are even number of characters 73 idx = int(len(hexdata) / 2) * 2 74 hexdata = hexdata[:idx] 75 76 idx = 0 77 while idx < len(hexdata): 78 # When running QEMU via west or ninja, there may be additional 79 # strings printed by QEMU, west or ninja (for example, QEMU 80 # is terminated, or user interrupted, etc). So we need to 81 # figure out where the end of log data stream by 82 # trying to convert from hex to bin. 83 idx += 2 84 85 try: 86 binascii.unhexlify(hexdata[:idx]) 87 except binascii.Error: 88 idx -= 2 89 break 90 91 logdata = binascii.unhexlify(hexdata[:idx]) 92 else: 93 logfile = open(args.logfile, "rb") 94 if not logfile: 95 logger.error("ERROR: Cannot open binary log data file: %s, exiting...", args.logfile) 96 sys.exit(1) 97 98 logdata = logfile.read() 99 100 logfile.close() 101 102 return logdata 103 104def main(): 105 """Main function of log parser""" 106 args = parse_args() 107 108 # Setup logging for parser 109 logging.basicConfig(format=LOGGER_FORMAT) 110 if args.debug: 111 logger.setLevel(logging.DEBUG) 112 else: 113 logger.setLevel(logging.INFO) 114 115 logdata = read_log_file(args) 116 if logdata is None: 117 logger.error("ERROR: cannot read log from file: %s, exiting...", args.logfile) 118 sys.exit(1) 119 120 parserlib.parser(logdata, args.dbfile, logger) 121 122if __name__ == "__main__": 123 main() 124