Logging with Logger Dependency

By default, Stario uses a logger that is bound to the request. This means that all logs are automatically contextualized with the request ID.

Basic Logging

from stario import Query
from stario.logging import Logger

@app.get("/users")
async def list_users(logger: Logger):
    logger.info("Fetching all users")

    users = await db.get_users()
    logger.info("Fetched users", count=len(users))

    return div([render_user(u) for u in users])

Log Levels

from stario.logging import Logger

async def my_handler(logger: Logger):
    logger.debug("Detailed debugging info")
    logger.info("General information")
    logger.warning("Something unexpected")
    logger.error("An error occurred")
    logger.critical("System failure")

Threshold-Based Buffering

By default, logs are buffered until a message at or above the threshold level is logged. This is useful to avoid logging too much information for successful requests - but including useful information for failed requests.

For example, if you want to log all logs above WARNING level, you can set the threshold level to WARNING:

from stario.logging import Logger

@app.get("/users")
async def list_users(logger: Logger):
    logger.info("Fetching users")
    users = await db.get_users()
    logger.info("Fetched users", count=len(users))

    # Only logs above WARNING level are written to the console (by default)
    logger.warning("Threshold reached")

Contextual Structured Logging

from stario.logging import Logger

@app.post("/process")
async def process(logger: Logger, user_id: int):
    logger.info("Processing request", user_id=user_id, feeling="happy")

    result = await do_work(user_id)

    logger.info(f"Completed: {result}", result_ok=result is not None)

Exception Logging

from stario.logging import Logger

@app.get("/risky")
async def risky_operation(logger: Logger):
    try:
        return await dangerous_call()
    except Exception as e:
        logger.exception("Failed to complete operation")
        # Logs full stack trace automatically

Timed Operations

from stario.logging import Logger

@app.get("/users")
async def list_users(logger: Logger):
    with logger.timed("Fetching users"):
        users = await db.get_users()

    logger.info("Fetched users", count=len(users))

    return div([render_user(u) for u in users])