1from __future__ import print_function 2import sys 3from io import StringIO 4from twisted.python import usage 5 6import foolscap 7from foolscap.logging.tail import TailOptions, LogTail 8from foolscap.logging.gatherer import \ 9 CreateGatherOptions, create_log_gatherer, \ 10 CreateIncidentGatherOptions, create_incident_gatherer 11from foolscap.logging.dumper import DumpOptions, LogDumper 12from foolscap.logging.web import WebViewerOptions, WebViewer 13from foolscap.logging.filter import FilterOptions, Filter 14from foolscap.logging.incident import ClassifyOptions, IncidentClassifier 15 16class Options(usage.Options): 17 synopsis = "Usage: flogtool (tail|create-gatherer|dump|filter|web-viewer)" 18 19 subCommands = [ 20 ("tail", None, TailOptions, "follow logs of the target node"), 21 ("create-gatherer", None, CreateGatherOptions, 22 "Make a .tac which will record all logs to a given directory"), 23 ("create-incident-gatherer", None, CreateIncidentGatherOptions, 24 "Make a .tac which will record all incidents to a given directory"), 25 ("dump", None, DumpOptions, 26 "dump the logs recorded by 'logtool gather'"), 27 ("filter", None, FilterOptions, 28 "produce a new file with a subset of the events from another file"), 29 ("web-viewer", None, WebViewerOptions, 30 "view the logs through a web page"), 31 ("classify-incident", None, ClassifyOptions, 32 "classify a stored Incident file"), 33 ] 34 35 def postOptions(self): 36 if not hasattr(self, 'subOptions'): 37 raise usage.UsageError("must specify a command") 38 39 def opt_help(self): 40 print(self.synopsis) 41 sys.exit(0) 42 43 def opt_version(self): 44 from twisted import copyright 45 print("Foolscap version:", foolscap.__version__) 46 print("Twisted version:", copyright.version) 47 sys.exit(0) 48 49 50def dispatch(command, options): 51 if command == "tail": 52 lt = LogTail(options) 53 return lt.run(options.target_furl) 54 55 elif command == "create-gatherer": 56 return create_log_gatherer(options) 57 58 elif command == "create-incident-gatherer": 59 return create_incident_gatherer(options) 60 61 elif command == "dump": 62 ld = LogDumper() 63 return ld.run(options) 64 65 elif command == "filter": 66 f = Filter() 67 return f.run(options) 68 69 elif command == "web-viewer": 70 wv = WebViewer() 71 return wv.run(options) 72 73 elif command == "classify-incident": 74 ic = IncidentClassifier() 75 return ic.run(options) 76 77 else: 78 print("unknown command '%s'" % command) 79 raise NotImplementedError 80 81def run_flogtool(argv=None, run_by_human=True): 82 if argv: 83 command_name = argv[0] 84 else: 85 command_name = sys.argv[0] 86 config = Options() 87 try: 88 config.parseOptions(argv) 89 except usage.error as e: 90 if not run_by_human: 91 raise 92 print("%s: %s" % (command_name, e)) 93 print() 94 c = getattr(config, 'subOptions', config) 95 print(str(c)) 96 sys.exit(1) 97 98 command = config.subCommand 99 so = config.subOptions 100 if not run_by_human: 101 so.stdout = StringIO() 102 so.stderr = StringIO() 103 rc = dispatch(command, so) 104 if rc is None: 105 rc = 0 106 if run_by_human: 107 sys.exit(rc) 108 else: 109 return (so.stdout.getvalue(), so.stderr.getvalue()) 110