Jordan Halterman | c9ce09a | 2017-03-21 11:27:25 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Splits ONOS DEBUG logs by partition/session for debugging consistent primitives. |
| 3 | # When logs are split, this script will create a separate log file for each partition |
| 4 | # and each Atomix session, e.g. karaf.log.partition-1, karaf.log.session-10, etc. |
| 5 | # |
| 6 | # Usage: onos-split-logs [directory|file] |
| 7 | import sys, os, re |
| 8 | from os.path import isfile, isdir, dirname, basename |
| 9 | |
| 10 | path = sys.argv[1] |
| 11 | |
| 12 | INDENT = 25 |
| 13 | SEP = ' | ' |
Jordan Halterman | a2268ec | 2017-05-03 17:11:33 -0700 | [diff] [blame] | 14 | MAX_LINE_LENGTH = 500 |
Jordan Halterman | c9ce09a | 2017-03-21 11:27:25 -0700 | [diff] [blame] | 15 | |
| 16 | DOMAINS = ('com', 'org', 'net', 'io', 'us') |
| 17 | |
| 18 | def is_exception(line): |
| 19 | for domain in DOMAINS: |
| 20 | if line.startswith(domain + '.'): |
| 21 | return True |
| 22 | return line.strip().startswith('at ') |
| 23 | |
| 24 | def find_pattern(f, pattern): |
| 25 | values = set() |
| 26 | prog = re.compile(pattern) |
| 27 | for line in f: |
| 28 | match = prog.search(line) |
| 29 | if match: |
| 30 | values.add(match.group(1)) |
| 31 | f.seek(0) |
| 32 | return values |
| 33 | |
| 34 | def split_line(line): |
| 35 | if is_exception(line): |
| 36 | return line |
| 37 | split = line.split('|') |
| 38 | if len(split) > 5: |
| 39 | ts = split[0].strip() |
| 40 | cls = split[3].strip() |
| 41 | log = split[5].strip(' /') |
| 42 | tsbuf = ''.join([' ' for i in range(INDENT - len(ts))]) |
| 43 | clsbuf = ''.join([' ' for i in range(INDENT - len(cls))]) |
Jordan Halterman | a2268ec | 2017-05-03 17:11:33 -0700 | [diff] [blame] | 44 | data = ts + tsbuf + SEP + cls + clsbuf + SEP + log |
| 45 | return data[:MAX_LINE_LENGTH] + '...\n' if len(data) > MAX_LINE_LENGTH else data |
Jordan Halterman | c9ce09a | 2017-03-21 11:27:25 -0700 | [diff] [blame] | 46 | return '' |
| 47 | |
| 48 | def split_log(infile, matcher, filemaker, matchmaker): |
| 49 | for match in matcher(infile): |
| 50 | matchers = matchmaker(match) |
| 51 | with open(filemaker(match), 'w+') as outfile: |
| 52 | for line in infile: |
| 53 | for m in matchers: |
| 54 | if m(line): |
| 55 | outfile.write(split_line(line)) |
| 56 | break |
| 57 | infile.seek(0) |
| 58 | |
| 59 | def split_partitions(filepath, f): |
| 60 | split_log( |
| 61 | f, |
| 62 | lambda f: find_pattern(f, '9876-partition-([0-9]+)'), |
| 63 | lambda partition: filepath + '.partition-' + partition, |
| 64 | lambda partition: ( |
| 65 | lambda line: 'partition-' + partition in line, |
| 66 | is_exception)) |
| 67 | |
| 68 | def split_sessions(filepath, f): |
| 69 | split_log( |
| 70 | f, |
| 71 | lambda f: find_pattern(f, 'session=([0-9]+)'), |
| 72 | lambda session: filepath + '.session-' + session, |
| 73 | lambda session: ( |
| 74 | lambda line: ' ' + session + ' - ' in line, |
| 75 | lambda line: 'session=' + session in line, |
| 76 | is_exception)) |
| 77 | |
| 78 | def split_file(dirpath, filename): |
| 79 | filepath = dirpath + os.sep + filename |
| 80 | with open(filepath, 'r') as f: |
| 81 | split_partitions(filepath, f) |
| 82 | split_sessions(filepath, f) |
| 83 | |
| 84 | def split_files(path): |
| 85 | for (dirpath, dirnames, filenames) in os.walk(path): |
| 86 | for filename in filenames: |
| 87 | if '.log' in filename: |
| 88 | split_file(dirpath, filename) |
| 89 | |
| 90 | if __name__ == '__main__': |
| 91 | path = sys.argv[1] |
| 92 | if isfile(path): |
| 93 | split_file(dirname(path), basename(path)) |
| 94 | else: |
| 95 | split_files(path) |