def run_server(reporting_queue): def report_launch(actual_port): reporting_queue.put( 'Launching server with pid %d at http://localhost:%d' % (os.getpid(), actual_port)) def done_reporting(): reporting_queue.put(DONE) try: # We mustn't block in the child, because the multiprocessing module enforces that the # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue # but is allowed to block indefinitely on the server loop. if not os.fork(): # Child process. info_dir = RunInfo.dir(self.context.config) # If these are specified explicitly in the config, use those. Otherwise # they will be None, and we'll use the ones baked into this package. template_dir = self.context.config.get('reporting', 'reports_template_dir') assets_dir = self.context.config.get('reporting', 'reports_assets_dir') settings = ReportingServer.Settings(info_dir=info_dir, template_dir=template_dir, assets_dir=assets_dir, root=get_buildroot(), allowed_clients=self.context.options.allowed_clients) server = ReportingServer(self.context.options.port, settings) actual_port = server.server_port() ReportingServerManager.save_current_server_port(actual_port) report_launch(actual_port) done_reporting() # Block forever here. server.start() except socket.error: done_reporting() raise
def execute(self): DONE = '__done_reporting' def maybe_open(port): if self.context.options.server_open: binary_util.ui_open('http://localhost:%d' % port) port = ReportingServerManager.get_current_server_port() if port: maybe_open(port) print('Server already running at http://localhost:%d' % port, file=sys.stderr) return def run_server(reporting_queue): def report_launch(actual_port): reporting_queue.put( 'Launching server with pid %d at http://localhost:%d' % (os.getpid(), actual_port)) def done_reporting(): reporting_queue.put(DONE) try: # We mustn't block in the child, because the multiprocessing module enforces that the # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue # but is allowed to block indefinitely on the server loop. if not os.fork(): # Child process. info_dir = RunInfo.dir(self.context.config) # If these are specified explicitly in the config, use those. Otherwise # they will be None, and we'll use the ones baked into this package. template_dir = self.context.config.get('reporting', 'reports_template_dir') assets_dir = self.context.config.get('reporting', 'reports_assets_dir') settings = ReportingServer.Settings(info_dir=info_dir, template_dir=template_dir, assets_dir=assets_dir, root=get_buildroot(), allowed_clients=self.context.options.allowed_clients) server = ReportingServer(self.context.options.port, settings) actual_port = server.server_port() ReportingServerManager.save_current_server_port(actual_port) report_launch(actual_port) done_reporting() # Block forever here. server.start() except socket.error: done_reporting() raise # We do reporting on behalf of the child process (necessary, since reporting may be buffered in # a background thread). We use multiprocessing.Process() to spawn the child so we can use that # module's inter-process Queue implementation. reporting_queue = multiprocessing.Queue() proc = multiprocessing.Process(target=run_server, args=[reporting_queue]) proc.daemon = True proc.start() s = reporting_queue.get() while s != DONE: print(s, file=sys.stderr) s = reporting_queue.get() # The child process is done reporting, and is now in the server loop, so we can proceed. server_port = ReportingServerManager.get_current_server_port() maybe_open(server_port)
def run_server(reporting_queue): def report_launch(actual_port): reporting_queue.put( 'Launching server with pid {pid} at http://localhost:{port}' .format(pid=os.getpid(), port=actual_port)) def done_reporting(): reporting_queue.put(DONE) try: # We mustn't block in the child, because the multiprocessing module enforces that the # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue # but is allowed to block indefinitely on the server loop. if not os.fork(): # Child process. # The server finds run-specific info dirs by looking at the subdirectories of info_dir, # which is conveniently and obviously the parent dir of the current run's info dir. info_dir = os.path.dirname(self.context.run_tracker.run_info_dir) # If these are specified explicitly in the config, use those. Otherwise # they will be None, and we'll use the ones baked into this package. template_dir = self.get_options().template_dir assets_dir = self.get_options().assets_dir settings = ReportingServer.Settings(info_dir=info_dir, template_dir=template_dir, assets_dir=assets_dir, root=get_buildroot(), allowed_clients=self.get_options().allowed_clients) server = ReportingServer(self.get_options().port, settings) actual_port = server.server_port() ReportingServerManager.save_current_server_port(actual_port) report_launch(actual_port) done_reporting() # Block forever here. server.start() except socket.error: done_reporting() raise
def execute(self): server = ReportingServerManager(self.context, self.get_options()) if not server.is_alive(): logger.info("No server found.") return pid = server.pid try: logger.info("Killing server with {pid} at http://localhost:{port}".format(pid=pid, port=server.socket)) server.terminate() except ReportingServerManager.NonResponsiveProcess: logger.info("Failed to kill server with pid {pid}!".format(pid=pid))
def initial_reporting(config, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ reports_dir = os.path.join(config.getdefault('pants_workdir'), 'reports') link_to_latest = os.path.join(reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) try: if os.path.lexists(link_to_latest): os.unlink(link_to_latest) os.symlink(run_dir, link_to_latest) except OSError as e: # Another run may beat us to deletion or creation. if not (e.errno == errno.EEXIST or e.errno == errno.ENOENT): raise report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings( outfile=outfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. template_dir = config.get('reporting', 'reports_template_dir') html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) (_, port) = ReportingServerManager.get_current_server_pid_and_port() if port: run_tracker.run_info.add_info( 'report_url', 'http://localhost:%d/run/%s' % (port, run_id)) return report
def execute(self): server = ReportingServerManager(self.context, self.get_options()) if not server.is_alive(): logger.info('No server found.') return pid = server.pid try: logger.info( 'Killing server with {pid} at http://localhost:{port}'.format( pid=pid, port=server.socket)) server.terminate() except ReportingServerManager.NonResponsiveProcess: logger.info( 'Failed to kill server with pid {pid}!'.format(pid=pid))
def initial_reporting(self, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ link_to_latest = os.path.join(self.get_options().reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(self.get_options().reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) relative_symlink(run_dir, link_to_latest) report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() errfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings( outfile=outfile, errfile=errfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False, label_format=self.get_options().console_label_format, tool_output_format=self.get_options().console_tool_output_format) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. html_reporter_settings = HtmlReporter.Settings( log_level=Report.INFO, html_dir=html_dir, template_dir=self.get_options().template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) port = ReportingServerManager().socket if port: run_tracker.run_info.add_info( 'report_url', 'http://localhost:{}/run/{}'.format(port, run_id)) return report
def initialize(self, run_tracker, start_time=None): """Initialize with the given RunTracker. TODO: See `RunTracker.start`. """ run_id = run_tracker.initialize() run_dir = os.path.join(self.get_options().reports_dir, run_id) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) relative_symlink( run_dir, os.path.join(self.get_options().reports_dir, 'latest')) report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() errfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings( outfile=outfile, errfile=errfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False, label_format=self.get_options().console_label_format, tool_output_format=self.get_options().console_tool_output_format) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. html_reporter_settings = HtmlReporter.Settings( log_level=Report.INFO, html_dir=html_dir, template_dir=self.get_options().template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) port = ReportingServerManager().socket if port: run_tracker.run_info.add_info( 'report_url', 'http://localhost:{}/run/{}'.format(port, run_id)) # And start tracking the run. run_tracker.start(report, start_time)
def run_server(reporting_queue): def report_launch(actual_port): reporting_queue.put( 'Launching server with pid {pid} at http://localhost:{port}' .format(pid=os.getpid(), port=actual_port)) def done_reporting(): reporting_queue.put(DONE) try: # We mustn't block in the child, because the multiprocessing module enforces that the # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue # but is allowed to block indefinitely on the server loop. if not os.fork(): # Child process. # The server finds run-specific info dirs by looking at the subdirectories of info_dir, # which is conveniently and obviously the parent dir of the current run's info dir. info_dir = os.path.dirname( self.context.run_tracker.run_info_dir) # If these are specified explicitly in the config, use those. Otherwise # they will be None, and we'll use the ones baked into this package. template_dir = self.get_options().template_dir assets_dir = self.get_options().assets_dir settings = ReportingServer.Settings( info_dir=info_dir, template_dir=template_dir, assets_dir=assets_dir, root=get_buildroot(), allowed_clients=self.get_options().allowed_clients) server = ReportingServer(self.get_options().port, settings) actual_port = server.server_port() ReportingServerManager.save_current_server_port( actual_port) report_launch(actual_port) done_reporting() # Block forever here. server.start() except socket.error: done_reporting() raise
def initial_reporting(config, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ reports_dir = os.path.join(config.getdefault('pants_workdir'), 'reports') link_to_latest = os.path.join(reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) try: if os.path.lexists(link_to_latest): os.unlink(link_to_latest) os.symlink(run_dir, link_to_latest) except OSError as e: # Another run may beat us to deletion or creation. if not (e.errno == errno.EEXIST or e.errno == errno.ENOENT): raise report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings(outfile=outfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. template_dir = config.get('reporting', 'reports_template_dir') html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) port = ReportingServerManager.get_current_server_port() if port: run_tracker.run_info.add_info('report_url', 'http://localhost:%d/run/%s' % (port, run_id)) return report
def execute(self): pidfiles_and_ports = ReportingServerManager.get_current_server_pidfiles_and_ports() if not pidfiles_and_ports: print('No server found.', file=sys.stderr) # There should only be one pidfile, but in case there are many, we kill them all here. for pidfile, port in pidfiles_and_ports: with open(pidfile, 'r') as infile: pidstr = infile.read() try: os.unlink(pidfile) pid = int(pidstr) os.kill(pid, signal.SIGKILL) print('Killed server with pid %d at http://localhost:%d' % (pid, port), file=sys.stderr) except (ValueError, OSError): pass
def console_output(self, targets): pidfiles_and_ports = ReportingServerManager.get_current_server_pidfiles_and_ports() if not pidfiles_and_ports: return ['No server found.'] # There should only be one pidfile, but in case there are many, we kill them all here. for pidfile, port in pidfiles_and_ports: with open(pidfile, 'r') as infile: pidstr = infile.read() try: os.unlink(pidfile) pid = int(pidstr) os.kill(pid, signal.SIGKILL) return ['Killed server with pid %d at http://localhost:%d' % (pid, port)] except (ValueError, OSError): return []
def execute(self): manager = ReportingServerManager(self.context, self.get_options()) if manager.is_alive(): logger.info( 'Server already running with pid {pid} at http://localhost:{port}' .format(pid=manager.pid, port=manager.socket)) else: manager.daemonize() manager.await_socket(10) logger.info( 'Launched server with pid {pid} at http://localhost:{port}'. format(pid=manager.pid, port=manager.socket)) self._maybe_open(manager.socket)
def console_output(self, targets): pidfiles_and_ports = ReportingServerManager.get_current_server_pidfiles_and_ports( ) if not pidfiles_and_ports: return ['No server found.'] # There should only be one pidfile, but in case there are many, we kill them all here. for pidfile, port in pidfiles_and_ports: with open(pidfile, 'r') as infile: pidstr = infile.read() try: os.unlink(pidfile) pid = int(pidstr) os.kill(pid, signal.SIGKILL) return [ 'Killed server with pid %d at http://localhost:%d' % (pid, port) ] except (ValueError, OSError): return []
def initial_reporting(self, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ link_to_latest = os.path.join(self.get_options().reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(self.get_options().reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) relative_symlink(run_dir, link_to_latest) report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings(outfile=outfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=self.get_options().template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) (_, port) = ReportingServerManager.get_current_server_pid_and_port() if port: run_tracker.run_info.add_info('report_url', 'http://localhost:{}/run/{}'.format(port, run_id)) return report
def execute(self): manager = ReportingServerManager(self.context, self.get_options()) if manager.is_alive(): logger.info('Server already running with pid {pid} at http://localhost:{port}' .format(pid=manager.pid, port=manager.socket)) else: manager.daemonize() manager.await_socket(10) logger.info('Launched server with pid {pid} at http://localhost:{port}' .format(pid=manager.pid, port=manager.socket)) self._maybe_open(manager.socket)
def execute(self): manager = ReportingServerManager(self.context, self.get_options()) if manager.is_alive(): logger.info( "Server already running with pid {pid} at http://localhost:{port}" .format(pid=manager.pid, port=manager.socket)) else: manager.daemonize() manager.await_socket(10) logger.info( f"Launched server with pid {manager.pid} at http://localhost:{manager.socket}" ) logger.info( f"To kill, run `{self.get_options().pants_bin_name} killserver`" ) self._maybe_open(manager.socket)
def initialize(self, run_tracker, all_options, start_time=None): """Initialize with the given RunTracker. TODO: See `RunTracker.start`. """ run_id = run_tracker.initialize(all_options) run_dir = os.path.join(self.get_options().reports_dir, run_id) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) relative_symlink(run_dir, os.path.join(self.get_options().reports_dir, 'latest')) report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = BytesIO() errfile = BytesIO() capturing_reporter_settings = PlainTextReporter.Settings( outfile=outfile, errfile=errfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False, label_format=self.get_options().console_label_format, tool_output_format=self.get_options().console_tool_output_format) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=self.get_options().template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Set up Zipkin reporting. zipkin_endpoint = self.get_options().zipkin_endpoint trace_id = self.get_options().zipkin_trace_id parent_id = self.get_options().zipkin_parent_id if zipkin_endpoint is None and trace_id is not None and parent_id is not None: raise ValueError( "The zipkin-endpoint flag must be set if zipkin-trace-id and zipkin-parent-id flags are given." ) if (trace_id is None) != (parent_id is None): raise ValueError( "Flags zipkin-trace-id and zipkin-parent-id must both either be set or not set." ) if zipkin_endpoint is not None: zipkin_reporter_settings = ZipkinReporter.Settings(log_level=Report.INFO) zipkin_reporter = ZipkinReporter( run_tracker, zipkin_reporter_settings, zipkin_endpoint, trace_id, parent_id ) report.add_reporter('zipkin', zipkin_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) port = ReportingServerManager().socket if port: run_tracker.run_info.add_info('report_url', 'http://localhost:{}/run/{}'.format(port, run_id)) # And start tracking the run. run_tracker.start(report, start_time)
def initialize(self, run_tracker, all_options, start_time=None): """Initialize with the given RunTracker. TODO: See `RunTracker.start`. """ run_id, run_uuid = run_tracker.initialize(all_options) run_dir = os.path.join(self.get_options().reports_dir, run_id) html_dir = os.path.join(run_dir, "html") safe_mkdir(html_dir) relative_symlink( run_dir, os.path.join(self.get_options().reports_dir, "latest")) report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = BytesIO() errfile = BytesIO() capturing_reporter_settings = PlainTextReporter.Settings( outfile=outfile, errfile=errfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False, label_format=self.get_options().console_label_format, tool_output_format=self.get_options().console_tool_output_format, ) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter("capturing", capturing_reporter) # Set up HTML reporting. We always want that. html_reporter_settings = HtmlReporter.Settings( log_level=Report.INFO, html_dir=html_dir, template_dir=self.get_options().template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter("html", html_reporter) # Set up Zipkin reporting. zipkin_endpoint = self.get_options().zipkin_endpoint trace_id = self.get_options().zipkin_trace_id parent_id = self.get_options().zipkin_parent_id sample_rate = self.get_options().zipkin_sample_rate service_name_prefix = self.get_options().zipkin_service_name_prefix if "{}" not in service_name_prefix: service_name_prefix = service_name_prefix + "/{}" max_span_batch_size = int( self.get_options().zipkin_max_span_batch_size) if zipkin_endpoint is None and trace_id is not None and parent_id is not None: raise ValueError( "The zipkin-endpoint flag must be set if zipkin-trace-id and zipkin-parent-id flags are given." ) if (trace_id is None) != (parent_id is None): raise ValueError( "Flags zipkin-trace-id and zipkin-parent-id must both either be set or not set." ) # If trace_id isn't set by a flag, use UUID from run_id if trace_id is None: trace_id = run_uuid if trace_id and (len(trace_id) != 16 and len(trace_id) != 32 or not is_hex_string(trace_id)): raise ValueError( "Value of the flag zipkin-trace-id must be a 16-character or 32-character hex string. " + "Got {}.".format(trace_id)) if parent_id and (len(parent_id) != 16 or not is_hex_string(parent_id)): raise ValueError( "Value of the flag zipkin-parent-id must be a 16-character hex string. " + "Got {}.".format(parent_id)) if zipkin_endpoint is not None: zipkin_reporter_settings = ZipkinReporter.Settings( log_level=Report.INFO) zipkin_reporter = ZipkinReporter( run_tracker, zipkin_reporter_settings, zipkin_endpoint, trace_id, parent_id, sample_rate, service_name_prefix, max_span_batch_size, ) report.add_reporter("zipkin", zipkin_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info("default_report", html_reporter.report_path()) port = ReportingServerManager().socket if port: run_tracker.run_info.add_info( "report_url", "http://localhost:{}/run/{}".format(port, run_id)) # And start tracking the run. run_tracker.start(report, start_time)