{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Logging-Beispiele" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Erstellen einer Log-Datei" ] }, { "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-Ebenen\n", "\n", "Ebene | Beschreibung\n", ":-- | :--\n", "``CRITICAL`` | Das Programm wurde angehalten\n", "``ERROR`` | Ein schwerwiegender Fehler ist aufgetreten\n", "``WARNING`` | Ein Hinweis darauf, dass etwas Unerwartetes passiert ist (Standardstufe)\n", "``INFO`` | Bestätigung, dass die Dinge wie erwartet funktionieren.\n", "``DEBUG`` | Detaillierte Informationen, die in der Regel nur bei der Diagnose von Problemen von Interesse sind." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setzen der Logging-Ebene" ] }, { "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": [ "## Erstellen eines Logger-Objekts" ] }, { "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_65477/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": [ "## Ausnahmen (englisch *exceptions*) loggen" ] }, { "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_65477/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-Typen\n", "\n", "Handler | Beschreibung\n", ":--- | :---\n", "`StreamHandler` | `stdout`, `stderr` oder dateiähnliche Objekte\n", "`FileHandler` | für das Schreiben auf die Festplatte\n", "`RotatingFileHandler` | unterstützt die Protokollrotation\n", "`TimedRotatingFileHandler` | unterstützt die Rotation von Protokolldateien auf der Festplatte in bestimmten Zeitabständen\n", "`SocketHandler` | sendet Logging-Ausgaben an einen Netzwerk-Socket\n", "`SMTPHandler` | unterstützt das Senden von Logging-Nachrichten an eine E-Mail-Adresse über SMTP\n", "\n", "
\n", "\n", "**Siehe auch**\n", "\n", "Weitere Handler können gefunden werden unter [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 \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/logging/handlers.py\", line 1081, in emit\n", " smtp = smtplib.SMTP(self.mailhost, port, timeout=self.timeout)\n", " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/smtplib.py\", line 255, in __init__\n", " (code, msg) = self.connect(host, port)\n", " ^^^^^^^^^^^^^^^^^^^^^^^^\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/smtplib.py\", line 341, in connect\n", " self.sock = self._get_socket(host, port, self.timeout)\n", " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/smtplib.py\", line 312, in _get_socket\n", " return socket.create_connection((host, port), timeout,\n", " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/socket.py\", line 851, in create_connection\n", " raise exceptions[0]\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/socket.py\", line 836, in create_connection\n", " sock.connect(sa)\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/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel_launcher.py\", line 17, in \n", " app.launch_new_instance()\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/traitlets/config/application.py\", line 1043, in launch_instance\n", " app.start()\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/kernelapp.py\", line 736, in start\n", " self.io_loop.start()\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/tornado/platform/asyncio.py\", line 195, in start\n", " self.asyncio_loop.run_forever()\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 607, in run_forever\n", " self._run_once()\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 1922, in _run_once\n", " handle._run()\n", " File \"/opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/events.py\", line 80, in _run\n", " self._context.run(self._callback, *self._args)\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/kernelbase.py\", line 516, in dispatch_queue\n", " await self.process_one()\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/kernelbase.py\", line 505, in process_one\n", " await dispatch(*args)\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/kernelbase.py\", line 412, in dispatch_shell\n", " await result\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/kernelbase.py\", line 740, in execute_request\n", " reply_content = await reply_content\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/ipkernel.py\", line 422, in do_execute\n", " res = shell.run_cell(\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/ipykernel/zmqshell.py\", line 546, in run_cell\n", " return super().run_cell(*args, **kwargs)\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/IPython/core/interactiveshell.py\", line 3009, in run_cell\n", " result = self._run_cell(\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/IPython/core/interactiveshell.py\", line 3064, in _run_cell\n", " result = runner(coro)\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/IPython/core/async_helpers.py\", line 129, in _pseudo_sync_runner\n", " coro.send(None)\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/IPython/core/interactiveshell.py\", line 3269, in run_cell_async\n", " has_raised = await self.run_ast_nodes(code_ast.body, cell_name,\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/IPython/core/interactiveshell.py\", line 3448, in run_ast_nodes\n", " if await self.run_code(code, result, async_=asy):\n", " File \"/Users/veit/.local/share/virtualenvs/python-311-6zxVKbDJ/lib/python3.11/site-packages/IPython/core/interactiveshell.py\", line 3508, in run_code\n", " exec(code_obj, self.user_global_ns, self.user_ns)\n", " File \"/var/folders/hk/s8m0bblj0g10hw885gld52mc0000gn/T/ipykernel_65477/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-Formatierung\n", "\n", "Mit Formatierern könnt ihr den Log-Meldungen Formatierungen hinzufügen." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "formatter = logging.Formatter(\"%(asctime)s - %(name)s - %(message)s\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Neben ``%(asctime)s``, ``%(name)s`` und ``%(message)s`` findet ihr noch weitere Attribute 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", "2023-08-21 18:08:14,555 - 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", "**Bemerkung**\n", "\n", "Das Logging-Modul ist thread-sicher. Logging funktioniert jedoch möglicherweise nicht in asynchronen Kontexten. In solchen Fällen könnt ihr jedoch den [QueueHandler](https://docs.python.org/3/library/logging.handlers.html#queuehandler) verwenden.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Siehe auch**\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 an mehrere Handler" ] }, { "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": [ "## Logging konfigurieren\n", "\n", "
\n", "\n", "**Siehe auch**\n", "\n", "[logging configuration](https://docs.python.org/3/howto/logging.html#configuring-logging)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### … in einer INI-Datei\n", "\n", "Im folgenden Beispiel wird die Datei `development.ini` in diesem Verzeichnis geladen:\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", "* Möglichkeit, die Konfiguration während des Betriebs zu aktualisieren, indem die Funktion `logging.config.listen()` verwendet wird um an einem Socket zu lauschen.\n", "* In verschiedenen Umgebungen können unterschiedliche Konfigurationen verwendet werden, also z.B. kann in der `development.ini` `DEBUG` als Log-Level angegeben werden, während in der `production.ini` `WARN` verwendet wird.\n", "\n", "**Con:**\n", "\n", "* Weniger Kontrolle z.B. gegenüber benutzerdefinierten Filtern oder Logger, die im Code konfiguriert sind." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### … in einer dictConfig" ] }, { "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": [ "2023-08-21 18:08:14,573 exampleApp INFO Program started\n", "2023-08-21 18:08:14,574 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", "* Aktualisieren während des Betriebs\n", "\n", "**Con:**\n", "\n", "* Weniger Kontrolle als beim Konfigurieren eines Loggers im Code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### … direkt im 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` | Startet das Logging irgendwo in einer Session |\n", "| | `%logstart [-o\\|-r\\|-t\\|-q] [log_name [log_mode]]` |\n", "| | Wenn kein Name angegeben wird, wird `ipython_log.py` im aktuellen Verzeichnis verwendet. |\n", "| | `log_mode` ist ein optionaler Parameter. Folgende Modi können angegeben werden: |\n", "| | * `append` hängt die Logging-Informationen am Ende einer vorhandenen Datei an |\n", "| | * `backup` benennt die vorhandene Datei um in `name~` und schreibt in `name` |\n", "| | * `global` hängt die Logging-Informationen am Ende einer vorhandenen Datei im |\n", "| | * `over` überschreibt eine existierende Log-Datei |\n", "| | * `rotate` erstellt rotierende Log-Dateien: `name.1~`, `name.2~`, etc. |\n", "| | Optionen: |\n", "| | * `-o` logt auch den Output von IPython |\n", "| | * `-r` logt *raw* Output |\n", "| | * `-t` schreibt einen Zeitstempel vor jeden Logeintrag |\n", "| | * `-q` unterdrückt die Logging-Ausgabe |\n", "| `%logon` | Neustart des Logging |\n", "| `%logoff` | Temporäres Beenden des Logging |\n", "\n", "**Pro:**\n", "\n", "* Vollständige Kontrolle über die Konfiguration\n", "\n", "**Con:**\n", "\n", "* Änderungen in der Konfiguration erfordern eine Änderung des Quellcodes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logs rotieren" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2023-08-21 18:08:14,580 Rotating Log INFO This is an example log line 0\n", "2023-08-21 18:08:14,580 Rotating Log INFO This is an example log line 0\n", "2023-08-21 18:08:16,086 Rotating Log INFO This is an example log line 1\n", "2023-08-21 18:08:16,086 Rotating Log INFO This is an example log line 1\n", "2023-08-21 18:08:17,595 Rotating Log INFO This is an example log line 2\n", "2023-08-21 18:08:17,595 Rotating Log INFO This is an example log line 2\n", "2023-08-21 18:08:19,103 Rotating Log INFO This is an example log line 3\n", "2023-08-21 18:08:19,103 Rotating Log INFO This is an example log line 3\n", "2023-08-21 18:08:20,612 Rotating Log INFO This is an example log line 4\n", "2023-08-21 18:08:20,612 Rotating Log INFO This is an example log line 4\n", "2023-08-21 18:08:22,122 Rotating Log INFO This is an example log line 5\n", "2023-08-21 18:08:22,122 Rotating Log INFO This is an example log line 5\n", "2023-08-21 18:08:23,632 Rotating Log INFO This is an example log line 6\n", "2023-08-21 18:08:23,632 Rotating Log INFO This is an example log line 6\n", "2023-08-21 18:08:25,137 Rotating Log INFO This is an example log line 7\n", "2023-08-21 18:08:25,137 Rotating Log INFO This is an example log line 7\n", "2023-08-21 18:08:26,646 Rotating Log INFO This is an example log line 8\n", "2023-08-21 18:08:26,646 Rotating Log INFO This is an example log line 8\n", "2023-08-21 18:08:28,155 Rotating Log INFO This is an example log line 9\n", "2023-08-21 18:08:28,155 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(\"This is an example log line %s\" % 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": [ "### Logs zeitgesteuert rotieren" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2023-08-21 18:08:29,674 Rotating Log INFO This is an example!\n", "2023-08-21 18:08:29,674 Rotating Log INFO This is an example!\n", "2023-08-21 18:09:44,681 Rotating Log INFO This is an example!\n", "2023-08-21 18:09:44,681 Rotating Log INFO This is an example!\n", "2023-08-21 18:10:59,688 Rotating Log INFO This is an example!\n", "2023-08-21 18:10:59,688 Rotating Log INFO This is an example!\n", "2023-08-21 18:12:14,697 Rotating Log INFO This is an example!\n", "2023-08-21 18:12:14,697 Rotating Log INFO This is an example!\n", "2023-08-21 18:13:29,702 Rotating Log INFO This is an example!\n", "2023-08-21 18:13:29,702 Rotating Log INFO This is an example!\n", "2023-08-21 18:14:44,710 Rotating Log INFO This is an example!\n", "2023-08-21 18:14:44,710 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": [ "## Erstellen eines Logging-Dekorators\n", "\n", "
\n", "\n", "**Siehe auch**\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": [ "## Einen Logging-Filter erstellen" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2023-08-21 18:15:59,730 filter_example DEBUG Message from bar\n", "2023-08-21 18:15:59,730 filter_example DEBUG Message from bar\n" ] } ], "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.11 Kernel", "language": "python", "name": "python311" }, "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.11.4" }, "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": 2 }