diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index 0211e1d9..d66d7337 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -21,6 +21,7 @@ import json import uuid import socket import shutil +import asyncio from ..config import Config from .project import Project @@ -91,7 +92,7 @@ class Controller: user=server_config.get("user", ""), password=server_config.get("password", ""), force=True, - connect=False) + connect=True) except ControllerError: log.fatal("Cannot access to the local server, make sure something else is not running on the TCP port {}".format(port)) sys.exit(1) @@ -311,7 +312,7 @@ class Controller: self._computes[compute.id] = compute self.save() if connect: - await compute.connect() + asyncio.ensure_future(compute.connect()) self.notification.controller_emit("compute.created", compute.__json__()) return compute else: diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index b4962dab..8d540298 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -105,7 +105,7 @@ class Compute: def _session(self): if self._http_session is None or self._http_session.closed is True: - connector = aiohttp.TCPConnector(force_close=True) + connector = aiohttp.TCPConnector(limit=None, force_close=True) self._http_session = aiohttp.ClientSession(connector=connector) return self._http_session @@ -464,7 +464,7 @@ class Compute: elif response.type == aiohttp.WSMsgType.CLOSED: pass break - except aiohttp.ClientError as e: + except aiohttp.client_exceptions.ClientResponseError as e: log.error("Client response error received on compute '{}' WebSocket '{}': {}".format(self._id, ws_url,e)) finally: self._connected = False @@ -594,8 +594,8 @@ class Compute: """ Forward a call to the emulator on compute """ + action = "/{}/{}".format(type, path) try: - action = "/{}/{}".format(type, path) res = await self.http_query(method, action, data=data, timeout=None) except aiohttp.ServerDisconnectedError: raise ControllerError(f"Connection lost to {self._id} during {method} {action}") diff --git a/gns3server/logger.py b/gns3server/logger.py index 64f4c043..ac0108c9 100644 --- a/gns3server/logger.py +++ b/gns3server/logger.py @@ -57,6 +57,11 @@ class ColouredFormatter(logging.Formatter): colour = self.RESET message = message.replace("#RESET#", self.RESET) + + # do not show uvicorn filename and line number in logs + if record.name.startswith("uvicorn"): + message = message.replace(f"{record.name}:{record.lineno}", "uvicorn") + message = '{colour}{message}{reset}'.format(colour=colour, message=message, reset=self.RESET) return message @@ -108,7 +113,7 @@ class LogFilter: This filter some noise from the logs """ def filter(record): - if record.name == "aiohttp.access" and "/settings" in record.msg and "200" in record.msg: + if "/settings" in record.msg and "200" in record.msg: return 0 return 1 @@ -150,11 +155,11 @@ def init_logger(level, logfile=None, max_bytes=10000000, backup_count=10, compre stream_handler.formatter = ColouredFormatter("{asctime} {levelname} {filename}:{lineno} {message}", "%Y-%m-%d %H:%M:%S", "{") else: stream_handler = ColouredStreamHandler(sys.stdout) - stream_handler.formatter = ColouredFormatter("{asctime} {levelname} {filename}:{lineno}#RESET# {message}", "%Y-%m-%d %H:%M:%S", "{") + stream_handler.formatter = ColouredFormatter("{asctime} {levelname} {name}:{lineno}#RESET# {message}", "%Y-%m-%d %H:%M:%S", "{") if quiet: stream_handler.addFilter(logging.Filter(name="user_facing")) - logging.getLogger('user_facing').propagate = False + logging.getLogger("user_facing").propagate = False if level > logging.DEBUG: stream_handler.addFilter(LogFilter) logging.basicConfig(level=level, handlers=[stream_handler]) - return logging.getLogger('user_facing') + return stream_handler diff --git a/gns3server/run.py b/gns3server/run.py index 6963d0da..794d80c2 100644 --- a/gns3server/run.py +++ b/gns3server/run.py @@ -23,7 +23,6 @@ Start the program. Use main.py to load it. import os import datetime -import sys import locale import argparse import psutil @@ -257,14 +256,19 @@ def run(): if args.debug: level = logging.DEBUG - user_log = init_logger(level, logfile=args.log, max_bytes=int(args.logmaxsize), backup_count=int(args.logbackupcount), - compression=args.logcompression, quiet=args.quiet) - user_log.info("GNS3 server version {}".format(__version__)) + stream_handler = init_logger(level, + logfile=args.log, + max_bytes=int(args.logmaxsize), + backup_count=int(args.logbackupcount), + compression=args.logcompression, + quiet=args.quiet) + + log.info("GNS3 server version {}".format(__version__)) current_year = datetime.date.today().year - user_log.info("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year)) + log.info("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year)) for config_file in Config.instance().get_config_files(): - user_log.info("Config file {} loaded".format(config_file)) + log.info("Config file {} loaded".format(config_file)) set_config(args) server_config = Config.instance().get_section_config("Server") @@ -283,8 +287,10 @@ def run(): if sys.version_info < (3, 6, 0): raise SystemExit("Python 3.6 or higher is required") - user_log.info("Running with Python {major}.{minor}.{micro} and has PID {pid}".format(major=sys.version_info[0], minor=sys.version_info[1], - micro=sys.version_info[2], pid=os.getpid())) + log.info("Running with Python {major}.{minor}.{micro} and has PID {pid}".format(major=sys.version_info[0], + minor=sys.version_info[1], + micro=sys.version_info[2], + pid=os.getpid())) # check for the correct locale (UNIX/Linux only) locale_check() @@ -304,8 +310,25 @@ def run(): try: log.info("Starting server on {}:{}".format(host, port)) - #uvicorn.run("app:app", host=host, port=port, log_level="info")#, reload=True) - config = uvicorn.Config("gns3server.app:app", host=host, port=port, access_log=True) + + # only show uvicorn access logs in debug mode + access_log = False + if log.getEffectiveLevel() == logging.DEBUG: + access_log = True + + config = uvicorn.Config("gns3server.app:app", host=host, port=port, access_log=access_log) + + # overwrite uvicorn loggers with our own logger + for uvicorn_logger_name in ("uvicorn", "uvicorn.error"): + uvicorn_logger = logging.getLogger(uvicorn_logger_name) + uvicorn_logger.handlers = [stream_handler] + uvicorn_logger.propagate = False + + if access_log: + uvicorn_logger = logging.getLogger("uvicorn.access") + uvicorn_logger.handlers = [stream_handler] + uvicorn_logger.propagate = False + server = uvicorn.Server(config) loop = asyncio.get_event_loop() loop.run_until_complete(server.serve())