1 | # lognestmonster Copyright (c) 2019 Joshua 'joshuas3' Stockin |
2 | # <https://github.com/JoshuaS3/lognestmonster/>. |
3 |
|
4 |
|
5 | # This file is part of lognestmonster. |
6 |
|
7 | # lognestmonster is free software: you can redistribute it and/or modify |
8 | # it under the terms of the GNU General Public License as published by |
9 | # the Free Software Foundation, either version 3 of the License, or |
10 | # (at your option) any later version. |
11 |
|
12 | # lognestmonster is distributed in the hope that it will be useful, |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | # GNU General Public License for more details. |
16 |
|
17 | # You should have received a copy of the GNU General Public License |
18 | # along with lognestmonster. If not, see <https://www.gnu.org/licenses/>. |
19 |
|
20 | import os |
21 | import sys |
22 | import time |
23 | import traceback |
24 | from utils import * |
25 | from format import * |
26 | from text import * |
27 | from args import * |
28 | from parseargs import * |
29 | from read import * |
30 | from tui import * |
31 |
|
32 | def output_exit(error=None): |
33 | exitcode = 0 |
34 | output(VERSION_SHORT) |
35 | if error is not None: # print argument error is exists |
36 | output(TEXT_RED, "error: ", RESET, error) |
37 | exitcode = 1 |
38 | output(HELP_MESSAGE) |
39 | exit(exitcode) |
40 |
|
41 | def main(): |
42 | options = parseargs(sys.argv[1:]) |
43 |
|
44 | display_help = "help" in options |
45 | display_version = "version" in options |
46 | is_status = "status" in options |
47 |
|
48 | filter_errors = "errors" in options |
49 | filter_warnings = "warnings" in options |
50 | filter_info = "info" in options |
51 | filter_debug = "debug" in options |
52 | filter_verbose = "verbose" in options |
53 | filter_veryverbose = "veryverbose" in options |
54 |
|
55 | filter_after = "after" in options |
56 | filter_before = "before" in options |
57 | filter_tag = "tag" in options |
58 |
|
59 | screen_size = term_size() |
60 | clines = screen_size[0] |
61 | ccols = screen_size[1] |
62 | if ccols > 80: ccols = 80 |
63 |
|
64 | if display_help: |
65 | output(VERSION_SHORT) |
66 |
|
67 | output("usage: lognestmonster ", USAGE_MESSAGE) |
68 |
|
69 | output() |
70 |
|
71 | for paragraph in COMMAND_INFO.split("\n\n"): |
72 | output_lines(wrap(paragraph, ccols)) |
73 |
|
74 | output() |
75 |
|
76 | args = [] |
77 |
|
78 | div1 = int(ccols/3) |
79 | div2 = int(ccols/3*2) |
80 | for arg in ARGUMENT_OPTIONS: |
81 | arg_lines = [] |
82 | indicators = wrap(", ".join(ARGUMENT_OPTIONS[arg]["indicators"]), div1) |
83 | description = wrap(ARGUMENT_OPTIONS[arg]["description"], div2) |
84 | l1 = indicators[0] |
85 | z = 0 |
86 | for line in description: |
87 | try: |
88 | l1 = indicators[z] |
89 | except: |
90 | l1 = "" |
91 | z += 1 |
92 | l = columnize([(div1, l1), (div2, line)], ccols) |
93 | arg_lines.append(l) |
94 | args += arg_lines |
95 |
|
96 | output_lines(args) |
97 | output() |
98 | output(DESCRIPTION_PYTHON_VERSION) |
99 | return |
100 | elif display_version: |
101 | output(VERSION_MESSAGE) |
102 | return |
103 | elif len(sys.argv) == 1 or type(options) is str: # argument error or no args passed |
104 | if type(options) is str: # print argument error is exists |
105 | output_exit(options) |
106 | else: |
107 | output_exit() |
108 |
|
109 | positional = sys.argv[-1] |
110 | if positional is not "-" and os.path.isfile(positional) is not True and os.path.isdir(positional) is not True: |
111 | output_exit("file unknown '" + positional + "'") |
112 |
|
113 | if positional is "-": positional = "stdin" |
114 |
|
115 | if positional is "stdin": |
116 | fd = sys.stdin |
117 | else: |
118 | try: |
119 | fd = open(positional, "rb", buffering=8192) |
120 | except: |
121 | output_exit("unable to open file '" + positional + "'") |
122 |
|
123 | if not is_status: |
124 | p = TUI() |
125 | p.folder_name = positional |
126 | p.loop() |
127 | else: |
128 | r = Reader(fd) |
129 |
|
130 | filter_verbosity_levels = [] |
131 | if filter_errors: |
132 | filter_verbosity_levels.append(5) |
133 | if filter_warnings: |
134 | filter_verbosity_levels.append(4) |
135 | if filter_info: |
136 | filter_verbosity_levels.append(0) |
137 | if filter_debug: |
138 | filter_verbosity_levels.append(1) |
139 | if filter_verbose: |
140 | filter_verbosity_levels.append(2) |
141 | if filter_veryverbose: |
142 | filter_verbosity_levels.append(3) |
143 | if filter_verbosity_levels != []: |
144 | r.filter_verbosity = filter_verbosity_levels |
145 | r.filters = True |
146 | else: |
147 | r.filter_verbosity = [0, 1, 2, 3, 4, 5] |
148 |
|
149 | if filter_after: |
150 | try: |
151 | r.filter_time_start = int(options["after"][0]) |
152 | r.filters = True |
153 | except: |
154 | output_exit("expected int for flag --after, got '" + options["after"][0] + "'") |
155 | if filter_before: |
156 | try: |
157 | r.filter_time_end = int(options["before"][0]) |
158 | r.filters = True |
159 | except: |
160 | output_exit("expected int for flag --before, got '" + options["before"][0] + "'") |
161 |
|
162 | if filter_tag: |
163 | r.filter_tag = str(options["tag"][0]) |
164 | r.filters = True |
165 | if positional is not "stdin": r.size() |
166 | else: r.seekable = False |
167 | s = time.time() |
168 | def update(): |
169 | if r.total_statements % 1000 == 0: # for every 1000 statements parsed |
170 | output("{0} statements | {1} events | {2} bad bytes | {3}%".format(r.statement_count, r.event_count, r.bad_bytes, round((r.position/r.file_size)*1000)/10), end="\r") |
171 | r.onupdate(update) |
172 | r.scan() |
173 | output("{0} statements | {1} events | {2} bad bytes | 100.0%".format(r.statement_count, r.event_count, r.bad_bytes)) |
174 | output("Stats:") |
175 | output(" File - ", positional) |
176 | output(" File size - ", bytecount_string(r.file_size)) |
177 | output(" Statements - {0}/{1}".format(r.statement_count, r.total_statements)) |
178 | output(" Events - {0}/{1}".format(r.event_count, r.total_events)) |
179 | elapsed = time.time() - s |
180 | if elapsed > 1: |
181 | output("Finished in {0} seconds ({1} statements per second)".format(elapsed, int(r.total_statements/elapsed))) |
182 |
|
183 | fd.close() |
184 |
|
185 |
|
186 | if __name__ == "__main__": |
187 | try: |
188 | main() |
189 | except Exception as e: |
190 | output(TEXT_RED, CONTRAST, "unhandled exception:", RESET) |
191 | output("-------------- EXCEPTION --------------") |
192 | output(traceback.format_exc()) |
193 | output("------------ EXCEPTION END ------------") |
194 | output("Please report this as an issue on GitHub:") |
195 | output("<", TEXT_YELLOW, "https://www.github.com/JoshuaS3/lognestmonster/issues/new", RESET, ">") |
196 | exit(1) |
197 |
|