Logging in FastAPI applications

Identifying logs from the same request: Correlation ID

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

requirements.txt
--- 
+++ 
@@ -4,4 +4,5 @@
 sqlalchemy
 databases[aiosqlite]
 python-dotenv
-rich+rich
+asgi-correlation-id
storeapi/logging_conf.py
--- 
+++ 
@@ -8,16 +8,23 @@
         {
             "version": 1,
             "disable_existing_loggers": False,
+            "filters": {
+                "correlation_id": {
+                    "()": "asgi_correlation_id.CorrelationIdFilter",
+                    "uuid_length": 8 if isinstance(config, DevConfig) else 32,
+                    "default_value": "-",
+                }
+            },
             "formatters": {
                 "console": {
                     "class": "logging.Formatter",
                     "datefmt": "%Y-%m-%dT%H:%M:%S",
-                    "format": "%(name)s:%(lineno)d - %(message)s",
+                    "format": "(%(correlation_id)s) %(name)s:%(lineno)d - %(message)s",
                 },
                 "file": {
                     "class": "logging.Formatter",
                     "datefmt": "%Y-%m-%dT%H:%M:%S",
-                    "format": "%(asctime)s.%(msecs)03dZ | %(levelname)-8s | %(name)s:%(lineno)d - %(message)s",
+                    "format": "%(asctime)s.%(msecs)03dZ | %(levelname)-8s | [%(correlation_id)s] %(name)s:%(lineno)d - %(message)s",
                 },
             },
             "handlers": {
@@ -25,11 +32,13 @@
                     "class": "rich.logging.RichHandler",  # could use logging.StreamHandler instead
                     "level": "DEBUG",
                     "formatter": "console",
+                    "filters": ["correlation_id"],
                 },
                 "rotating_file": {
                     "class": "logging.handlers.RotatingFileHandler",
                     "level": "DEBUG",
                     "formatter": "file",
+                    "filters": ["correlation_id"],
                     "filename": "storeapi.log",
                     "maxBytes": 1024 * 1024,  # 1 MB
                     "backupCount": 2,
storeapi/main.py
--- 
+++ 
@@ -1,6 +1,7 @@
 import logging
 from contextlib import asynccontextmanager

+from asgi_correlation_id import CorrelationIdMiddleware
 from fastapi import FastAPI, HTTPException
 from fastapi.exception_handlers import http_exception_handler
 from storeapi.database import database
@@ -17,6 +18,7 @@
     await database.disconnect()

 app = FastAPI(lifespan=lifespan)
+app.add_middleware(CorrelationIdMiddleware)


 app.include_router(post_router)