From c26a616ee61d0bee7e0cdde2dfe52b01d6cf9789 Mon Sep 17 00:00:00 2001 From: Abdelhadi Dyouri Date: Thu, 6 Mar 2025 21:39:19 +0000 Subject: [PATCH 1/5] add loguru code examples --- loguru/basic_logging.py | 5 +++++ loguru/context_logging.py | 15 +++++++++++++++ loguru/error_handling.py | 17 +++++++++++++++++ loguru/file_logging.py | 6 ++++++ loguru/json_logging.py | 26 ++++++++++++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 loguru/basic_logging.py create mode 100644 loguru/context_logging.py create mode 100644 loguru/error_handling.py create mode 100644 loguru/file_logging.py create mode 100644 loguru/json_logging.py diff --git a/loguru/basic_logging.py b/loguru/basic_logging.py new file mode 100644 index 0000000000..0999f4da7e --- /dev/null +++ b/loguru/basic_logging.py @@ -0,0 +1,5 @@ +from loguru import logger + +logger.debug("Debug message") +logger.info("Info message") +logger.error("Error message") \ No newline at end of file diff --git a/loguru/context_logging.py b/loguru/context_logging.py new file mode 100644 index 0000000000..7792408c37 --- /dev/null +++ b/loguru/context_logging.py @@ -0,0 +1,15 @@ +from loguru import logger +import sys + +logger.remove() +logger.add(sys.stderr, format="{time} | {level} | {message} | {extra}") + +user_logger = logger.bind(user_id="123") +user_logger.info("User logged in") +user_logger.info("User started a session") + +with logger.contextualize(request_id="abc789"): + logger.info("Processing request") + logger.info("Request completed") + +logger.info("Request is processed, this will not show extra context") \ No newline at end of file diff --git a/loguru/error_handling.py b/loguru/error_handling.py new file mode 100644 index 0000000000..a25a9b7c80 --- /dev/null +++ b/loguru/error_handling.py @@ -0,0 +1,17 @@ +import sys +from loguru import logger + +logger.remove() +logger.add(sys.stderr, format="{time} | {level} | {message} | {extra}", level="TRACE") + +@logger.catch +def perform_action(user, action): + with logger.contextualize(user=user, action=action): + logger.trace("Starting action") + logger.info("Performing action") + if action not in ["login", "logout"]: + logger.trace("Invalid action detected") + raise ValueError("Invalid action") + logger.success("Action completed") + +perform_action("alice", "delete") \ No newline at end of file diff --git a/loguru/file_logging.py b/loguru/file_logging.py new file mode 100644 index 0000000000..98df565ab3 --- /dev/null +++ b/loguru/file_logging.py @@ -0,0 +1,6 @@ +from loguru import logger +import time +logger.add(sink="app.log", rotation="5 seconds", retention="1 minute") +for i in range(100): + logger.info(f"Processing item #{i}") + time.sleep(2) \ No newline at end of file diff --git a/loguru/json_logging.py b/loguru/json_logging.py new file mode 100644 index 0000000000..c1486b6be3 --- /dev/null +++ b/loguru/json_logging.py @@ -0,0 +1,26 @@ +import json +from loguru import logger + +def simple_serializer(record): + subset = { + "time": record["time"].timestamp(), + "level": record["level"].name, + "message": record["message"], + "context": record["extra"] # Include any bound context + } + return json.dumps(subset) + +def add_serialization(record): + record["extra"]["json_output"] = simple_serializer(record) + +logger.remove() + +logger = logger.patch(add_serialization) + +logger.add( + "simple_logs.json", + format="{extra[json_output]}" +) + +logger.bind(user="john").info("User logged in") +logger.bind(order_id="12345").info("Order processed") From 18f5416c45929aa7f9ee69b07eb0c69f13fee431 Mon Sep 17 00:00:00 2001 From: Abdelhadi Dyouri Date: Thu, 6 Mar 2025 21:49:48 +0000 Subject: [PATCH 2/5] Run black on Loguru example code --- loguru/basic_logging.py | 2 +- loguru/context_logging.py | 2 +- loguru/error_handling.py | 4 +++- loguru/file_logging.py | 5 +++-- loguru/json_logging.py | 10 +++++----- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/loguru/basic_logging.py b/loguru/basic_logging.py index 0999f4da7e..251a709f7b 100644 --- a/loguru/basic_logging.py +++ b/loguru/basic_logging.py @@ -2,4 +2,4 @@ logger.debug("Debug message") logger.info("Info message") -logger.error("Error message") \ No newline at end of file +logger.error("Error message") diff --git a/loguru/context_logging.py b/loguru/context_logging.py index 7792408c37..0a8a711f26 100644 --- a/loguru/context_logging.py +++ b/loguru/context_logging.py @@ -12,4 +12,4 @@ logger.info("Processing request") logger.info("Request completed") -logger.info("Request is processed, this will not show extra context") \ No newline at end of file +logger.info("Request is processed, this will not show extra context") diff --git a/loguru/error_handling.py b/loguru/error_handling.py index a25a9b7c80..f598b7105a 100644 --- a/loguru/error_handling.py +++ b/loguru/error_handling.py @@ -4,6 +4,7 @@ logger.remove() logger.add(sys.stderr, format="{time} | {level} | {message} | {extra}", level="TRACE") + @logger.catch def perform_action(user, action): with logger.contextualize(user=user, action=action): @@ -14,4 +15,5 @@ def perform_action(user, action): raise ValueError("Invalid action") logger.success("Action completed") -perform_action("alice", "delete") \ No newline at end of file + +perform_action("alice", "delete") diff --git a/loguru/file_logging.py b/loguru/file_logging.py index 98df565ab3..01a3b717ca 100644 --- a/loguru/file_logging.py +++ b/loguru/file_logging.py @@ -1,6 +1,7 @@ from loguru import logger import time + logger.add(sink="app.log", rotation="5 seconds", retention="1 minute") for i in range(100): - logger.info(f"Processing item #{i}") - time.sleep(2) \ No newline at end of file + logger.info(f"Processing item #{i}") + time.sleep(2) diff --git a/loguru/json_logging.py b/loguru/json_logging.py index c1486b6be3..d7dcf5f12b 100644 --- a/loguru/json_logging.py +++ b/loguru/json_logging.py @@ -1,26 +1,26 @@ import json from loguru import logger + def simple_serializer(record): subset = { "time": record["time"].timestamp(), "level": record["level"].name, "message": record["message"], - "context": record["extra"] # Include any bound context + "context": record["extra"], # Include any bound context } return json.dumps(subset) + def add_serialization(record): record["extra"]["json_output"] = simple_serializer(record) + logger.remove() logger = logger.patch(add_serialization) -logger.add( - "simple_logs.json", - format="{extra[json_output]}" -) +logger.add("simple_logs.json", format="{extra[json_output]}") logger.bind(user="john").info("User logged in") logger.bind(order_id="12345").info("Order processed") From 5c1b71aa90213b7b1e4b7c6c99eb09deede4bcf9 Mon Sep 17 00:00:00 2001 From: Abdelhadi Dyouri Date: Thu, 6 Mar 2025 21:56:17 +0000 Subject: [PATCH 3/5] Run ruff --fix on Loguru example code --- loguru/context_logging.py | 3 ++- loguru/error_handling.py | 1 + loguru/file_logging.py | 3 ++- loguru/json_logging.py | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/loguru/context_logging.py b/loguru/context_logging.py index 0a8a711f26..ea5bdc1a34 100644 --- a/loguru/context_logging.py +++ b/loguru/context_logging.py @@ -1,6 +1,7 @@ -from loguru import logger import sys +from loguru import logger + logger.remove() logger.add(sys.stderr, format="{time} | {level} | {message} | {extra}") diff --git a/loguru/error_handling.py b/loguru/error_handling.py index f598b7105a..5c58728710 100644 --- a/loguru/error_handling.py +++ b/loguru/error_handling.py @@ -1,4 +1,5 @@ import sys + from loguru import logger logger.remove() diff --git a/loguru/file_logging.py b/loguru/file_logging.py index 01a3b717ca..626289dd40 100644 --- a/loguru/file_logging.py +++ b/loguru/file_logging.py @@ -1,6 +1,7 @@ -from loguru import logger import time +from loguru import logger + logger.add(sink="app.log", rotation="5 seconds", retention="1 minute") for i in range(100): logger.info(f"Processing item #{i}") diff --git a/loguru/json_logging.py b/loguru/json_logging.py index d7dcf5f12b..75bcb06e9d 100644 --- a/loguru/json_logging.py +++ b/loguru/json_logging.py @@ -1,4 +1,5 @@ import json + from loguru import logger From f8907121534d69599f2cadaca50fba8f7b569e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Zaczy=C5=84ski?= Date: Wed, 30 Apr 2025 13:59:13 +0200 Subject: [PATCH 4/5] Post-TR updates --- loguru/context_logging.py | 2 +- loguru/error_handling.py | 20 -------------------- loguru/json_logging.py | 27 --------------------------- 3 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 loguru/error_handling.py delete mode 100644 loguru/json_logging.py diff --git a/loguru/context_logging.py b/loguru/context_logging.py index ea5bdc1a34..e23dc95858 100644 --- a/loguru/context_logging.py +++ b/loguru/context_logging.py @@ -5,7 +5,7 @@ logger.remove() logger.add(sys.stderr, format="{time} | {level} | {message} | {extra}") -user_logger = logger.bind(user_id="123") +user_logger = logger.bind(user_id=123) user_logger.info("User logged in") user_logger.info("User started a session") diff --git a/loguru/error_handling.py b/loguru/error_handling.py deleted file mode 100644 index 5c58728710..0000000000 --- a/loguru/error_handling.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys - -from loguru import logger - -logger.remove() -logger.add(sys.stderr, format="{time} | {level} | {message} | {extra}", level="TRACE") - - -@logger.catch -def perform_action(user, action): - with logger.contextualize(user=user, action=action): - logger.trace("Starting action") - logger.info("Performing action") - if action not in ["login", "logout"]: - logger.trace("Invalid action detected") - raise ValueError("Invalid action") - logger.success("Action completed") - - -perform_action("alice", "delete") diff --git a/loguru/json_logging.py b/loguru/json_logging.py deleted file mode 100644 index 75bcb06e9d..0000000000 --- a/loguru/json_logging.py +++ /dev/null @@ -1,27 +0,0 @@ -import json - -from loguru import logger - - -def simple_serializer(record): - subset = { - "time": record["time"].timestamp(), - "level": record["level"].name, - "message": record["message"], - "context": record["extra"], # Include any bound context - } - return json.dumps(subset) - - -def add_serialization(record): - record["extra"]["json_output"] = simple_serializer(record) - - -logger.remove() - -logger = logger.patch(add_serialization) - -logger.add("simple_logs.json", format="{extra[json_output]}") - -logger.bind(user="john").info("User logged in") -logger.bind(order_id="12345").info("Order processed") From e801b990c310838843e4f2ba007a48e912a86489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Zaczy=C5=84ski?= Date: Wed, 30 Apr 2025 14:04:51 +0200 Subject: [PATCH 5/5] Add missing files --- loguru/README.md | 24 ++++++++++++++++++++++++ loguru/catch_and_log_errors.py | 9 +++++++++ loguru/custom_json_logging.py | 24 ++++++++++++++++++++++++ loguru/customized_log_errors.py | 12 ++++++++++++ loguru/debug_with_context.py | 22 ++++++++++++++++++++++ loguru/loguru_json_file.py | 6 ++++++ loguru/loguru_json_format.py | 7 +++++++ loguru/requirements.txt | 1 + 8 files changed, 105 insertions(+) create mode 100644 loguru/README.md create mode 100644 loguru/catch_and_log_errors.py create mode 100644 loguru/custom_json_logging.py create mode 100644 loguru/customized_log_errors.py create mode 100644 loguru/debug_with_context.py create mode 100644 loguru/loguru_json_file.py create mode 100644 loguru/loguru_json_format.py create mode 100644 loguru/requirements.txt diff --git a/loguru/README.md b/loguru/README.md new file mode 100644 index 0000000000..994b34d7bf --- /dev/null +++ b/loguru/README.md @@ -0,0 +1,24 @@ +# How to Use Loguru for Simpler Python Logging + +This repository contains code related to the Real Python tutorial [How to Use Loguru for Simpler Python Logging](https://realpython.com/python-loguru/). + +## Setup + +You should first create and activate a virtual environment: + +```sh +$ python -m venv venv/ +$ source venv/bin/activate +``` + +Install the pinned dependencies from `requirements.txt`: + +```sh +(venv) $ python -m pip install -r requirements.txt +``` + +Then you can execute the provided Python scripts, for example: + +```sh +(venv) $ python basic_logging.py +``` diff --git a/loguru/catch_and_log_errors.py b/loguru/catch_and_log_errors.py new file mode 100644 index 0000000000..1c392bd125 --- /dev/null +++ b/loguru/catch_and_log_errors.py @@ -0,0 +1,9 @@ +from loguru import logger + + +@logger.catch +def divide(a, b): + return a / b + + +divide(10, 0) diff --git a/loguru/custom_json_logging.py b/loguru/custom_json_logging.py new file mode 100644 index 0000000000..bd3e5529d1 --- /dev/null +++ b/loguru/custom_json_logging.py @@ -0,0 +1,24 @@ +import json + +from loguru import logger + + +def simple_serializer(record): + subset = { + "time": record["time"].timestamp(), + "level": record["level"].name, + "message": record["message"], + "context": record["extra"], # Include any bound context + } + return json.dumps(subset) + + +def add_serialization(record): + record["extra"]["json_output"] = simple_serializer(record) + + +logger.remove() +logger = logger.patch(add_serialization) +logger.add("custom.json", format="{extra[json_output]}") +logger.bind(user="john").info("User logged in") +logger.bind(order_id=12345).info("Order processed") diff --git a/loguru/customized_log_errors.py b/loguru/customized_log_errors.py new file mode 100644 index 0000000000..b3bd395437 --- /dev/null +++ b/loguru/customized_log_errors.py @@ -0,0 +1,12 @@ +from loguru import logger + + +@logger.catch(message="Database connection failed", level="ERROR") +def connect_to_db(host, port): + if port < 1000: + raise ValueError("Invalid port number") + # Simulated database connection + return 1 / 0 # Simulate error + + +connect_to_db("localhost", 123) diff --git a/loguru/debug_with_context.py b/loguru/debug_with_context.py new file mode 100644 index 0000000000..e9e46749ca --- /dev/null +++ b/loguru/debug_with_context.py @@ -0,0 +1,22 @@ +import sys + +from loguru import logger + +logger.remove() +logger.add( + sys.stderr, format="{time} | {level} | {message} | {extra}", level="TRACE" +) + + +@logger.catch +def perform_action(user, action): + with logger.contextualize(user=user, action=action): + logger.trace("Starting action") + logger.info("Performing action") + if action not in ["login", "logout"]: + logger.trace("Invalid action detected") + raise ValueError("Invalid action") + logger.success("Action completed") + + +perform_action("alice", "delete") diff --git a/loguru/loguru_json_file.py b/loguru/loguru_json_file.py new file mode 100644 index 0000000000..3d727ae720 --- /dev/null +++ b/loguru/loguru_json_file.py @@ -0,0 +1,6 @@ +from loguru import logger + +logger.remove() +logger.add("app.json", serialize=True, format="{time} | {level} | {message}") +logger.info("Application started") +logger.warning("Memory usage high") diff --git a/loguru/loguru_json_format.py b/loguru/loguru_json_format.py new file mode 100644 index 0000000000..863db3fdf9 --- /dev/null +++ b/loguru/loguru_json_format.py @@ -0,0 +1,7 @@ +import sys + +from loguru import logger + +logger.remove() +logger.add(sys.stderr, serialize=True) +logger.info("User logged in", user_id=123) diff --git a/loguru/requirements.txt b/loguru/requirements.txt new file mode 100644 index 0000000000..6c11c4caa9 --- /dev/null +++ b/loguru/requirements.txt @@ -0,0 +1 @@ +loguru==0.7.3