Skip to content

Instantly share code, notes, and snippets.

@grobertson
Created July 8, 2013 16:10
Show Gist options
  • Save grobertson/5950174 to your computer and use it in GitHub Desktop.
Save grobertson/5950174 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
from sys import stdin
from time import strptime
import re, shlex, subprocess, datetime
import curses
stdscr = curses.initscr()
curses.start_color()
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK)
def parse_line(line):
line = clean_logline(line)
line_halves = re.split('\]\: ', line)
line_meta = re.split(' ', line_halves[0])
parsed_data = dict()
parsed_data['timestamp'] = line_meta[0]
if line_meta.__len__() > 1:
try:
parsed_type = re.search('^([a-zA-Z]+)\[([a-zA-Z]+)', line_meta[1])
parsed_data['log_source'] = parsed_type.group(1)
parsed_data['log_type'] = parsed_type.group(2)
parsed_time = re.match('([\d][\d][\d][\d])\-([\d][\d])\-([\d][\d])T([\d][\d])\:([\d][\d])\:([\d][\d])', parsed_data['timestamp'])
year_int = int(parsed_time.group(1))
month_int = int(parsed_time.group(2))
day_int = int(parsed_time.group(3))
hour_int = int(parsed_time.group(4))
minute_int = int(parsed_time.group(5))
second_int = int(parsed_time.group(6))
parsed_data['log_time'] = datetime.datetime(year_int, month_int, day_int, hour_int, minute_int, second_int)
except:
print line
return False
else:
return False
if parsed_data['log_source'] == "heroku":
if line_halves.__len__() > 1:
line_halves[1] = re.sub(', ', ',', line_halves[1])
line_chunks = re.split(' ', line_halves[1])
for chunk in line_chunks:
line_chunks = re.split('=', chunk)
if line_chunks.__len__() > 2:
#fwd and path are a little clunky to parse
pass
elif line_chunks.__len__() > 1:
parsed_data[line_chunks[0]] = line_chunks[1]
pass
else:
pass
else:
return False
else:
# app (i.e. app[instance] or (async job output) app.*.*[guid] lines would need specific parsing and you'd do that somewhere around here.
return False
return parsed_data
def run_heroku(app_name):
command = '/usr/bin/heroku logs -t --app ' + app_name
args = shlex.split(command)
heroku = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(heroku.stdout.readline, b'')
def clean_logline(line):
line = re.sub('\n', '', line)
return line
#main loop
for line in run_heroku('dailydot'):
new_data = parse_line(line)
if not new_data:
pass
else:
if new_data['log_type'] == 'web':
#print new_data
pass
elif new_data['log_type'] == 'worker':
pass
elif new_data['log_type'] == 'router':
line_number = int(re.search('\.([\d]+)', new_data['dyno']).group(1))
stdscr.addstr(0,1,"Dyno\t\tService\t\tConnect\t\tStatus", curses.A_REVERSE)
if new_data['status'] == "503":
stdscr.addstr(line_number,1, new_data['dyno'] + "\t\t" + new_data['connect'] + "\t\t" + new_data['service'] + "\t\t" + new_data['status'], curses.color_pair(1))
else:
service = re.search('([\d]+)ms', new_data['service'])
service_time = int(service.group(1))
if service_time < 2000:
stdscr.addstr(line_number,1, new_data['dyno'] + "\t\t" + new_data['connect'] + "\t\t" + new_data['service'] + "\t\t" + new_data['status'], curses.color_pair(3))
else:
stdscr.addstr(line_number,1, new_data['dyno'] + "\t\t" + new_data['connect'] + "\t\t" + new_data['service'] + "\t\t" + new_data['status'], curses.color_pair(2))
stdscr.refresh()
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment