question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] How to print logs to file

See original GitHub issue

First check

  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google “How to X in FastAPI” and didn’t find any information.

Description

The logouts print by fastapi are not saved to a log file.

  • how can i print the logouts to a file?
  • how can i config the log format using fastapi?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

41reactions
nkhitrovcommented, Apr 18, 2020

Try this example. I hope it will be useful 🦊

import logging
import sys
from pprint import pformat

from fastapi import FastAPI
from loguru import logger
from loguru._defaults import LOGURU_FORMAT
from starlette.requests import Request


class InterceptHandler(logging.Handler):
    """
    Default handler from examples in loguru documentaion.
    See https://loguru.readthedocs.io/en/stable/overview.html#entirely-compatible-with-standard-logging
    """

    def emit(self, record):
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # Find caller from where originated the logged message
        frame, depth = logging.currentframe(), 2
        while frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1

        logger.opt(depth=depth, exception=record.exc_info).log(
            level, record.getMessage()
        )


def format_record(record: dict) -> str:
    """
    Custom format for loguru loggers.
    Uses pformat for log any data like request/response body during debug.
    Works with logging if loguru handler it.

    Example:
    >>> payload = [{"users":[{"name": "Nick", "age": 87, "is_active": True}, {"name": "Alex", "age": 27, "is_active": True}], "count": 2}]
    >>> logger.bind(payload=).debug("users payload")
    >>> [   {   'count': 2,
    >>>         'users': [   {'age': 87, 'is_active': True, 'name': 'Nick'},
    >>>                      {'age': 27, 'is_active': True, 'name': 'Alex'}]}]
    """
    format_string = LOGURU_FORMAT

    if record["extra"].get("payload") is not None:
        record["extra"]["payload"] = pformat(
            record["extra"]["payload"], indent=4, compact=True, width=88
        )
        format_string += "\n<level>{extra[payload]}</level>"

    format_string += "{exception}\n"
    return format_string


app = FastAPI(title="Logger Handler", debug=True)

# set loguru format for root logger
logging.getLogger().handlers = [InterceptHandler()]

# set format
logger.configure(
    handlers=[{"sink": sys.stdout, "level": logging.DEBUG, "format": format_record}]
)

# Also set loguru handler for uvicorn loger.
# Default format:
# INFO:     127.0.0.1:35238 - "GET / HTTP/1.1" 200 OK
#
# New format:
# 2020-04-18 16:33:49.728 | INFO     | uvicorn.protocols.http.httptools_impl:send:447 - 127.0.0.1:35942 - "GET / HTTP/1.1" 200

# uvicorn loggers: .error .access .asgi
# https://github.com/encode/uvicorn/blob/master/uvicorn/config.py#L243
logging.getLogger("uvicorn.access").handlers = [InterceptHandler()]


@app.get("/")
def index(request: Request) -> None:
    logger.info("loguru log")
    logging.info("logging log")

    logging.getLogger("fastapi").debug("fatapi info log")
    logger.bind(payload=dict(request.query_params)).debug("params with formating")
    return None

Start server with uvicorn main:app --reload.

Sending request: curl "localhost:8000/?a=11111111111111&b=2222222222222&c=33333333333&d=444444444444444"

Check server logs:

(venv) [nick@nick untitled]$ uvicorn main:app --reload 
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [194284]
2020-04-18 16:48:12.183 | INFO     | uvicorn.main:serve:397 - Started server process [194286]
2020-04-18 16:48:12.184 | INFO     | uvicorn.lifespan.on:startup:22 - Waiting for application startup.
2020-04-18 16:48:12.184 | INFO     | uvicorn.lifespan.on:startup:34 - Application startup complete.
2020-04-18 16:48:15.549 | INFO     | main:index:69 - loguru log
2020-04-18 16:48:15.550 | INFO     | main:index:70 - logging log
2020-04-18 16:48:15.551 | DEBUG    | main:index:73 - params with formating
{   'a': '11111111111111',
    'b': '2222222222222',
    'c': '33333333333',
    'd': '444444444444444'}
2020-04-18 16:48:15.553 | INFO     | uvicorn.protocols.http.httptools_impl:send:447 - 127.0.0.1:36312 - "GET /?a=11111111111111&b=2222222222222&c=33333333333&d=444444444444444 HTTP/1.1" 200
16reactions
nkhitrovcommented, Apr 16, 2020

Hi, @luozhouyang

You can config logs with loguru. It can change the format of standard logs and write them to a file

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to write to a file, using the logging Python module?
Here is two examples, one print the logs (stdout) the other write the logs to a file: import logging import sys logger =...
Read more >
Logger in Java | Java Logging Basics with Log4j and util
Create new Logger; Log Levels; Properties File; Logging Events ... statements is that log messages will be printed only on the console.
Read more >
Solved The purpose of this exercise is to write a Python - Chegg
Question : The purpose of this exercise is to write a Python program to process a log file and print some summary results....
Read more >
How To Write Logs To A File With Python? - Better Stack
logger = logging.getLogger(__name__) FileOutputHandler = logging.FileHandler ...
Read more >
Python Logging - Print logs in File - Studytonight
If you want to print python logs in a file rather than on the console then we can do so using the basicConfig()...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found