1#!/usr/bin/env python3 2 3r""" 4BMC FFDC will at times include the journal in json format 5(journalctl -o json-pretty ). This is a quick and dirty script which 6will convert that json output into the standard journalctl output 7""" 8 9import datetime 10import json 11import re 12from argparse import ArgumentParser 13from datetime import timezone 14 15 16def jpretty_to_python(buf): 17 entries = [] 18 19 for entry in re.findall("^{$(.+?)^}$", buf, re.DOTALL | re.MULTILINE): 20 entries += [json.loads("{{{}}}".format(entry))] 21 22 return entries 23 24 25def format_timestamp_utc(us_timestamp, use_utc=False): 26 """Convert microseconds since epoch to formatted timestamp (with microseconds).""" 27 ts = float(us_timestamp) / 1000000 28 tz = timezone.utc if use_utc else None 29 dt = datetime.datetime.fromtimestamp(ts, tz) 30 return dt.strftime("%b %d %H:%M:%S.%f") 31 32 33if __name__ == "__main__": 34 parser = ArgumentParser() 35 parser.add_argument( 36 "journalfile", metavar="FILE", help="the file to parse" 37 ) 38 parser.add_argument( 39 "--localtime", 40 action="store_true", 41 help="Display timestamps in local time (default is UTC)", 42 ) 43 args = parser.parse_args() 44 45 with open(args.journalfile) as fd: 46 entries = jpretty_to_python(fd.read()) 47 entries = sorted(entries, key=lambda k: k["__REALTIME_TIMESTAMP"]) 48 49 for e in entries: 50 e["ts"] = format_timestamp_utc( 51 e["__REALTIME_TIMESTAMP"], use_utc=not args.localtime 52 ) 53 try: 54 print( 55 f'{e["ts"]} {e["_HOSTNAME"]} {e["SYSLOG_IDENTIFIER"]}:' 56 f' {e["MESSAGE"]}' 57 ) 58 except Exception: 59 print("Unable to parse msg: " + str(e)) 60 continue 61