| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1101,6 +1101,9 @@ need: | |||
| 1101 | 1101 | | Current process name when using ``multiprocessing`` | Set ``logging.logMultiprocessing`` to ``False``. | | |
| 1102 | 1102 | | to manage multiple processes. | | | |
| 1103 | 1103 | +-----------------------------------------------------+---------------------------------------------------+ | |
| 1104 | + | Current :class:`asyncio.Task` name when using | Set ``logging.logAsyncioTasks`` to ``False``. | | ||
| 1105 | + | ``asyncio``. | | | ||
| 1106 | + +-----------------------------------------------------+---------------------------------------------------+ | ||
| 1104 | 1107 | ||
| 1105 | 1108 | Also note that the core logging module only includes the basic handlers. If | |
| 1106 | 1109 | you don't import :mod:`logging.handlers` and :mod:`logging.config`, they won't | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -872,10 +872,14 @@ the options available to you. | |||
| 872 | 872 | +----------------+-------------------------+-----------------------------------------------+ | |
| 873 | 873 | | threadName | ``%(threadName)s`` | Thread name (if available). | | |
| 874 | 874 | +----------------+-------------------------+-----------------------------------------------+ | |
| 875 | + | taskName | ``%(taskName)s`` | :class:`asyncio.Task` name (if available). | | ||
| 876 | + +----------------+-------------------------+-----------------------------------------------+ | ||
| 875 | 877 | ||
| 876 | 878 | .. versionchanged:: 3.1 | |
| 877 | 879 | *processName* was added. | |
| 878 | 880 | ||
| 881 | + .. versionchanged:: 3.12 | ||
| 882 | + *taskName* was added. | ||
| 879 | 883 | ||
| 880 | 884 | .. _logger-adapter: | |
| 881 | 885 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -64,20 +64,25 @@ | |||
| 64 | 64 | raiseExceptions = True | |
| 65 | 65 | ||
| 66 | 66 | # | |
| 67 | - # If you don't want threading information in the log, set this to zero | ||
| 67 | + # If you don't want threading information in the log, set this to False | ||
| 68 | 68 | # | |
| 69 | 69 | logThreads = True | |
| 70 | 70 | ||
| 71 | 71 | # | |
| 72 | - # If you don't want multiprocessing information in the log, set this to zero | ||
| 72 | + # If you don't want multiprocessing information in the log, set this to False | ||
| 73 | 73 | # | |
| 74 | 74 | logMultiprocessing = True | |
| 75 | 75 | ||
| 76 | 76 | # | |
| 77 | - # If you don't want process information in the log, set this to zero | ||
| 77 | + # If you don't want process information in the log, set this to False | ||
| 78 | 78 | # | |
| 79 | 79 | logProcesses = True | |
| 80 | 80 | ||
| 81 | + # | ||
| 82 | + # If you don't want asyncio task information in the log, set this to False | ||
| 83 | + # | ||
| 84 | + logAsyncioTasks = True | ||
| 85 | + | ||
| 81 | 86 | #--------------------------------------------------------------------------- | |
| 82 | 87 | # Level related stuff | |
| 83 | 88 | #--------------------------------------------------------------------------- | |
@@ -361,6 +366,15 @@ def __init__(self, name, level, pathname, lineno, | |||
| 361 | 366 | else: | |
| 362 | 367 | self.process = None | |
| 363 | 368 | ||
| 369 | + self.taskName = None | ||
| 370 | + if logAsyncioTasks: | ||
| 371 | + asyncio = sys.modules.get('asyncio') | ||
| 372 | + if asyncio: | ||
| 373 | + try: | ||
| 374 | + self.taskName = asyncio.current_task().get_name() | ||
| 375 | + except Exception: | ||
| 376 | + pass | ||
| 377 | + | ||
| 364 | 378 | def __repr__(self): | |
| 365 | 379 | return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno, | |
| 366 | 380 | self.pathname, self.lineno, self.msg) | |
@@ -566,6 +580,7 @@ class Formatter(object): | |||
| 566 | 580 | (typically at application startup time) | |
| 567 | 581 | %(thread)d Thread ID (if available) | |
| 568 | 582 | %(threadName)s Thread name (if available) | |
| 583 | + %(taskName)s Task name (if available) | ||
| 569 | 584 | %(process)d Process ID (if available) | |
| 570 | 585 | %(message)s The result of record.getMessage(), computed just as | |
| 571 | 586 | the record is emitted | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,6 @@ | |||
| 18 | 18 | ||
| 19 | 19 | Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved. | |
| 20 | 20 | """ | |
| 21 | - | ||
| 22 | 21 | import logging | |
| 23 | 22 | import logging.handlers | |
| 24 | 23 | import logging.config | |
@@ -50,6 +49,7 @@ | |||
| 50 | 49 | from test.support.logging_helper import TestHandler | |
| 51 | 50 | import textwrap | |
| 52 | 51 | import threading | |
| 52 | + import asyncio | ||
| 53 | 53 | import time | |
| 54 | 54 | import unittest | |
| 55 | 55 | import warnings | |
@@ -4552,29 +4552,63 @@ def test_multiprocessing(self): | |||
| 4552 | 4552 | import multiprocessing | |
| 4553 | 4553 | ||
| 4554 | 4554 | def test_optional(self): | |
| 4555 | - r = logging.makeLogRecord({}) | ||
| 4555 | + NONE = self.assertIsNone | ||
| 4556 | 4556 | NOT_NONE = self.assertIsNotNone | |
| 4557 | + | ||
| 4558 | + r = logging.makeLogRecord({}) | ||
| 4557 | 4559 | NOT_NONE(r.thread) | |
| 4558 | 4560 | NOT_NONE(r.threadName) | |
| 4559 | 4561 | NOT_NONE(r.process) | |
| 4560 | 4562 | NOT_NONE(r.processName) | |
| 4563 | + NONE(r.taskName) | ||
| 4561 | 4564 | log_threads = logging.logThreads | |
| 4562 | 4565 | log_processes = logging.logProcesses | |
| 4563 | 4566 | log_multiprocessing = logging.logMultiprocessing | |
| 4567 | + log_asyncio_tasks = logging.logAsyncioTasks | ||
| 4564 | 4568 | try: | |
| 4565 | 4569 | logging.logThreads = False | |
| 4566 | 4570 | logging.logProcesses = False | |
| 4567 | 4571 | logging.logMultiprocessing = False | |
| 4572 | + logging.logAsyncioTasks = False | ||
| 4568 | 4573 | r = logging.makeLogRecord({}) | |
| 4569 | - NONE = self.assertIsNone | ||
| 4574 | + | ||
| 4570 | 4575 | NONE(r.thread) | |
| 4571 | 4576 | NONE(r.threadName) | |
| 4572 | 4577 | NONE(r.process) | |
| 4573 | 4578 | NONE(r.processName) | |
| 4579 | + NONE(r.taskName) | ||
| 4574 | 4580 | finally: | |
| 4575 | 4581 | logging.logThreads = log_threads | |
| 4576 | 4582 | logging.logProcesses = log_processes | |
| 4577 | 4583 | logging.logMultiprocessing = log_multiprocessing | |
| 4584 | + logging.logAsyncioTasks = log_asyncio_tasks | ||
| 4585 | + | ||
| 4586 | + async def _make_record_async(self, assertion): | ||
| 4587 | + r = logging.makeLogRecord({}) | ||
| 4588 | + assertion(r.taskName) | ||
| 4589 | + | ||
| 4590 | + def test_taskName_with_asyncio_imported(self): | ||
| 4591 | + try: | ||
| 4592 | + make_record = self._make_record_async | ||
| 4593 | + with asyncio.Runner() as runner: | ||
| 4594 | + logging.logAsyncioTasks = True | ||
| 4595 | + runner.run(make_record(self.assertIsNotNone)) | ||
| 4596 | + logging.logAsyncioTasks = False | ||
| 4597 | + runner.run(make_record(self.assertIsNone)) | ||
| 4598 | + finally: | ||
| 4599 | + asyncio.set_event_loop_policy(None) | ||
| 4600 | + | ||
| 4601 | + def test_taskName_without_asyncio_imported(self): | ||
| 4602 | + try: | ||
| 4603 | + make_record = self._make_record_async | ||
| 4604 | + with asyncio.Runner() as runner, support.swap_item(sys.modules, 'asyncio', None): | ||
| 4605 | + logging.logAsyncioTasks = True | ||
| 4606 | + runner.run(make_record(self.assertIsNone)) | ||
| 4607 | + logging.logAsyncioTasks = False | ||
| 4608 | + runner.run(make_record(self.assertIsNone)) | ||
| 4609 | + finally: | ||
| 4610 | + asyncio.set_event_loop_policy(None) | ||
| 4611 | + | ||
| 4578 | 4612 | ||
| 4579 | 4613 | class BasicConfigTest(unittest.TestCase): | |
| 4580 | 4614 | ||
@@ -4853,6 +4887,30 @@ def dummy_handle_error(record): | |||
| 4853 | 4887 | # didn't write anything due to the encoding error | |
| 4854 | 4888 | self.assertEqual(data, r'') | |
| 4855 | 4889 | ||
| 4890 | + def test_log_taskName(self): | ||
| 4891 | + async def log_record(): | ||
| 4892 | + logging.warning('hello world') | ||
| 4893 | + | ||
| 4894 | + try: | ||
| 4895 | + encoding = 'utf-8' | ||
| 4896 | + logging.basicConfig(filename='test.log', errors='strict', encoding=encoding, | ||
| 4897 | + format='%(taskName)s - %(message)s', level=logging.WARNING) | ||
| 4898 | + | ||
| 4899 | + self.assertEqual(len(logging.root.handlers), 1) | ||
| 4900 | + handler = logging.root.handlers[0] | ||
| 4901 | + self.assertIsInstance(handler, logging.FileHandler) | ||
| 4902 | + | ||
| 4903 | + with asyncio.Runner(debug=True) as runner: | ||
| 4904 | + logging.logAsyncioTasks = True | ||
| 4905 | + runner.run(log_record()) | ||
| 4906 | + finally: | ||
| 4907 | + asyncio.set_event_loop_policy(None) | ||
| 4908 | + handler.close() | ||
| 4909 | + with open('test.log', encoding='utf-8') as f: | ||
| 4910 | + data = f.read().strip() | ||
| 4911 | + os.remove('test.log') | ||
| 4912 | + self.assertRegex(data, r'Task-\d+ - hello world') | ||
| 4913 | + | ||
| 4856 | 4914 | ||
| 4857 | 4915 | def _test_log(self, method, level=None): | |
| 4858 | 4916 | # logging.root has no handlers so basicConfig should be called | |
@@ -5644,7 +5702,7 @@ def test__all__(self): | |||
| 5644 | 5702 | 'logThreads', 'logMultiprocessing', 'logProcesses', 'currentframe', | |
| 5645 | 5703 | 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', | |
| 5646 | 5704 | 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', 'root', | |
| 5647 | - 'threading'} | ||
| 5705 | + 'threading', 'logAsyncioTasks'} | ||
| 5648 | 5706 | support.check__all__(self, logging, not_exported=not_exported) | |
| 5649 | 5707 | ||
| 5650 | 5708 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Added ``taskName`` attribute to :mod:`logging` module for use with :mod:`asyncio` tasks. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments