Skip to content

Instantly share code, notes, and snippets.

@dejw
Created April 18, 2012 21:40
Show Gist options
  • Select an option

  • Save dejw/2416782 to your computer and use it in GitHub Desktop.

Select an option

Save dejw/2416782 to your computer and use it in GitHub Desktop.
Frog monitoring module
# -*- coding: utf-8 -*-
import threading, time
import tornado.ioloop
import tornado.web
from collections import deque
class MonitorHandler(tornado.web.RequestHandler):
def initialize(self, monitor):
self.monitor = monitor
def get(self):
self.write({
"endpoints" : [
{
"name" : name,
"endpoint" : end.get('endpoint'),
"averageCallTime" : self.monitor.average_call_time.get(name)
}
for name, end in self.monitor.endpoints.iteritems()
]
})
class BaseMonitor(object):
def __init__(self):
self.call_time_queues = {}
self.average_call_time = {}
def wrap_callable(self, name, callable_):
self.call_time_queues[name] = deque(maxlen=10)
def wrapper(*args, **kwargs):
try:
start = time.time()
return callable_(*args, **kwargs)
finally:
end = time.time()
queue = self.call_time_queues[name]
queue.append(end - start)
self.average_call_time[name] = sum(queue) / float(len(queue))
return wrapper
def start(self, **kwargs):
for name, endpoint in self.endpoints.iteritems():
owner = module = __import__(endpoint['module_name'], fromlist=[endpoint['object_name']])
object_ = callable_ = getattr(module, endpoint['object_name'])
callable_name = endpoint['object_name']
if endpoint['attribute_name']:
owner = object_
callable_ = getattr(object_, endpoint['attribute_name'])
callable_name = endpoint['attribute_name']
wrapped_callable = self.wrap_callable(name, callable_)
setattr(owner, callable_name, wrapped_callable)
self.application = application = tornado.web.Application([
(r"/%s" % self.__class__.__name__, MonitorHandler, {'monitor' : self}),
], debug=True)
self.application.listen(port=int(self.port), address=self.host)
print "starting monitor at", self.host, self.port
t = threading.Thread(target=tornado.ioloop.IOLoop.instance().start)
t.daemon = True
t.start()
print "daemon started"
class FrogBuilder(object):
def __init__(self, name):
self.name = name
self.host = "localhost"
self.port = 9000
self.endpoints = {}
def listen(self, host, port=None):
self.host = host
self.port = port or self.port
return self
def register(self, endpoint, named=None, measure=None):
"""
endpoint module(.module)?.object(/attribute)?
"""
raw_endpoint = endpoint
named = named or endpoint
endpoint, _, attribute_name = endpoint.partition("/")
module_name, _, object_name = endpoint.rpartition(".")
# Try to import first?
#module = __import__(module_name, fromlist=[object_name])
self.endpoints[named] = {
"endpoint" : raw_endpoint,
"module_name" : module_name,
"object_name" : object_name,
"attribute_name" : attribute_name,
}
return self
def build(self):
return type(self.name, (BaseMonitor,), {
"host" : self.host,
"port" : self.port,
"endpoints" : self.endpoints,
})
webapp: python webapp_frog_config.py $PORT
# -*- coding: utf-8 -*-
import sys, time, random
import tornado.ioloop
import tornado.web
def some_time_consuming_function(amount):
time.sleep(amount)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world!")
some_time_consuming_function(random.random() * 3)
some_time_consuming_function(random.random())
self.write("Bye, world!")
application = tornado.web.Application([
(r"/", MainHandler),
], debug=True)
def run():
application.listen(int(sys.argv[1]))
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
run()
# -*- coding: utf-8 -*-
from frog import FrogBuilder
# 0.0.0.0:9000/webapp
WebappMonitor = (FrogBuilder("webapp")
.listen("0.0.0.0", 9000)
.register("webapp.MainHandler/get", named="index_page", measure=['call_time'])
.register("webapp.some_time_consuming_function")
.build())
if __name__ == "__main__":
# Niestety monitor trzeba wystartowac zanim zaimportuje sie moduly, do
# ktorych sie podlacza. W przeciwnym wypadku dekorowanie nie dziala
WebappMonitor().start()
from webapp import run
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment