Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/flask/logging.py: 47%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import logging
4import sys
5import typing as t
7from werkzeug.local import LocalProxy
9from .globals import request
11if t.TYPE_CHECKING: # pragma: no cover
12 from .sansio.app import App
15@LocalProxy
16def wsgi_errors_stream() -> t.TextIO:
17 """Find the most appropriate error stream for the application. If a request
18 is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``.
20 If you configure your own :class:`logging.StreamHandler`, you may want to
21 use this for the stream. If you are using file or dict configuration and
22 can't import this directly, you can refer to it as
23 ``ext://flask.logging.wsgi_errors_stream``.
24 """
25 if request:
26 return request.environ["wsgi.errors"] # type: ignore[no-any-return]
28 return sys.stderr
31def has_level_handler(logger: logging.Logger) -> bool:
32 """Check if there is a handler in the logging chain that will handle the
33 given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`.
34 """
35 level = logger.getEffectiveLevel()
36 current = logger
38 while current:
39 if any(handler.level <= level for handler in current.handlers):
40 return True
42 if not current.propagate:
43 break
45 current = current.parent # type: ignore
47 return False
50#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format
51#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``.
52default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore
53default_handler.setFormatter(
54 logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")
55)
58def create_logger(app: App) -> logging.Logger:
59 """Get the Flask app's logger and configure it if needed.
61 The logger name will be the same as
62 :attr:`app.import_name <flask.Flask.name>`.
64 When :attr:`~flask.Flask.debug` is enabled, set the logger level to
65 :data:`logging.DEBUG` if it is not set.
67 If there is no handler for the logger's effective level, add a
68 :class:`~logging.StreamHandler` for
69 :func:`~flask.logging.wsgi_errors_stream` with a basic format.
70 """
71 logger = logging.getLogger(app.name)
73 if app.debug and not logger.level:
74 logger.setLevel(logging.DEBUG)
76 if not has_level_handler(logger):
77 logger.addHandler(default_handler)
79 return logger