#!/usr/bin/env python3 # vim: wrapmargin=0 textwidth=0 smarttab expandtab tabstop=2 shiftwidth=2 """Produce a report on the provided EDDN Gateway log file's ERRORs.""" import argparse import fileinput import re import semantic_version def parse_cl_args() -> str: """ Check command-line arguments for input file name. :returns: str - input file name """ parser = argparse.ArgumentParser( prog='eddn-report-log-errors', description='Process an EDDN Gateway log file and report on any ERROR lines found' ) parser.add_argument( 'inputfile', metavar='<input file name>', help='Name of an EDDN Gateway log file' ) args = parser.parse_args() return args.inputfile def process_file(input_file: str) -> None: print(f'Input file: {input_file}') _RE_ERROR = re.compile( r'^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[\.,][0-9]{3} - ERROR - Gateway:[0-9]+:' r' (?P<err_msg>.+)' r' \((?P<request_size>[0-9]+),' r' "(?P<uploader_id>[^"]*)",' r' "(?P<software_name>[^"]*)",' r' "(?P<software_version>[^"]*)",' r' "(?P<schema_ref>[^"]*)",' r' "(?P<journal_event>[^"]*)"\)' r' from (?P<sender_ip>.+)$' ) # TODO: Make this handle gzipped files with fileinput.FileInput(files=(input_file), mode='r') as input: line = input.readline() while line: line = line.strip() matches = _RE_ERROR.search(line) if matches: # print(matches.group('err_msg')) # print(matches.group('request_size')) # print(matches.group('uploader_id')) # print(matches.group('software_name')) # print(matches.group('software_version')) # print(matches.group('schema_ref')) # print(matches.group('journal_event')) # print(matches.group('sender_ip')) # print('') software_version = semantic_version.Version.coerce(matches.group('software_version')) ################################################################### # Issues we know about and HAVE already alerted their # developers to. ################################################################### if matches.group('software_name') == 'EDDiscovery': # https://github.com/EDDiscovery/EDDiscovery/releases/latest if software_version >= semantic_version.Version.coerce('15.0.0.0'): if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/approachsettlement/1': if matches.group('err_msg') == 'Failed Validation "[<ValidationError: "\'Latitude\' is a required property">]"': # <https://github.com/EDDiscovery/EDDiscovery/issues/3236> pass elif matches.group('err_msg') == 'Failed Validation "[<ValidationError: "Additional properties are not allowed (\'Name_Localised\' was unexpected)">]"': # <https://github.com/EDDiscovery/EDDiscovery/issues/3237> pass else: print(line) else: print(line) elif software_version >= semantic_version.Version.coerce('12.1.7.0'): if matches.group('schema_ref') in ( 'https://eddn.edcd.io/schemas/shipyard/2', 'https://eddn.edcd.io/schemas/outfitting/2', ): # Reported via Discord PM to Robby 2022-01-07 if matches.group('err_msg') == 'Failed Validation "[<ValidationError: \'[] is too short\'>]"': pass else: print(line) else: print(line) elif matches.group('software_name') == 'EDDLite': # https://github.com/EDDiscovery/EDDLite/releases/tag/latest if software_version >= semantic_version.Version.coerce('2.0.0'): if matches.group('schema_ref') in ( 'https://eddn.edcd.io/schemas/shipyard/2', 'https://eddn.edcd.io/schemas/outfitting/2', ): # Failed Validation "[<ValidationError: "'2022-02-17T14.25.19Z' is not a 'date-time'">]" if ( matches.group('err_msg').startswith('Failed Validation "[<ValidationError: "') and matches.group('err_msg').endswith('\' is not a \'date-time\'">]"') ): # <https://github.com/EDDiscovery/EDDLite/issues/8> pass elif matches.group('err_msg') == 'Failed Validation "[<ValidationError: \'[] is too short\'>]"': # Reported via Discord PM to Robby 2022-01-07 pass else: print(line) else: print(line) elif matches.group('software_name') == 'EDDI': # https://github.com/EDCD/EDDI/releases/latest if software_version >= semantic_version.Version.coerce('4.0.1'): print(line) elif matches.group('software_name').startswith('E:D Market Connector'): # https://github.com/EDCD/EDMarketConnector/releases/latest if software_version >= semantic_version.Version.coerce('5.3.0'): if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/codexentry/1': # <https://github.com/EDCD/EDMarketConnector/issues/1393> if matches.group('err_msg') == 'Failed Validation "[<ValidationError: "\'\' is too short">]"': pass else: print(matches.group('err_msg')) print(line) elif matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/journal/1': # <https://github.com/EDCD/EDMarketConnector/issues/1403> if matches.group('err_msg') == 'Failed Validation "[<ValidationError: "\'SystemAddress\' is a required property">]"': # <https://github.com/EDCD/EDMarketConnector/issues/1403> pass elif matches.group('err_msg').startswith( 'Failed Validation "[<ValidationError: "{\'type\': [\'array\', \'boolean\', \'integer\', \'number\', \'null\', \'object\', \'string\']} is not allowed for' ): # <https://github.com/EDCD/EDMarketConnector/issues/1403> pass else: print(matches.group('err_msg')) print(line) elif matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/fssdiscoveryscan/1': if matches.group('err_msg') == 'Failed Validation "[<ValidationError: "None is not of type \'boolean\'">]"': # <https://github.com/EDCD/EDMarketConnector/issues/1403> pass else: print(line) elif matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/approachsettlement/1': if matches.group('err_msg') == 'Failed Validation "[<ValidationError: "\'Latitude\' is a required property">]"': # <https://github.com/EDCD/EDMarketConnector/issues/1476> pass else: print(line) else: print(line) elif matches.group('software_name') == 'Elite G19s Companion App': # <https://edcodex.info/?m=tools&entry=212> if software_version >= semantic_version.Version.coerce('3.7.7888.21039'): if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/commodity/3': if matches.group('err_msg') == 'Failed Validation "[<ValidationError: "Additional properties are not allowed (\'Proportion\', \'Name\' were unexpected)">]"': # Reported via Frontier forums: <https://forums.frontier.co.uk/threads/elite-g19s-companion-app-with-simulated-space-traffic-control.226782/post-9690204> pass else: print(line) else: print(line) elif matches.group('software_name') == 'EDSM': # It's in-browser, no public source/releases if software_version >= semantic_version.Version.coerce('1.0.3'): if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/journal/1': if matches.group('journal_event') == 'Scan': # <https://github.com/EDSM-NET/FrontEnd/issues/472> if matches.group('err_msg').startswith( 'Failed Validation "[<ValidationError: "None is not of type \'integer\'">]"' ): pass elif ( matches.group('err_msg').startswith('Failed Validation "[<ValidationError: "{') and matches.group('err_msg').endswith('} is not of type \'array\'">]"') ): # <https://github.com/EDSM-NET/FrontEnd/issues/473> pass else: print(matches.group('err_msg')) print(line) else: print(line) else: print(line) elif matches.group('software_name') == 'EDSM - Console': # It's in-browser, no public source/releases if software_version >= semantic_version.Version.coerce('1.0'): if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/journal/1': if matches.group('journal_event') == 'Scan': # <https://github.com/EDSM-NET/FrontEnd/issues/466> if not matches.group('err_msg').startswith( 'Failed Validation "[<ValidationError: "{\'type\': [\'array\', \'boolean\', \'integer\', \'number\', \'null\', \'object\', \'string\']} is not allowed for ' ): print(matches.group('err_msg')) print(line) else: print(line) else: print(line) elif matches.group('software_name') == 'EDAOS': # Apparently a Barry Carylon project, but no home page ? if software_version >= semantic_version.Version.coerce('1.2.3'): if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/journal/1': if matches.group('journal_event') == 'Docked': # <https://discord.com/channels/164411426939600896/205369618284544000/929102478954340372> if matches.group('err_msg').startswith( 'Failed Validation "[<ValidationError: "{\'type\': [\'array\', \'boolean\', \'integer\', \'number\', \'null\', \'object\', \'string\']} is not allowed for ' ): pass print(matches.group('err_msg')) print(line) else: print(line) else: print(line) elif matches.group('software_name') == 'EliteLogAgent': # <https://github.com/DarkWanderer/Elite-Log-Agent> if software_version >= semantic_version.Version.coerce('2.0.0.660'): print(line) # <https://edcodex.info/?m=tools&entry=440> # <https://bitbucket.org/JuustoKakku/moonlight/src/master/> elif matches.group('software_name') == 'Moonlight': if matches.group('software_version') == '1.3.4': if matches.group('schema_ref') == 'https://eddn.edcd.io/schemas/journal/1': if matches.group('journal_event') == 'Scan': # Ref: <https://bitbucket.org/JuustoKakku/moonlight/issues/5/bad-scan-events-being-sent-to-eddn> if not matches.group('err_msg').startswith( 'Failed Validation "[<ValidationError: "{\'type\': [\'array\', \'boolean\', \'integer\', \'number\', \'null\', \'object\', \'string\']} is not allowed for \'' ): print(matches.group('err_msg')) print(line) else: print(line) else: print(line) # Abandoned/unmaintained project # <https://forums.frontier.co.uk/threads/release-eva-elite-virtual-assistant-for-iphone-ipad-no-longer-working-jan-2020.245900/page-18> # <https://apps.apple.com/gb/app/eva/id1098763533> elif matches.group('software_name') in ('EVA [iPhone]', 'EVA [iPad]'): pass ################################################################### # Issues we know about, but haven't yet alerted developers to ################################################################### ################################################################### else: print(line) line = input.readline() if __name__ == "__main__": input_file = parse_cl_args() process_file(input_file)