codekingpro/portable-devtools
115k
1from __future__ import annotations2 3import logging4import sys5import typing as t6 7from werkzeug.local import LocalProxy8 9from .globals import request10 11if t.TYPE_CHECKING: # pragma: no cover12 from .sansio.app import App13 14 15@LocalProxy16def wsgi_errors_stream() -> t.TextIO:17 """Find the most appropriate error stream for the application. If a request18 is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``.19 20 If you configure your own :class:`logging.StreamHandler`, you may want to21 use this for the stream. If you are using file or dict configuration and22 can't import this directly, you can refer to it as23 ``ext://flask.logging.wsgi_errors_stream``.24 """25 if request:26 return request.environ["wsgi.errors"] # type: ignore[no-any-return]27 28 return sys.stderr29 30 31def has_level_handler(logger: logging.Logger) -> bool:32 """Check if there is a handler in the logging chain that will handle the33 given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`.34 """35 level = logger.getEffectiveLevel()36 current = logger37 38 while current:39 if any(handler.level <= level for handler in current.handlers):40 return True41 42 if not current.propagate:43 break44 45 current = current.parent # type: ignore46 47 return False48 49 50#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format51#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``.52default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore53default_handler.setFormatter(54 logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")55)56 57 58def create_logger(app: App) -> logging.Logger:59 """Get the Flask app's logger and configure it if needed.60 61 The logger name will be the same as62 :attr:`app.import_name <flask.Flask.name>`.63 64 When :attr:`~flask.Flask.debug` is enabled, set the logger level to65 :data:`logging.DEBUG` if it is not set.66 67 If there is no handler for the logger's effective level, add a68 :class:`~logging.StreamHandler` for69 :func:`~flask.logging.wsgi_errors_stream` with a basic format.70 """71 logger = logging.getLogger(app.name)72 73 if app.debug and not logger.level:74 logger.setLevel(logging.DEBUG)75 76 if not has_level_handler(logger):77 logger.addHandler(default_handler)78 79 return logger80 