Magesh Ravi

Magesh Ravi

Artist | Techie | Entrepreneur

Print statements in dockerized django projects

I work on multiple Django projects at a time. Docker helps me to keep the project dependencies organized. My typical docker setup for a Django project looks like this.

Recently, I wanted to debug a variable inside my app. I included a print statement with the variable, as usual. I then had a look at the container's console output using,

# docker-compose logs -f <container_name>
docker-compose logs -f myapp-web

I didn't see any debug info in the console log. After multiple container restarts (the go-to fix for everything), I found that the print statements would appear only when the Django server stops or restarts.

A quick search revealed this was due to the python container's PYTHONBUFFERED setting.

ENV PYTHONBUFFERED 1

One of the solutions offered was to set PYTHONBUFFERED to 0. But it didn't feel right as buffering improves IO performance by reducing the total number of calls.

The better solution was to use logging.

Configure logging

In my project's settings.py file, I added:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
        'myapp': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
            'propagate': True,
        }
    }
}

By default, I've set my app's logging level to INFO. For the development environment, I've set the logging level to DEBUG in the container's .env file.

DJANGO_LOG_LEVEL=DEBUG

Using the logger

In my view (or any other module), I can use the logger as shown below.

class HomePage(View):

    logger = logging.getLogger(__name__)

    def get(self, request):
        self.logger.debug("IP Address for debug-toolbar: %s" % request.META['REMOTE_ADDR'])
        return render(request, 'index.html')

Now, I see the output of the logger statement in the docker's console log.

myapp-web_1  | IP Address for debug-toolbar: 172.19.0.1

Last updated: Nov. 5, 2023, 6:21 p.m.