summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBinh Le <lebinh.it@gmail.com>2014-03-29 11:44:29 +0700
committerBinh Le <lebinh.it@gmail.com>2014-03-29 11:44:29 +0700
commit773a0d6e5405e622f6329648ffbffe5546e5ab1b (patch)
tree467e511549234d5698e314baff759a99ce6c5fd2
parent08fdbc99bcb4185039915d46930ed16c04a5229b (diff)
Use curses instead of repeatedly clear terminal screen and switch to timer signal for periodically printing of report instead of threads.
-rwxr-xr-xngxtop/ngxtop.py50
1 files changed, 24 insertions, 26 deletions
diff --git a/ngxtop/ngxtop.py b/ngxtop/ngxtop.py
index 17af878..6b13679 100755
--- a/ngxtop/ngxtop.py
+++ b/ngxtop/ngxtop.py
@@ -53,15 +53,16 @@ Examples:
$ ngxtop avg bytes_sent --filter 'status == 200 and request_path.startswith("foo")'
"""
from __future__ import print_function
+import atexit
from contextlib import closing
+import curses
import logging
-import os
import re
import sqlite3
import subprocess
-import threading
import time
import sys
+import signal
try:
import urlparse
@@ -271,7 +272,7 @@ class SQLProcessor(object):
self.index_fields = index_fields if index_fields is not None else []
self.column_list = ','.join(fields)
self.holder_list = ','.join(':%s' % var for var in fields)
- self.conn = sqlite3.connect(':memory:', check_same_thread=False)
+ self.conn = sqlite3.connect(':memory:')
self.init_db()
def process(self, records):
@@ -280,7 +281,6 @@ class SQLProcessor(object):
with closing(self.conn.cursor()) as cursor:
for r in records:
cursor.execute(insert, r)
- return self.count()
def report(self):
if not self.begin:
@@ -331,9 +331,8 @@ def process_log(lines, pattern, processor, arguments):
if filter_exp:
records = (r for r in records if eval(filter_exp, {}, r))
- total = processor.process(records)
- print(processor.report())
- return total
+ processor.process(records)
+ print(processor.report()) # this will only run when start in --no-follow mode
def build_processor(arguments):
@@ -382,21 +381,25 @@ def build_source(access_log, arguments):
return lines
-def build_reporter(processor, arguments):
+def setup_reporter(processor, arguments):
if arguments['--no-follow']:
- return None
+ return
- def report(interval=float(arguments['--interval'])):
- os.system('cls' if os.name == 'nt' else 'clear')
- while True:
- time.sleep(interval)
- output = processor.report()
- os.system('cls' if os.name == 'nt' else 'clear')
- print(output)
+ scr = curses.initscr()
+ atexit.register(curses.endwin)
+
+ def print_report(sig, frame):
+ output = processor.report()
+ scr.erase()
+ try:
+ scr.addstr(output)
+ except curses.error:
+ pass
+ scr.refresh()
- thread = threading.Thread(target=report)
- thread.daemon = True
- return thread
+ signal.signal(signal.SIGALRM, print_report)
+ interval = float(arguments['--interval'])
+ signal.setitimer(signal.ITIMER_REAL, 0.1, interval)
def process(arguments):
@@ -419,16 +422,11 @@ def process(arguments):
print('available variables:\n ', ', '.join(sorted(extract_variables(log_format))))
return
- begin = time.time()
source = build_source(access_log, arguments)
pattern = build_pattern(log_format)
processor = build_processor(arguments)
- reporter = build_reporter(processor, arguments)
- if reporter is not None:
- reporter.start()
- total = process_log(source, pattern, processor, arguments)
- duration = time.time() - begin
- logging.info('Processed %d lines in %.3f seconds, %.2f lines/sec.', total, duration, total / duration)
+ setup_reporter(processor, arguments)
+ process_log(source, pattern, processor, arguments)
def main():