123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- #!/usr/bin/env python3
- #
- # Copyright (c) 2021 Intel Corporation
- #
- # SPDX-License-Identifier: Apache-2.0
- """
- Log Parser for Dictionary-based Logging
- This uses the JSON database file to decode the input binary
- log data and print the log messages.
- """
- import argparse
- import binascii
- import logging
- import sys
- import dictionary_parser
- from dictionary_parser.log_database import LogDatabase
- LOGGER_FORMAT = "%(message)s"
- logger = logging.getLogger("parser")
- LOG_HEX_SEP = "##ZLOGV1##"
- def parse_args():
- """Parse command line arguments"""
- argparser = argparse.ArgumentParser()
- argparser.add_argument("dbfile", help="Dictionary Logging Database file")
- argparser.add_argument("logfile", help="Log Data file")
- argparser.add_argument("--hex", action="store_true",
- help="Log Data file is in hexadecimal strings")
- argparser.add_argument("--rawhex", action="store_true",
- help="Log file only contains hexadecimal log data")
- argparser.add_argument("--debug", action="store_true",
- help="Print extra debugging information")
- return argparser.parse_args()
- def main():
- """Main function of log parser"""
- args = parse_args()
- # Setup logging for parser
- logging.basicConfig(format=LOGGER_FORMAT)
- if args.debug:
- logger.setLevel(logging.DEBUG)
- else:
- logger.setLevel(logging.INFO)
- # Read from database file
- database = LogDatabase.read_json_database(args.dbfile)
- if database is None:
- logger.error("ERROR: Cannot open database file: %s, exiting...", args.dbfile)
- sys.exit(1)
- # Open log data file for reading
- if args.hex:
- if args.rawhex:
- # Simply log file with only hexadecimal data
- logdata = dictionary_parser.utils.convert_hex_file_to_bin(args.logfile)
- else:
- hexdata = ''
- with open(args.logfile, "r") as hexfile:
- for line in hexfile.readlines():
- hexdata += line.strip()
- if LOG_HEX_SEP not in hexdata:
- logger.error("ERROR: Cannot find start of log data, exiting...")
- sys.exit(1)
- idx = hexdata.index(LOG_HEX_SEP) + len(LOG_HEX_SEP)
- hexdata = hexdata[idx:]
- if len(hexdata) % 2 != 0:
- # Make sure there are even number of characters
- idx = int(len(hexdata) / 2) * 2
- hexdata = hexdata[:idx]
- idx = 0
- while idx < len(hexdata):
- # When running QEMU via west or ninja, there may be additional
- # strings printed by QEMU, west or ninja (for example, QEMU
- # is terminated, or user interrupted, etc). So we need to
- # figure out where the end of log data stream by
- # trying to convert from hex to bin.
- idx += 2
- try:
- binascii.unhexlify(hexdata[:idx])
- except binascii.Error:
- idx -= 2
- break
- logdata = binascii.unhexlify(hexdata[:idx])
- else:
- logfile = open(args.logfile, "rb")
- if not logfile:
- logger.error("ERROR: Cannot open binary log data file: %s, exiting...", args.logfile)
- sys.exit(1)
- logdata = logfile.read()
- logfile.close()
- log_parser = dictionary_parser.get_parser(database)
- if log_parser is not None:
- logger.debug("# Build ID: %s", database.get_build_id())
- logger.debug("# Target: %s, %d-bit", database.get_arch(), database.get_tgt_bits())
- if database.is_tgt_little_endian():
- logger.debug("# Endianness: Little")
- else:
- logger.debug("# Endianness: Big")
- ret = log_parser.parse_log_data(logdata, debug=args.debug)
- if not ret:
- logger.error("ERROR: there were error(s) parsing log data")
- sys.exit(1)
- else:
- logger.error("ERROR: Cannot find a suitable parser matching database version!")
- sys.exit(1)
- if __name__ == "__main__":
- main()
|