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

30 statements  

1from __future__ import annotations 

2 

3import logging 

4import sys 

5import typing as t 

6 

7from werkzeug.local import LocalProxy 

8 

9from .globals import request 

10 

11if t.TYPE_CHECKING: # pragma: no cover 

12 from .sansio.app import App 

13 

14 

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``. 

19 

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] 

27 

28 return sys.stderr 

29 

30 

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 

37 

38 while current: 

39 if any(handler.level <= level for handler in current.handlers): 

40 return True 

41 

42 if not current.propagate: 

43 break 

44 

45 current = current.parent # type: ignore 

46 

47 return False 

48 

49 

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) 

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 as 

62 :attr:`app.import_name <flask.Flask.name>`. 

63 

64 When :attr:`~flask.Flask.debug` is enabled, set the logger level to 

65 :data:`logging.DEBUG` if it is not set. 

66 

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) 

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 logger