def test_no_parallelism(self): step = 2 trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE, timedelta(seconds=0), max_parallelism=1, max_endpoint_errors=100) for i in xrange(step): trManager.append(SleepingTransaction(trManager, delay=1)) trManager.flush() # Flushes should be sequential for i in xrange(step): self.assertEqual(trManager._running_flushes, 1) self.assertEqual(trManager._finished_flushes, i) self.assertEqual(len(trManager._trs_to_flush), step - (i + 1)) time.sleep(1)
def test_drop_repeated_error(self): trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE, timedelta(seconds=0), max_endpoint_errors=1) # Fail it once oneTrSize = 10 trManager.append(memTransaction(oneTrSize, trManager)) # It should still be there after flush trManager.flush() self.assertEqual(len(trManager._transactions), 1) #Try again, now it should be gone trManager.flush() self.assertEqual(len(trManager._transactions), 0)
def testThrottling(self): """Test throttling while flushing""" # No throttling, no delay for replay trManager = TransactionManager(timedelta(seconds = 0), MAX_QUEUE_SIZE, THROTTLING_DELAY) trManager._flush_without_ioloop = True # Use blocking API to emulate tornado ioloop # Add 3 transactions, make sure no memory limit is in the way oneTrSize = MAX_QUEUE_SIZE / 10 for i in xrange(3): tr = memTransaction(oneTrSize, trManager) trManager.append(tr) # Try to flush them, time it before = datetime.now() trManager.flush() after = datetime.now() self.assertTrue( (after-before) > 3 * THROTTLING_DELAY)
def test_parallelism(self): step = 4 trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE, timedelta(seconds=0), max_parallelism=step, max_endpoint_errors=100) for i in xrange(step): trManager.append(SleepingTransaction(trManager)) trManager.flush() self.assertEqual(trManager._running_flushes, step) self.assertEqual(trManager._finished_flushes, 0) # If _trs_to_flush != None, it means that it's still running as it should be self.assertEqual(trManager._trs_to_flush, []) time.sleep(1) # It should be finished self.assertEqual(trManager._running_flushes, 0) self.assertEqual(trManager._finished_flushes, step) self.assertIs(trManager._trs_to_flush, None)
def test_endpoint_error(self): trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE, timedelta(seconds=0), max_endpoint_errors=2) step = 10 oneTrSize = (MAX_QUEUE_SIZE / step) - 1 for i in xrange(step): trManager.append(memTransaction(oneTrSize, trManager)) trManager.flush() # There should be exactly step transaction in the list, # and only 2 of them with a flush count of 1 self.assertEqual(len(trManager._transactions), step) flush_count = 0 for tr in trManager._transactions: flush_count += tr._flush_count self.assertEqual(flush_count, 2) # If we retry to flush, two OTHER transactions should be tried trManager.flush() self.assertEqual(len(trManager._transactions), step) flush_count = 0 for tr in trManager._transactions: flush_count += tr._flush_count self.assertIn(tr._flush_count, [0, 1]) self.assertEqual(flush_count, 4) # Finally when it's possible to flush, everything should go smoothly for tr in trManager._transactions: tr.is_flushable = True trManager.flush() self.assertEqual(len(trManager._transactions), 0)
def testMemoryLimit(self): """Test memory limit as well as simple flush""" # No throttling, no delay for replay trManager = TransactionManager(timedelta(seconds=0), MAX_QUEUE_SIZE, timedelta(seconds=0)) step = 10 oneTrSize = (MAX_QUEUE_SIZE / step) - 1 for i in xrange(step): tr = memTransaction(oneTrSize, trManager) trManager.append(tr) trManager.flush() # There should be exactly step transaction in the list, with # a flush count of 1 self.assertEqual(len(trManager._transactions), step) for tr in trManager._transactions: self.assertEqual(tr._flush_count, 1) # Try to add one more tr = memTransaction(oneTrSize + 10, trManager) trManager.append(tr) # At this point, transaction one (the oldest) should have been removed from the list self.assertEqual(len(trManager._transactions), step) for tr in trManager._transactions: self.assertNotEqual(tr._id, 1) trManager.flush() self.assertEqual(len(trManager._transactions), step) # Check and allow transactions to be flushed for tr in trManager._transactions: tr.is_flushable = True # Last transaction has been flushed only once if tr._id == step + 1: self.assertEqual(tr._flush_count, 1) else: self.assertEqual(tr._flush_count, 2) trManager.flush() self.assertEqual(len(trManager._transactions), 0)
class Application(tornado.web.Application): NO_PARALLELISM = 1 DEFAULT_PARALLELISM = 5 def __init__(self, port, agentConfig, watchdog=True, skip_ssl_validation=False, use_simple_http_client=False): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} self._dns_cache = None AgentTransaction.set_application(self) AgentTransaction.set_endpoints(agentConfig['endpoints']) if agentConfig['endpoints'] == {}: log.warning( u"No valid endpoint found. Forwarder will drop all incoming payloads." ) AgentTransaction.set_request_timeout(agentConfig['forwarder_timeout']) max_parallelism = self.NO_PARALLELISM # Multiple endpoints => enable parallelism if len(agentConfig['endpoints']) > 1: max_parallelism = self.DEFAULT_PARALLELISM self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY, max_parallelism=max_parallelism) AgentTransaction.set_tr_manager(self._tr_manager) self._watchdog = None self.skip_ssl_validation = skip_ssl_validation or _is_affirmative( agentConfig.get('skip_ssl_validation')) self.agent_dns_caching = _is_affirmative( agentConfig.get('dns_caching')) self.agent_dns_ttl = int(agentConfig.get('dns_ttl', DEFAULT_DNS_TTL)) if self.agent_dns_caching: self._dns_cache = DNSCache(ttl=self.agent_dns_ttl) self.use_simple_http_client = use_simple_http_client if self.skip_ssl_validation: log.info( "Skipping SSL hostname validation, useful when using a transparent proxy" ) # Monitor activity if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER / 1000 self._watchdog = Watchdog.create( watchdog_timeout, max_resets=WATCHDOG_HIGH_ACTIVITY_THRESHOLD) def get_from_dns_cache(self, url): if not self.agent_dns_caching: log.debug('Caching disabled, not resolving.') return url location = urlparse(url) resolve = self._dns_cache.resolve(location.netloc) return "{scheme}://{ip}".format(scheme=location.scheme, ip=resolve) def log_request(self, handler): """ Override the tornado logging method. If everything goes well, log level is DEBUG. Otherwise it's WARNING or ERROR depending on the response code. """ if handler.get_status() < 400: log_method = log.debug elif handler.get_status() < 500: log_method = log.warning else: log_method = log.error request_time = 1000.0 * handler.request.request_time() log_method(u"%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time) def appendMetric(self, prefix, name, host, device, ts, value): if prefix in self._metrics: metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if name in metrics: metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics['uuid'] = get_uuid() self._metrics['internalHostname'] = get_hostname(self._agentConfig) self._metrics['apiKey'] = self._agentConfig['api_key'] MetricTransaction(json.dumps(self._metrics), headers={'Content-Type': 'application/json'}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/intake/metrics?", MetricsAgentInputHandler), (r"/intake/metadata?", MetadataAgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/api/v1/check_run/?", ApiCheckRunHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, log_function=self.log_request) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) try: # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address=self._agentConfig['bind_host']) except gaierror: log.warning( "localhost seems undefined in your host file, using 127.0.0.1 instead" ) http_server.listen(self._port, address="127.0.0.1") except socket_error as e: if "Errno 99" in str(e): log.warning( "IPv6 doesn't seem to be fully supported. Falling back to IPv4" ) http_server.listen(self._port, address="127.0.0.1") else: raise except socket_error as e: log.exception( "Socket error %s. Is another application listening on the same port ? Exiting", e) sys.exit(1) except Exception as e: log.exception("Uncaught exception. Forwarder is exiting.") sys.exit(1) log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = tornado.ioloop.IOLoop.current() logging.getLogger().setLevel(get_logging_config()['log_level'] or logging.INFO) def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs, TRANSACTION_FLUSH_INTERVAL, io_loop=self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: log.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, get_hostname(self._agentConfig), io_loop=self.mloop) if non_local_traffic is True: gs.listen(gport) else: gs.listen(gport, address="localhost") # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()
class Forwarder(tornado.web.Application): def __init__(self, port, agent_config, watchdog=True, skip_ssl_validation=False, use_simple_http_client=False): self._port = int(port) self._agentConfig = agent_config self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints(MonAPI(agent_config['Api'])) self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None self.skip_ssl_validation = skip_ssl_validation or agent_config.get( 'skip_ssl_validation', False) self.use_simple_http_client = use_simple_http_client if self.skip_ssl_validation: log.info("Skipping SSL hostname validation, useful when using a transparent proxy") if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog( watchdog_timeout, max_mem_mb=agent_config.get('limit_memory_consumption', None)) def _post_metrics(self): if len(self._metrics) > 0: MetricTransaction(self._metrics, headers={'Content-Type': 'application/json'}) self._metrics = {} # todo why is the tornado logging method overridden? Perhaps ditch this. def log_request(self, handler): """ Override the tornado logging method. If everything goes well, log level is DEBUG. Otherwise it's WARNING or ERROR depending on the response code. """ if handler.get_status() < 400: log_method = log.debug elif handler.get_status() < 500: log_method = log.warning else: log_method = log.error request_time = 1000.0 * handler.request.request_time() log_method("%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time) def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", AgentInputHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, log_function=self.log_request ) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) try: # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address="localhost") except gaierror: log.warning( "localhost seems undefined in your host file, using 127.0.0.1 instead") http_server.listen(self._port, address="127.0.0.1") except socket_error as e: if "Errno 99" in str(e): log.warning("IPv6 doesn't seem to be fully supported. Falling back to IPv4") http_server.listen(self._port, address="127.0.0.1") else: raise except socket_error as e: log.exception( "Socket error %s. Is another application listening on the same port ? Exiting", e) sys.exit(1) except Exception: log.exception("Uncaught exception. Forwarder is exiting.") sys.exit(1) log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = get_tornado_ioloop() logging.getLogger().setLevel(get_logging_config()['log_level'] or logging.INFO) def flush_trs(): if self._watchdog: self._watchdog.reset() self._post_metrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback( flush_trs, TRANSACTION_FLUSH_INTERVAL, io_loop=self.mloop) # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()
class Application(tornado.web.Application): def __init__(self, port, agentConfig, watchdog=True): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints() self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog(watchdog_timeout) def appendMetric(self, prefix, name, host, device, ts, value): if self._metrics.has_key(prefix): metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if metrics.has_key(name): metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics['uuid'] = get_uuid() self._metrics['internalHostname'] = gethostname(self._agentConfig) self._metrics['apiKey'] = self._agentConfig['api_key'] MetricTransaction(self._metrics, {}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=True, ) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) http_server.listen(self._port) logging.info("Listening on port %d" % self._port) # Register callbacks self.mloop = tornado.ioloop.IOLoop.instance() def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs, TRANSACTION_FLUSH_INTERVAL, io_loop=self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: logging.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, gethostname(self._agentConfig), io_loop=self.mloop) gs.listen(gport) # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() logging.info("Stopped") def stop(self): self.mloop.stop()
class Application(tornado.web.Application): def __init__(self, port, agentConfig, watchdog=True): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints() self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog(watchdog_timeout) def appendMetric(self, prefix, name, host, device, ts, value): if self._metrics.has_key(prefix): metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if metrics.has_key(name): metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics["uuid"] = getUuid() self._metrics["internalHostname"] = gethostname(self._agentConfig) self._metrics["apiKey"] = self._agentConfig["api_key"] MetricTransaction(self._metrics, {}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/status/?", StatusHandler), ] settings = dict(cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=True) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) http_server.listen(self._port) logging.info("Listening on port %d" % self._port) # Register callbacks self.mloop = tornado.ioloop.IOLoop.instance() def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs, TRANSACTION_FLUSH_INTERVAL, io_loop=self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: logging.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, gethostname(self._agentConfig), io_loop=self.mloop) gs.listen(gport) # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() def stop(self): self.mloop.stop()
class Application(tornado.web.Application): def __init__(self, port, agentConfig, watchdog=True): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints() self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog(watchdog_timeout) def appendMetric(self, prefix, name, host, device, ts, value): if self._metrics.has_key(prefix): metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if metrics.has_key(name): metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics['uuid'] = get_uuid() self._metrics['internalHostname'] = gethostname(self._agentConfig) self._metrics['apiKey'] = self._agentConfig['api_key'] MetricTransaction(self._metrics, {}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, ) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) # set the root logger to warn so tornado is less chatty logging.getLogger().setLevel(logging.WARNING) # but keep the forwarder logger at the original level forwarder_logger = logging.getLogger('forwarder') log_config = get_logging_config() forwarder_logger.setLevel(log_config['log_level'] or logging.INFO) # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address = "localhost") except gaierror: log.warning("Warning localhost seems undefined in your host file, using 127.0.0.1 instead") http_server.listen(self._port, address = "127.0.0.1") log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = tornado.ioloop.IOLoop.instance() def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs,TRANSACTION_FLUSH_INTERVAL, io_loop = self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: log.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, gethostname(self._agentConfig), io_loop=self.mloop) if non_local_traffic is True: gs.listen(gport) else: gs.listen(gport, address = "localhost") # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()
class Application(tornado.web.Application): def __init__(self, port, agentConfig, watchdog=True): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints() self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog(watchdog_timeout, max_mem_mb=agentConfig.get('limit_memory_consumption', None)) def log_request(self, handler): """ Override the tornado logging method. If everything goes well, log level is DEBUG. Otherwise it's WARNING or ERROR depending on the response code. """ if handler.get_status() < 400: log_method = log.debug elif handler.get_status() < 500: log_method = log.warning else: log_method = log.error request_time = 1000.0 * handler.request.request_time() log_method("%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time) def appendMetric(self, prefix, name, host, device, ts, value): if self._metrics.has_key(prefix): metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if metrics.has_key(name): metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics['uuid'] = get_uuid() self._metrics['internalHostname'] = get_hostname(self._agentConfig) self._metrics['apiKey'] = self._agentConfig['api_key'] MetricTransaction(json.dumps(self._metrics), headers={'Content-Type': 'application/json'}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, log_function=self.log_request ) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address = "localhost") except gaierror: log.warning("Warning localhost seems undefined in your host file, using 127.0.0.1 instead") http_server.listen(self._port, address = "127.0.0.1") log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = tornado.ioloop.IOLoop.instance() logging.getLogger().setLevel(get_logging_config()['log_level'] or logging.INFO) def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs,TRANSACTION_FLUSH_INTERVAL, io_loop = self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: log.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, get_hostname(self._agentConfig), io_loop=self.mloop) if non_local_traffic is True: gs.listen(gport) else: gs.listen(gport, address = "localhost") # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()
class Application(tornado.web.Application): def __init__(self, port, agentConfig, watchdog=True, skip_ssl_validation=False): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints() self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None self.skip_ssl_validation = skip_ssl_validation or agentConfig.get('skip_ssl_validation', False) if self.skip_ssl_validation: log.info("Skipping SSL hostname validation, useful when using a transparent proxy") if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog(watchdog_timeout, max_mem_mb=agentConfig.get('limit_memory_consumption', None)) def log_request(self, handler): """ Override the tornado logging method. If everything goes well, log level is DEBUG. Otherwise it's WARNING or ERROR depending on the response code. """ if handler.get_status() < 400: log_method = log.debug elif handler.get_status() < 500: log_method = log.warning else: log_method = log.error request_time = 1000.0 * handler.request.request_time() log_method("%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time) def appendMetric(self, prefix, name, host, device, ts, value): if self._metrics.has_key(prefix): metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if metrics.has_key(name): metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics['uuid'] = get_uuid() self._metrics['internalHostname'] = get_hostname(self._agentConfig) self._metrics['apiKey'] = self._agentConfig['api_key'] MetricTransaction(json.dumps(self._metrics), headers={'Content-Type': 'application/json'}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, log_function=self.log_request ) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address = "localhost") except gaierror: log.warning("Warning localhost seems undefined in your host file, using 127.0.0.1 instead") http_server.listen(self._port, address = "127.0.0.1") log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = get_tornado_ioloop() logging.getLogger().setLevel(get_logging_config()['log_level'] or logging.INFO) def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs,TRANSACTION_FLUSH_INTERVAL, io_loop = self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: log.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, get_hostname(self._agentConfig), io_loop=self.mloop) if non_local_traffic is True: gs.listen(gport) else: gs.listen(gport, address = "localhost") # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()
class Forwarder(tornado.web.Application): def __init__(self, port, agent_config, watchdog=True, skip_ssl_validation=False, use_simple_http_client=False): self._port = int(port) self._agentConfig = agent_config self._metrics = {} MetricTransaction.set_application(self) MetricTransaction.set_endpoints(MonAPI(agent_config['Api'])) self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY) MetricTransaction.set_tr_manager(self._tr_manager) self._watchdog = None self.skip_ssl_validation = skip_ssl_validation or agent_config.get( 'skip_ssl_validation', False) self.use_simple_http_client = use_simple_http_client if self.skip_ssl_validation: log.info( "Skipping SSL hostname validation, useful when using a transparent proxy" ) if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER self._watchdog = Watchdog(watchdog_timeout, max_mem_mb=agent_config.get( 'limit_memory_consumption', None)) def _post_metrics(self): if len(self._metrics) > 0: MetricTransaction(self._metrics, headers={'Content-Type': 'application/json'}) self._metrics = {} # todo why is the tornado logging method overridden? Perhaps ditch this. def log_request(self, handler): """ Override the tornado logging method. If everything goes well, log level is DEBUG. Otherwise it's WARNING or ERROR depending on the response code. """ if handler.get_status() < 400: log_method = log.debug elif handler.get_status() < 500: log_method = log.warning else: log_method = log.error request_time = 1000.0 * handler.request.request_time() log_method("%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time) def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/api/v1/series/?", AgentInputHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, log_function=self.log_request) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) try: # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address="localhost") except gaierror: log.warning( "localhost seems undefined in your host file, using 127.0.0.1 instead" ) http_server.listen(self._port, address="127.0.0.1") except socket_error as e: if "Errno 99" in str(e): log.warning( "IPv6 doesn't seem to be fully supported. Falling back to IPv4" ) http_server.listen(self._port, address="127.0.0.1") else: raise except socket_error as e: log.exception( "Socket error %s. Is another application listening on the same port ? Exiting", e) sys.exit(1) except Exception: log.exception("Uncaught exception. Forwarder is exiting.") sys.exit(1) log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = get_tornado_ioloop() logging.getLogger().setLevel(get_logging_config()['log_level'] or logging.INFO) def flush_trs(): if self._watchdog: self._watchdog.reset() self._post_metrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs, TRANSACTION_FLUSH_INTERVAL, io_loop=self.mloop) # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()
class Application(tornado.web.Application): NO_PARALLELISM = 1 DEFAULT_PARALLELISM = 5 def __init__(self, port, agentConfig, watchdog=True, skip_ssl_validation=False, use_simple_http_client=False): self._port = int(port) self._agentConfig = agentConfig self._metrics = {} AgentTransaction.set_application(self) AgentTransaction.set_endpoints(agentConfig['endpoints']) AgentTransaction.set_request_timeout(agentConfig['forwarder_timeout']) max_parallelism = self.NO_PARALLELISM # Multiple endpoints => enable parallelism if len(agentConfig['endpoints']) > 1: max_parallelism = self.DEFAULT_PARALLELISM self._tr_manager = TransactionManager(MAX_WAIT_FOR_REPLAY, MAX_QUEUE_SIZE, THROTTLING_DELAY, max_parallelism=max_parallelism) AgentTransaction.set_tr_manager(self._tr_manager) self._watchdog = None self.skip_ssl_validation = skip_ssl_validation or agentConfig.get('skip_ssl_validation', False) self.use_simple_http_client = use_simple_http_client if self.skip_ssl_validation: log.info("Skipping SSL hostname validation, useful when using a transparent proxy") # Monitor activity if watchdog: watchdog_timeout = TRANSACTION_FLUSH_INTERVAL * WATCHDOG_INTERVAL_MULTIPLIER / 1000 self._watchdog = Watchdog( watchdog_timeout, max_mem_mb=agentConfig.get('limit_memory_consumption', None), max_resets=WATCHDOG_HIGH_ACTIVITY_THRESHOLD ) def log_request(self, handler): """ Override the tornado logging method. If everything goes well, log level is DEBUG. Otherwise it's WARNING or ERROR depending on the response code. """ if handler.get_status() < 400: log_method = log.debug elif handler.get_status() < 500: log_method = log.warning else: log_method = log.error request_time = 1000.0 * handler.request.request_time() log_method( u"%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time ) def appendMetric(self, prefix, name, host, device, ts, value): if prefix in self._metrics: metrics = self._metrics[prefix] else: metrics = {} self._metrics[prefix] = metrics if name in metrics: metrics[name].append([host, device, ts, value]) else: metrics[name] = [[host, device, ts, value]] def _postMetrics(self): if len(self._metrics) > 0: self._metrics['uuid'] = get_uuid() self._metrics['internalHostname'] = get_hostname(self._agentConfig) self._metrics['apiKey'] = self._agentConfig['api_key'] MetricTransaction(json.dumps(self._metrics), headers={'Content-Type': 'application/json'}) self._metrics = {} def run(self): handlers = [ (r"/intake/?", AgentInputHandler), (r"/intake/metrics?", MetricsAgentInputHandler), (r"/intake/metadata?", MetadataAgentInputHandler), (r"/api/v1/series/?", ApiInputHandler), (r"/api/v1/check_run/?", ApiCheckRunHandler), (r"/status/?", StatusHandler), ] settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", xsrf_cookies=False, debug=False, log_function=self.log_request ) non_local_traffic = self._agentConfig.get("non_local_traffic", False) tornado.web.Application.__init__(self, handlers, **settings) http_server = tornado.httpserver.HTTPServer(self) try: # non_local_traffic must be == True to match, not just some non-false value if non_local_traffic is True: http_server.listen(self._port) else: # localhost in lieu of 127.0.0.1 to support IPv6 try: http_server.listen(self._port, address=self._agentConfig['bind_host']) except gaierror: log.warning("localhost seems undefined in your host file, using 127.0.0.1 instead") http_server.listen(self._port, address="127.0.0.1") except socket_error as e: if "Errno 99" in str(e): log.warning("IPv6 doesn't seem to be fully supported. Falling back to IPv4") http_server.listen(self._port, address="127.0.0.1") else: raise except socket_error as e: log.exception("Socket error %s. Is another application listening on the same port ? Exiting", e) sys.exit(1) except Exception as e: log.exception("Uncaught exception. Forwarder is exiting.") sys.exit(1) log.info("Listening on port %d" % self._port) # Register callbacks self.mloop = get_tornado_ioloop() logging.getLogger().setLevel(get_logging_config()['log_level'] or logging.INFO) def flush_trs(): if self._watchdog: self._watchdog.reset() self._postMetrics() self._tr_manager.flush() tr_sched = tornado.ioloop.PeriodicCallback(flush_trs, TRANSACTION_FLUSH_INTERVAL, io_loop=self.mloop) # Register optional Graphite listener gport = self._agentConfig.get("graphite_listen_port", None) if gport is not None: log.info("Starting graphite listener on port %s" % gport) from graphite import GraphiteServer gs = GraphiteServer(self, get_hostname(self._agentConfig), io_loop=self.mloop) if non_local_traffic is True: gs.listen(gport) else: gs.listen(gport, address="localhost") # Start everything if self._watchdog: self._watchdog.reset() tr_sched.start() self.mloop.start() log.info("Stopped") def stop(self): self.mloop.stop()