Created
April 18, 2012 21:40
-
-
Save dejw/2416782 to your computer and use it in GitHub Desktop.
Frog monitoring module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- 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, | |
| }) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| webapp: python webapp_frog_config.py $PORT |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- 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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- 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