Logging in FastAPI applications

Obfuscating email addresses in logs using a custom filter

Want more?

This lesson for enrolled students only. Join the course to unlock it!

You can see the code changes implemented in this lecture below.

If you have purchased the course in a different platform, you still have access to the code changes per lecture here on Teclado. The lecture video and lecture notes remain locked.
Join course for $30

Modified files

storeapi/logging_conf.py
--- 
+++ 
@@ -1,6 +1,25 @@
+import logging
 from logging.config import dictConfig

 from storeapi.config import DevConfig, config
+
+
+def obfuscated(email: str, obfuscated_length: int):
+    """Obfuscate email address for logging purposes."""
+    characters = email[:obfuscated_length]
+    first, last = email.split("@")
+    return characters + ("*" * (len(first) - obfuscated_length)) + "@" + last
+
+
+class EmailObfuscationFilter(logging.Filter):
+    def __init__(self, name: str = "", obfuscated_length: int = 2) -> None:
+        super().__init__(name)
+        self.obfuscated_length = obfuscated_length
+
+    def filter(self, record: logging.LogRecord) -> bool:
+        if "email" in record.__dict__:
+            record.email = obfuscated(record.email, self.obfuscated_length)
+        return True


 def configure_logging() -> None:
@@ -13,7 +32,11 @@
                     "()": "asgi_correlation_id.CorrelationIdFilter",
                     "uuid_length": 8 if isinstance(config, DevConfig) else 32,
                     "default_value": "-",
-                }
+                },
+                "email_obfuscation": {
+                    "()": EmailObfuscationFilter,
+                    "obfuscated_length": 2 if isinstance(config, DevConfig) else 0,
+                },
             },
             "formatters": {
                 "console": {
@@ -34,13 +57,13 @@
                     "class": "rich.logging.RichHandler",  # could use logging.StreamHandler instead
                     "level": "DEBUG",
                     "formatter": "console",
-                    "filters": ["correlation_id"],
+                    "filters": ["correlation_id", "email_obfuscation"],
                 },
                 "rotating_file": {
                     "class": "logging.handlers.RotatingFileHandler",
                     "level": "DEBUG",
                     "formatter": "file",
-                    "filters": ["correlation_id"],
+                    "filters": ["correlation_id", "email_obfuscation"],
                     "filename": "storeapi.log",
                     "maxBytes": 1024 * 1024,  # 1 MB
                     "backupCount": 2,