async def serve(self, sockets=None): process_id = os.getpid() config = self.config if not config.loaded: config.load() self.lifespan = config.lifespan_class(config) self.install_signal_handlers() message = "Started server process [%d]" color_message = "Started server process [" + test4.style( "%d", fg="cyan") + "]" logger.info(message, process_id, extra={"color_message": color_message}) await self.startup(sockets=sockets) if self.should_exit: return await self.main_loop() await self.shutdown(sockets=sockets) message = "Finished server process [%d]" color_message = "Finished server process [" + test4.style( "%d", fg="cyan") + "]" logger.info( "Finished server process [%d]", process_id, extra={"color_message": color_message}, )
def startup(self): message = f"Started reloader process [{self.pid}] using {self.reloader_name}" color_message = "Started reloader process [{}] using {}".format( test4.style(str(self.pid), fg="cyan", bold=True), test4.style(str(self.reloader_name), fg="cyan", bold=True), ) logger.info(message, extra={"color_message": color_message}) for sig in HANDLED_SIGNALS: signal.signal(sig, self.signal_handler) self.process = get_subprocess(config=self.config, target=self.target, sockets=self.sockets) self.process.start()
def shutdown(self): for process in self.processes: process.join() message = "Stopping parent process [{}]".format(str(self.pid)) color_message = "Stopping parent process [{}]".format( test4.style(str(self.pid), fg="cyan", bold=True) ) logger.info(message, extra={"color_message": color_message})
def startup(self): message = "Started parent process [{}]".format(str(self.pid)) color_message = "Started parent process [{}]".format( test4.style(str(self.pid), fg="cyan", bold=True) ) logger.info(message, extra={"color_message": color_message}) for sig in HANDLED_SIGNALS: signal.signal(sig, self.signal_handler) for idx in range(self.config.workers): process = get_subprocess( config=self.config, target=self.target, sockets=self.sockets ) process.start() self.processes.append(process)
class ColourizedFormatter(logging.Formatter): """ A custom log formatter class that: * Outputs the LOG_LEVEL with an appropriate color. * If a log call includes an `extras={"color_message": ...}` it will be used for formatting the output, instead of the plain text message. """ level_name_colors = { TRACE_LOG_LEVEL: lambda level_name: test4.style(str(level_name), fg="blue"), logging.DEBUG: lambda level_name: test4.style(str(level_name), fg="cyan"), logging.INFO: lambda level_name: test4.style(str(level_name), fg="green"), logging.WARNING: lambda level_name: test4.style(str(level_name), fg="yellow"), logging.ERROR: lambda level_name: test4.style(str(level_name), fg="red"), logging.CRITICAL: lambda level_name: test4.style(str(level_name), fg="bright_red"), } def __init__(self, fmt=None, datefmt=None, style="%", use_colors=None): if use_colors in (True, False): self.use_colors = use_colors else: self.use_colors = sys.stdout.isatty() super().__init__(fmt=fmt, datefmt=datefmt, style=style) def color_level_name(self, level_name, level_no): default = lambda level_name: str(level_name) func = self.level_name_colors.get(level_no, default) return func(level_name) def should_use_colors(self): return True def formatMessage(self, record): recordcopy = copy(record) levelname = recordcopy.levelname seperator = " " * (8 - len(recordcopy.levelname)) if self.use_colors: levelname = self.color_level_name(levelname, recordcopy.levelno) if "color_message" in recordcopy.__dict__: recordcopy.msg = recordcopy.__dict__["color_message"] recordcopy.__dict__["message"] = recordcopy.getMessage() recordcopy.__dict__["levelprefix"] = levelname + ":" + seperator return super().formatMessage(recordcopy)
def formatMessage(self, record): recordcopy = copy(record) scope = recordcopy.__dict__["scope"] method = scope["method"] path = self.get_path(scope) full_path = self.get_full_path(scope) client_addr = self.get_client_addr(scope) status_code = self.get_status_code(recordcopy) http_version = scope["http_version"] request_line = "%s %s HTTP/%s" % (method, full_path, http_version) if self.use_colors: request_line = test4.style(request_line, bold=True) recordcopy.__dict__.update({ "method": method, "path": path, "full_path": full_path, "client_addr": client_addr, "request_line": request_line, "status_code": status_code, "http_version": http_version, }) return super().formatMessage(recordcopy)
def bind_socket(self): sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: sock.bind((self.host, self.port)) except OSError as exc: logger.error(exc) sys.exit(1) sock.set_inheritable(True) message = "Uvicorn running on %s://%s:%d (Press CTRL+C to quit)" color_message = ("Uvicorn running on " + test4.style("%s://%s:%d", bold=True) + " (Press CTRL+C to quit)") protocol_name = "https" if self.is_ssl else "http" logger.info( message, protocol_name, self.host, self.port, extra={"color_message": color_message}, ) return sock
class AccessFormatter(ColourizedFormatter): status_code_colours = { 1: lambda code: test4.style(str(code), fg="bright_white"), 2: lambda code: test4.style(str(code), fg="green"), 3: lambda code: test4.style(str(code), fg="yellow"), 4: lambda code: test4.style(str(code), fg="red"), 5: lambda code: test4.style(str(code), fg="bright_red"), } def get_client_addr(self, scope): client = scope.get("client") if not client: return "" return "%s:%d" % (client[0], client[1]) def get_path(self, scope): return scope.get("root_path", "") + scope["path"] def get_full_path(self, scope): path = scope.get("root_path", "") + scope["path"] query_string = scope.get("query_string", b"").decode("ascii") if query_string: return path + "?" + query_string return path def get_status_code(self, record): status_code = record.__dict__["status_code"] try: status_phrase = http.HTTPStatus(status_code).phrase except ValueError: status_phrase = "" status_and_phrase = "%s %s" % (status_code, status_phrase) if self.use_colors: default = lambda code: status_and_phrase func = self.status_code_colours.get(status_code // 100, default) return func(status_and_phrase) return status_and_phrase def formatMessage(self, record): recordcopy = copy(record) scope = recordcopy.__dict__["scope"] method = scope["method"] path = self.get_path(scope) full_path = self.get_full_path(scope) client_addr = self.get_client_addr(scope) status_code = self.get_status_code(recordcopy) http_version = scope["http_version"] request_line = "%s %s HTTP/%s" % (method, full_path, http_version) if self.use_colors: request_line = test4.style(request_line, bold=True) recordcopy.__dict__.update({ "method": method, "path": path, "full_path": full_path, "client_addr": client_addr, "request_line": request_line, "status_code": status_code, "http_version": http_version, }) return super().formatMessage(recordcopy)
async def startup(self, sockets=None): await self.lifespan.startup() if self.lifespan.should_exit: self.should_exit = True return config = self.config create_protocol = functools.partial(config.http_protocol_class, config=config, server_state=self.server_state) loop = asyncio.get_event_loop() if sockets is not None: # Explicitly passed a list of open sockets. # We use this when the server is run from a Gunicorn worker. self.servers = [] for sock in sockets: server = await loop.create_server(create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog) self.servers.append(server) elif config.fd is not None: # Use an existing socket, from a file descriptor. sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM) server = await loop.create_server(create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog) message = "Uvicorn running on socket %s (Press CTRL+C to quit)" logger.info(message % str(sock.getsockname())) self.servers = [server] elif config.uds is not None: # Create a socket using UNIX domain socket. uds_perms = 0o666 if os.path.exists(config.uds): uds_perms = os.stat(config.uds).st_mode server = await loop.create_unix_server(create_protocol, path=config.uds, ssl=config.ssl, backlog=config.backlog) os.chmod(config.uds, uds_perms) message = "Uvicorn running on unix socket %s (Press CTRL+C to quit)" logger.info(message % config.uds) self.servers = [server] else: # Standard case. Create a socket from a host/port pair. try: server = await loop.create_server( create_protocol, host=config.host, port=config.port, ssl=config.ssl, backlog=config.backlog, ) except OSError as exc: logger.error(exc) await self.lifespan.shutdown() sys.exit(1) port = config.port if port == 0: port = server.sockets[0].getsockname()[1] protocol_name = "https" if config.ssl else "http" message = "Uvicorn running on %s://%s:%d (Press CTRL+C to quit)" color_message = ("Uvicorn running on " + test4.style("%s://%s:%d", bold=True) + " (Press CTRL+C to quit)") logger.info( message, protocol_name, config.host, port, extra={"color_message": color_message}, ) self.servers = [server] self.started = True