forked from dodola/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
colorize_logs
executable file
·132 lines (106 loc) · 3.47 KB
/
colorize_logs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
# Copyright 2017 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
"""
This tool will color the lines from loglistener
Example usage #1:
# Colorize log lines, with all messages from the same thread in the same color
loglistener | scripts/colorize_logs -t
Example usage #2:
# Colorize log lines, with all messages from the same process in the same color
loglistener | scripts/colorize_logs
Example usage #3:
# Print the colorization of log.txt to stdout
# Identical to `scripts/colorize_logs < log.txt`
scripts/colorize_logs log.txt
Example usage #4:
# Colorize all ERROR and INFO lines in log.txt
scripts/colorize_logs -r ERROR -r INFO log.txt
Example usage #5:
# Colorize all lines with drv='<something>' in log.txt with distinct colors
# for each <something>
scripts/colorize_logs -r "drv='[^']*'" log.txt
"""
import argparse
import re
import sys
BASE_COLORS = [
#'\033[40m', # black
'\033[41m', # red
'\033[42m', # green
'\033[43m', # yellow
'\033[44m', # blue
'\033[45m', # magenta
'\033[46m', # cyan
#'\033[47m', # white
]
RESET_BG = '\033[49m'
class ColorAssigner(object):
def __init__(self, colors):
self.lru = list(colors)
self.task_colors = { }
def get_bg_color(self, task_id):
if task_id not in self.task_colors:
c = self.lru.pop(0)
self.task_colors[task_id] = c
else:
c = self.task_colors[task_id]
self.lru.remove(c)
self.lru.append(c)
return c
PROCESS_RE = r'^\[\d+\.\d+] (\d+)\.\d+> .*$'
THREAD_RE = r'^\[\d+\.\d+] (\d+\.\d+)> .*$'
def main():
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--process", "-p", dest="patterns", action="append_const",
const=PROCESS_RE, help="Color code by process (default)")
parser.add_argument("--thread", "-t", dest="patterns", action="append_const",
const=THREAD_RE, help="Color code by thread")
parser.add_argument("--regex", "-r", dest="patterns", action="append",
help="Color by matching regexp")
parser.add_argument("input", nargs='?', action="store", default=None,
help="The file to colorize. Defaults to stdin")
args = parser.parse_args()
if args.input:
f = open(args.input, 'r')
else:
f = sys.stdin
# If no patterns were specified, use the process pattern.
if not args.patterns:
args.patterns = [PROCESS_RE]
# Define the identifier extractor. It should be in group 1.
patterns = []
for pattern in args.patterns:
regex = re.compile(pattern)
if not regex.groups:
# if there's no group, wrap the pattern
regex = re.compile(r'^.*(' + pattern + r').*$')
patterns.append(regex)
assigner = ColorAssigner(BASE_COLORS);
while True:
line = f.readline()
if not line:
break
line = line.strip()
matched = False
for line_re in patterns:
m = line_re.match(line)
if m:
matched = True
task_id = m.group(1)
color = assigner.get_bg_color(task_id)
# Use join to avoid python putting a space between each value being
# printed.
print ''.join([color, line, RESET_BG])
sys.stdout.flush()
break
if not matched:
print line
sys.stdout.flush()
if __name__ == '__main__':
main()