{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Logging examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating a log file" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:root:This is a warning message\n", "CRITICAL:root:This is a critical message\n" ] } ], "source": [ "import logging\n", "\n", "\n", "logging.warning(\"This is a warning message\")\n", "logging.critical(\"This is a critical message\")\n", "logging.debug(\"debug\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logging levels\n", "\n", "Level | Description\n", ":-- | :--\n", "``CRITICAL`` | The programme was stopped\n", "``ERROR`` | A serious error has occurred\n", "``WARNING`` | An indication that something unexpected has happened (default level)\n", "``INFO`` | Confirmation that things are working as expected\n", "``DEBUG`` | Detailed information that is usually only of interest when diagnosing problems" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setting the logging level" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "ERROR:root:An error has happened!\n" ] } ], "source": [ "import logging\n", "\n", "\n", "logging.basicConfig(filename=\"example.log\", filemode=\"w\", level=logging.INFO)\n", "\n", "logging.info(\"Informational message\")\n", "logging.error(\"An error has happened!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating a Logger Object" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "ERROR:example:Error!\n", "Traceback (most recent call last):\n", " File \"/var/folders/hk/s8m0bblj0g10hw885gld52mc0000gn/T/ipykernel_14074/2646645271.py\", line 9, in \n", " raise RuntimeError\n", "RuntimeError\n" ] } ], "source": [ "import logging\n", "\n", "\n", "logging.basicConfig(filename=\"example.log\")\n", "logger = logging.getLogger(\"example\")\n", "logger.setLevel(logging.INFO)\n", "\n", "try:\n", " raise RuntimeError\n", "except Exception:\n", " logger.exception(\"Error!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logging exceptions" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "ERROR:example:You can’t do that!\n", "Traceback (most recent call last):\n", " File \"/var/folders/hk/s8m0bblj0g10hw885gld52mc0000gn/T/ipykernel_14074/760044062.py\", line 2, in \n", " 1 / 0\n", " ~~^~~\n", "ZeroDivisionError: division by zero\n" ] } ], "source": [ "try:\n", " 1 / 0\n", "except ZeroDivisionError:\n", " logger.exception(\"You can’t do that!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logging handler\n", "\n", "### Handler types\n", "\n", "Handler | Description\n", ":--- | :---\n", "``StreamHandler`` | ``stdout``, ``stderr`` or file-like objects\n", "``FileHandler`` | for writing to disk\n", "``RotatingFileHandler`` | supports log rotation\n", "``TimedRotatingFileHandler`` | supports the rotation of log files on the hard disk at specific time intervals\n", "``SocketHandler`` | sends logging output to a network socket\n", "``SMTPHandler`` | supports sending logging messages to an e-mail address via SMTP\n", "\n", "
\n", "\n", "**See also:**\n", "\n", "Further handlers can be found at [Logging handlers](https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### StreamHandler" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "This is an informational message\n", "INFO:stream_logger:This is an informational message\n" ] } ], "source": [ "import logging\n", "\n", "\n", "logger = logging.getLogger(\"stream_logger\")\n", "logger.setLevel(logging.INFO)\n", "\n", "console = logging.StreamHandler()\n", "\n", "logger.addHandler(console)\n", "logger.info(\"This is an informational message\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### SMTPHandler" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "--- Logging error ---\n", "Traceback (most recent call last):\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/logging/handlers.py\", line 1087, in emit\n", " smtp = smtplib.SMTP(self.mailhost, port, timeout=self.timeout)\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/smtplib.py\", line 255, in __init__\n", " (code, msg) = self.connect(host, port)\n", " ~~~~~~~~~~~~^^^^^^^^^^^^\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/smtplib.py\", line 341, in connect\n", " self.sock = self._get_socket(host, port, self.timeout)\n", " ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/smtplib.py\", line 312, in _get_socket\n", " return socket.create_connection((host, port), timeout,\n", " ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^\n", " self.source_address)\n", " ^^^^^^^^^^^^^^^^^^^^\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/socket.py\", line 864, in create_connection\n", " raise exceptions[0]\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/socket.py\", line 849, in create_connection\n", " sock.connect(sa)\n", " ~~~~~~~~~~~~^^^^\n", "ConnectionRefusedError: [Errno 61] Connection refused\n", "Call stack:\n", " File \"\", line 198, in _run_module_as_main\n", " File \"\", line 88, in _run_code\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel_launcher.py\", line 18, in \n", " app.launch_new_instance()\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/traitlets/config/application.py\", line 1075, in launch_instance\n", " app.start()\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/kernelapp.py\", line 739, in start\n", " self.io_loop.start()\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/tornado/platform/asyncio.py\", line 205, in start\n", " self.asyncio_loop.run_forever()\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/asyncio/base_events.py\", line 679, in run_forever\n", " self._run_once()\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/asyncio/base_events.py\", line 2027, in _run_once\n", " handle._run()\n", " File \"/Users/veit/Library/Application Support/uv/python/cpython-3.13.0-macos-aarch64-none/lib/python3.13/asyncio/events.py\", line 89, in _run\n", " self._context.run(self._callback, *self._args)\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/kernelbase.py\", line 545, in dispatch_queue\n", " await self.process_one()\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/kernelbase.py\", line 534, in process_one\n", " await dispatch(*args)\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/kernelbase.py\", line 437, in dispatch_shell\n", " await result\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/ipkernel.py\", line 362, in execute_request\n", " await super().execute_request(stream, ident, parent)\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/kernelbase.py\", line 778, in execute_request\n", " reply_content = await reply_content\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/ipkernel.py\", line 449, in do_execute\n", " res = shell.run_cell(\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/ipykernel/zmqshell.py\", line 549, in run_cell\n", " return super().run_cell(*args, **kwargs)\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py\", line 3075, in run_cell\n", " result = self._run_cell(\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py\", line 3130, in _run_cell\n", " result = runner(coro)\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/IPython/core/async_helpers.py\", line 128, in _pseudo_sync_runner\n", " coro.send(None)\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py\", line 3334, in run_cell_async\n", " has_raised = await self.run_ast_nodes(code_ast.body, cell_name,\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py\", line 3517, in run_ast_nodes\n", " if await self.run_code(code, result, async_=asy):\n", " File \"/Users/veit/cusy/trn/jupyter-tutorial/uvenvs/py313/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py\", line 3577, in run_code\n", " exec(code_obj, self.user_global_ns, self.user_ns)\n", " File \"/var/folders/hk/s8m0bblj0g10hw885gld52mc0000gn/T/ipykernel_14074/3660210047.py\", line 14, in \n", " logger.info(\"This is an informational message\")\n", "Message: 'This is an informational message'\n", "Arguments: ()\n", "INFO:email_logger:This is an informational message\n" ] } ], "source": [ "import logging\n", "import logging.handlers\n", "\n", "\n", "logger = logging.getLogger(\"email_logger\")\n", "logger.setLevel(logging.INFO)\n", "fh = logging.handlers.SMTPHandler(\n", " \"localhost\",\n", " fromaddr=\"python-log@localhost\",\n", " toaddrs=[\"logs@cusy.io\"],\n", " subject=\"Python log\",\n", ")\n", "logger.addHandler(fh)\n", "logger.info(\"This is an informational message\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Log formatting\n", "\n", "You can use formatters to format log messages." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "formatter = logging.Formatter(\"%(asctime)s - %(name)s - %(message)s\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Besides ``%(asctime)s``, ``%(name)s`` and ``%(message)s`` you will find other attributes in [LogRecord attributes](https://docs.python.org/3/library/logging.html#logrecord-attributes)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "This is an informational message\n", "2024-11-03 16:40:42,349 - stream_logger - This is an informational message\n", "INFO:stream_logger:This is an informational message\n" ] } ], "source": [ "import logging\n", "\n", "\n", "logger = logging.getLogger(\"stream_logger\")\n", "logger.setLevel(logging.INFO)\n", "\n", "console = logging.StreamHandler()\n", "formatter = logging.Formatter(\"%(asctime)s - %(name)s - %(message)s\")\n", "console.setFormatter(formatter)\n", "\n", "logger.addHandler(console)\n", "logger.info(\"This is an informational message\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Note:**\n", "\n", "The logging module is thread-safe. However, logging may not work in asynchronous contexts. In such cases, however, you can use the [QueueHandler](https://docs.python.org/3/library/logging.handlers.html#queuehandler).\n", "
\n", "
\n", "\n", "**See also:**\n", "\n", "[Logging to a single file from multiple processes](https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logging to multiple handlers" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "import logging\n", "\n", "\n", "def log(path, multipleLocs=False):\n", " logger = logging.getLogger(\"Example_logger_%s\" % fname)\n", " logger.setLevel(logging.INFO)\n", " fh = logging.FileHandler(path)\n", " formatter = logging.Formatter(\"%(asctime)s - %(name)s - %(message)s\")\n", " fh.setFormatter(formatter)\n", " logger.addHandler(fh)\n", "\n", " if multipleLocs:\n", " console = logging.StreamHandler()\n", " console.setLevel(logging.INFO)\n", " console.setFormatter(formatter)\n", " logger.addHandler(console)\n", "\n", " logger.info(\"This is an informational message\")\n", " try:\n", " 1 / 0\n", " except ZeroDivisionError:\n", " logger.exception(\"You can’t do that!\")\n", "\n", " logger.critical(\"This is a no-brainer!\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Configure logging\n", "\n", "
\n", "\n", "**See also:**\n", "\n", "* [logging configuration](https://docs.python.org/3/howto/logging.html#configuring-logging)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### … in an INI file\n", "\n", "In the following example, the file `development.ini` is loaded in this directory:\n", "\n", "``` ini\n", "[loggers]\n", "keys=root\n", "\n", "[handlers]\n", "keys=stream_handler\n", "\n", "[formatters]\n", "keys=formatter\n", "\n", "[logger_root]\n", "level=DEBUG\n", "handlers=stream_handler\n", "\n", "[handler_stream_handler]\n", "class=StreamHandler\n", "level=DEBUG\n", "formatter=formatter\n", "args=(sys.stderr,)\n", "\n", "[formatter_formatter]\n", "format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s\n", "```" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import logging\n", "import logging.config\n", "\n", "from logging.config import fileConfig\n", "\n", "\n", "logging.config.fileConfig(\"development.ini\")\n", "logger = logging.getLogger(\"example\")\n", "\n", "logger.info(\"Program started\")\n", "logger.info(\"Done!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Pro:**\n", "\n", "* Ability to update the configuration on the fly by using the `logging.config.listen()` function to listen on a socket.\n", "* Different configurations can be used in different environments, so for example, `DEBUG` can be specified as the log level in `development.ini`, while `WARN` is used in `production.ini`.\n", "\n", "**Con:**\n", "\n", "* Less control for example over custom filters or loggers configured in code." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### … in a `dict` config" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "import logging\n", "import logging.config\n", "\n", "\n", "dictLogConfig = {\n", " \"version\": 1,\n", " \"handlers\": {\n", " \"fileHandler\": {\n", " \"class\": \"logging.FileHandler\",\n", " \"formatter\": \"exampleFormatter\",\n", " \"filename\": \"dict_config.log\",\n", " }\n", " },\n", " \"loggers\": {\n", " \"exampleApp\": {\n", " \"handlers\": [\"fileHandler\"],\n", " \"level\": \"INFO\",\n", " }\n", " },\n", " \"formatters\": {\n", " \"exampleFormatter\": {\n", " \"format\": \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n", " }\n", " },\n", "}" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2024-11-03 16:40:42,364 exampleApp INFO Program started\n", "2024-11-03 16:40:42,365 exampleApp INFO Done!\n" ] } ], "source": [ "logging.config.dictConfig(dictLogConfig)\n", "\n", "logger = logging.getLogger(\"exampleApp\")\n", "\n", "logger.info(\"Program started\")\n", "logger.info(\"Done!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Pro:**\n", "\n", "* Update on the fly\n", "\n", "**Con:**\n", "\n", "* Less control than configuring a logger in code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### … directly in the code" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "logger = logging.getLogger()\n", "handler = logging.StreamHandler()\n", "formatter = logging.Formatter(\n", " \"%(asctime)s %(name)-12s %(levelname)-8s %(message)s\"\n", ")\n", "handler.setFormatter(formatter)\n", "logger.addHandler(handler)\n", "logger.setLevel(logging.DEBUG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## *Magic Commands*\n", "\n", "| Befehl | Beschreibung |\n", "| -------------- | ----------------------------------------------------------------------------------------- |\n", "| `%logstart` | Starts logging anywhere in a session |\n", "| | `%logstart [-o\\|-r\\|-t\\|-q] [log_name [log_mode]]` |\n", "| | If no name is given, `ipython_log.py` is used in the current directory. |\n", "| | `log_mode` is an optional parameter. The following modes can be specified: |\n", "| | * `append` appends the logging information to the end of an existing file |\n", "| | * `backup` renames the existing file to `name~` and writes to `name` |\n", "| | * `global` appends the logging information at the end of an existing file |\n", "| | * `over` overwrites an existing log file |\n", "| | * `rotate` creates rotating log files: `name.1~`, `name.2~`, etc. |\n", "| | Options: |\n", "| | * `-o` also logs the output of IPython |\n", "| | * `-r` logs raw output |\n", "| | * `-t` writes a time stamp in front of each log entry |\n", "| | * `-q` suppresses the logging output |\n", "| `%logon` | Restart the logging |\n", "| `%logoff` | Temporary termination of logging |\n", "\n", "**Pro:**\n", "\n", "* Complete control over the configuration\n", "\n", "**Con:**\n", "\n", "* Changes in the configuration require a change in the source code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logs rotate" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2024-11-03 16:40:42,370 Rotating Log INFO This is an example log line 0\n", "2024-11-03 16:40:42,370 Rotating Log INFO This is an example log line 0\n", "2024-11-03 16:40:43,876 Rotating Log INFO This is an example log line 1\n", "2024-11-03 16:40:43,876 Rotating Log INFO This is an example log line 1\n", "2024-11-03 16:40:45,384 Rotating Log INFO This is an example log line 2\n", "2024-11-03 16:40:45,384 Rotating Log INFO This is an example log line 2\n", "2024-11-03 16:40:46,893 Rotating Log INFO This is an example log line 3\n", "2024-11-03 16:40:46,893 Rotating Log INFO This is an example log line 3\n", "2024-11-03 16:40:48,399 Rotating Log INFO This is an example log line 4\n", "2024-11-03 16:40:48,399 Rotating Log INFO This is an example log line 4\n", "2024-11-03 16:40:49,908 Rotating Log INFO This is an example log line 5\n", "2024-11-03 16:40:49,908 Rotating Log INFO This is an example log line 5\n", "2024-11-03 16:40:51,414 Rotating Log INFO This is an example log line 6\n", "2024-11-03 16:40:51,414 Rotating Log INFO This is an example log line 6\n", "2024-11-03 16:40:52,922 Rotating Log INFO This is an example log line 7\n", "2024-11-03 16:40:52,922 Rotating Log INFO This is an example log line 7\n", "2024-11-03 16:40:54,428 Rotating Log INFO This is an example log line 8\n", "2024-11-03 16:40:54,428 Rotating Log INFO This is an example log line 8\n", "2024-11-03 16:40:55,938 Rotating Log INFO This is an example log line 9\n", "2024-11-03 16:40:55,938 Rotating Log INFO This is an example log line 9\n" ] } ], "source": [ "import logging\n", "import time\n", "\n", "from logging.handlers import RotatingFileHandler\n", "\n", "\n", "def create_rotating_log(path):\n", " logger = logging.getLogger(\"Rotating Log\")\n", " logger.setLevel(logging.INFO)\n", "\n", " handler = RotatingFileHandler(path, maxBytes=20, backupCount=5)\n", " logger.addHandler(handler)\n", "\n", " for i in range(10):\n", " logger.info(f\"This is an example log line {i}\")\n", " time.sleep(1.5)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " log_file = \"rotated.log\"\n", " create_rotating_log(log_file)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Rotate logs time-controlled" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2024-11-03 16:40:57,454 Rotating Log INFO This is an example!\n", "2024-11-03 16:40:57,454 Rotating Log INFO This is an example!\n" ] } ], "source": [ "import logging\n", "import time\n", "\n", "from logging.handlers import TimedRotatingFileHandler\n", "\n", "\n", "def create_timed_rotating_log(path):\n", " \"\"\"\"\"\"\n", " logger = logging.getLogger(\"Rotating Log\")\n", " logger.setLevel(logging.INFO)\n", "\n", " handler = TimedRotatingFileHandler(\n", " path, when=\"s\", interval=5, backupCount=5\n", " )\n", " logger.addHandler(handler)\n", "\n", " for i in range(6):\n", " logger.info(\"This is an example!\")\n", " time.sleep(75)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " log_file = \"timed_rotation.log\"\n", " create_timed_rotating_log(log_file)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a logging decorator\n", "\n", "
\n", "\n", "**See also:**\n", "\n", "* [How to Create an Exception Logging Decorator](https://www.blog.pythonlibrary.org/2016/06/09/python-how-to-create-an-exception-logging-decorator/)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a logging filter" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import logging\n", "import sys\n", "\n", "\n", "class ExampleFilter(logging.Filter):\n", " def filter(self, record):\n", " if record.funcName == \"foo\":\n", " return False\n", " return True\n", "\n", "\n", "logger = logging.getLogger(\"filter_example\")\n", "logger.addFilter(ExampleFilter())\n", "\n", "\n", "def foo():\n", " \"\"\"\n", " Ignore this function’s log messages\n", " \"\"\"\n", " logger.debug(\"Message from function foo\")\n", "\n", "\n", "def bar():\n", " logger.debug(\"Message from bar\")\n", "\n", "\n", "if __name__ == \"__main__\":\n", " logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)\n", " foo()\n", " bar()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.13 Kernel", "language": "python", "name": "python313" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }