def main() -> None: setup_logger("resotoworker") # Try to run in a new process group and # ignore if not possible for whatever reason try: os.setpgid(0, 0) except Exception: pass resotolib.proc.parent_pid = os.getpid() arg_parser = ArgumentParser( description="resoto worker", env_args_prefix="RESOTOWORKER_", ) add_args(arg_parser) jwt_add_args(arg_parser) logging_add_args(arg_parser) core_add_args(arg_parser) Config.add_args(arg_parser) TLSData.add_args(arg_parser) # Find resoto Plugins in the resoto.plugins module plugin_loader = PluginLoader() plugin_loader.add_plugin_args(arg_parser) # At this point the CLI, all Plugins as well as the WebServer have # added their args to the arg parser arg_parser.parse_args() try: wait_for_resotocore(resotocore.http_uri) except TimeoutError as e: log.fatal(f"Failed to connect to resotocore: {e}") sys.exit(1) tls_data = None if resotocore.is_secure: tls_data = TLSData( common_name=ArgumentParser.args.subscriber_id, resotocore_uri=resotocore.http_uri, ) tls_data.start() config = Config( ArgumentParser.args.subscriber_id, resotocore_uri=resotocore.http_uri, tls_data=tls_data, ) add_config(config) plugin_loader.add_plugin_config(config) config.load_config() def send_request(request: requests.Request) -> requests.Response: prepared = request.prepare() s = requests.Session() verify = None if tls_data: verify = tls_data.verify return s.send(request=prepared, verify=verify) core = Resotocore(send_request, config) collector = Collector(core.send_to_resotocore, config) # Handle Ctrl+c and other means of termination/shutdown resotolib.proc.initializer() add_event_listener(EventType.SHUTDOWN, shutdown, blocking=False) # Try to increase nofile and nproc limits increase_limits() web_server_args = {} if tls_data: web_server_args = { "ssl_cert": tls_data.cert_path, "ssl_key": tls_data.key_path, } web_server = WebServer( WebApp(mountpoint=Config.resotoworker.web_path), web_host=Config.resotoworker.web_host, web_port=Config.resotoworker.web_port, **web_server_args, ) web_server.daemon = True web_server.start() core_actions = CoreActions( identifier=f"{ArgumentParser.args.subscriber_id}-collector", resotocore_uri=resotocore.http_uri, resotocore_ws_uri=resotocore.ws_uri, actions={ "collect": { "timeout": Config.resotoworker.timeout, "wait_for_completion": True, }, "cleanup": { "timeout": Config.resotoworker.timeout, "wait_for_completion": True, }, }, message_processor=partial(core_actions_processor, plugin_loader, tls_data, collector), tls_data=tls_data, ) task_queue_filter = {} if len(Config.resotoworker.collector) > 0: task_queue_filter = {"cloud": list(Config.resotoworker.collector)} core_tasks = CoreTasks( identifier=f"{ArgumentParser.args.subscriber_id}-tagger", resotocore_ws_uri=resotocore.ws_uri, tasks=["tag"], task_queue_filter=task_queue_filter, message_processor=core_tag_tasks_processor, tls_data=tls_data, ) core_actions.start() core_tasks.start() for Plugin in plugin_loader.plugins(PluginType.ACTION): try: log.debug(f"Starting action plugin {Plugin}") plugin = Plugin(tls_data=tls_data) plugin.start() except Exception as e: log.exception(f"Caught unhandled persistent Plugin exception {e}") # We wait for the shutdown Event to be set() and then end the program # While doing so we print the list of active threads once per 15 minutes shutdown_event.wait() web_server.shutdown() time.sleep(1) # everything gets 1000ms to shutdown gracefully before we force it resotolib.proc.kill_children(resotolib.proc.SIGTERM, ensure_death=True) log.info("Shutdown complete") os._exit(0)
def main() -> None: setup_logger("resotometrics") resotolib.proc.parent_pid = os.getpid() add_event_listener(EventType.SHUTDOWN, shutdown) arg_parser = ArgumentParser(description="resoto metrics exporter", env_args_prefix="RESOTOMETRICS_") add_args(arg_parser) Config.add_args(arg_parser) resotocore_add_args(arg_parser) logging_add_args(arg_parser) jwt_add_args(arg_parser) TLSData.add_args(arg_parser) arg_parser.parse_args() try: wait_for_resotocore(resotocore.http_uri) except TimeoutError as e: log.fatal(f"Failed to connect to resotocore: {e}") sys.exit(1) tls_data = None if resotocore.is_secure: tls_data = TLSData( common_name=ArgumentParser.args.subscriber_id, resotocore_uri=resotocore.http_uri, ) tls_data.start() config = Config( ArgumentParser.args.subscriber_id, resotocore_uri=resotocore.http_uri, tls_data=tls_data, ) config.add_config(ResotoMetricsConfig) config.load_config() resotolib.proc.initializer() metrics = Metrics() graph_collector = GraphCollector(metrics) REGISTRY.register(graph_collector) resotocore_graph = Config.resotometrics.graph graph_uri = f"{resotocore.http_uri}/graph/{resotocore_graph}" search_uri = f"{graph_uri}/search/aggregate?section=reported" message_processor = partial(core_actions_processor, metrics, search_uri, tls_data) core_actions = CoreActions( identifier=ArgumentParser.args.subscriber_id, resotocore_uri=resotocore.http_uri, resotocore_ws_uri=resotocore.ws_uri, actions={ "generate_metrics": { "timeout": Config.resotometrics.timeout, "wait_for_completion": True, }, }, message_processor=message_processor, tls_data=tls_data, ) web_server_args = {} if tls_data: web_server_args = { "ssl_cert": tls_data.cert_path, "ssl_key": tls_data.key_path, } web_server = WebServer( WebApp(mountpoint=Config.resotometrics.web_path), web_host=Config.resotometrics.web_host, web_port=Config.resotometrics.web_port, **web_server_args, ) web_server.daemon = True web_server.start() core_actions.start() shutdown_event.wait() web_server.shutdown() core_actions.shutdown() resotolib.proc.kill_children(resotolib.proc.SIGTERM, ensure_death=True) log.info("Shutdown complete") sys.exit(0)