forked from StackStorm/st2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgelf-tail
executable file
·105 lines (83 loc) · 3.03 KB
/
gelf-tail
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
#!/usr/bin/env python
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Utility for tailing GELF formatted log files and pretty-printing the lines.
Based on https://github.com/racker/node-rackspace-shared-utils/blob/master/bin/gelf-tail
"""
import sys
import json
import datetime
from st2client.utils.color import DisplayColors
LEVEL_INT_TO_STRING_MAP = {
2: 'critical',
3: 'error',
4: 'warning',
6: 'info',
7: 'debug',
0: 'info'
}
def process_line(line):
try:
parsed = json.loads(line)
except ValueError:
# Invalid / non-json line
return
level = parsed['level']
dt = datetime.datetime.fromtimestamp(parsed['timestamp'])
timestamp = dt.strftime('%Y-%m-%d %H:%M:%S')
level_string = LEVEL_INT_TO_STRING_MAP.get(level, LEVEL_INT_TO_STRING_MAP[0])
timestamp = DisplayColors.colorize(timestamp, DisplayColors.GREEN)
if level < 4:
level = DisplayColors.colorize(level_string, DisplayColors.RED)
elif level < 6:
level = DisplayColors.colorize(level_string, DisplayColors.YELLOW)
elif level < 8:
level = DisplayColors.colorize(level_string, DisplayColors.GREEN)
short_message = parsed['short_message']
full_message = parsed['full_message']
if full_message:
if short_message in full_message:
message = full_message
else:
message = short_message + '\n' + full_message
else:
message = full_message
# Output main line
values = {'timestamp': timestamp, 'level': level, 'message': message}
print('%(timestamp)s [%(level)s]: %(message)s' % values)
# Output additional attributes
additional_attributes = dict([(k, v) for k, v in parsed.items() if k.startswith('_')])
if additional_attributes:
attributes = json.dumps(additional_attributes, indent=4, sort_keys=True)
print(attributes)
exception = parsed.get('_exception', None)
traceback = parsed.get('_traceback', None)
# Output exception (if any)
if exception:
if traceback:
print(traceback)
else:
print(exception)
def main():
line = sys.stdin.readline()
while line:
try:
process_line(line=line)
except Exception:
pass
line = sys.stdin.readline()
if __name__ == '__main__':
main()