Logs are one of the most important tools used to debug or get info on whether your systems are working on the track. Adding logs to a system is pretty easy, and especially if you are using Django, you can take advantage of the built-in logging framework. But the difficult part is to retrieve logs, I remember working at my first company where we would receive emails with log files attached when something would a particular step would be completed. It was a nightmare to sit and find issues in that file. And especially when we had to find some error that occurred a couple of weeks back, we had to manually open each mail for the given week and try to find the error. ๐Ÿ˜’

Gone are those days, now I know how you can work much more efficiently and optimize your time. Let me help you to set up the logs for Django servers and sync those logs in real-time with NewRelic.

  • Firstly let us configure the log files in Django. ย We need to make sure that the log files which are created are not eating up the whole disk space, for this, we should incorporate log file rotation. The following code will take care of creating new files whenever a log file exceeds 10MB of content and create a new file with an incremental file name.
import os
from logging.handlers import RotatingFileHandler


class MakeRotatingFileHandler(RotatingFileHandler):
    def __init__(self, filename, mode="a", maxBytes=1024 * 1024 * 10, backupCount=0, encoding=None, delay=0):
        os.makedirs(os.path.dirname(filename), exist_ok=True)
        RotatingFileHandler.__init__(self, filename, mode, maxBytes, backupCount, encoding, delay)
  • Once we have the file handler class created, we would now need to use the handler in our Django settings.py file, so that logs created inside Django can make use of the handler class. Using the below snippet in the django settings.py file we shall have our logs configured.
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "loggers": {
        "django_default": {
            "handlers": ["django_file"],
            "level": "INFO",
            "propogate": True,
        },
    },
    "handlers": {
        "django_file": {
            "level": "INFO",
            "class": "<path to the class>.MakeRotatingFileHandler",
            "filename": os.path.join(<where you want to put logs>, "logs/django_logs.log"),
            "maxBytes": 1024 * 1024 * 10,  # 10MB
            "backupCount": 10,
        },
    },
}

For details on how Django logging works please go through the documentation

Logging | Django documentation | Django
  • Now that we have our logging infrastructure set up in Django, let us see how we can use this logging infrastructure in our code.
import logging
import json

def log_event(event_name, log_data, logging_module="django_default", level="INFO"):
    logger = logging.getLogger(logging_module)
    msg = {"ev": event_name, "data": log_data}
    logger.log(msg=json.dumps(msg), level=getattr(logging, level))
    

# call the log event function
log_event('test_log', {'a': 1, 'b': 2})

We can see log files getting created in the specified folder which we configured in the settings.py file.

  • Once our logging infrastructure is in place, we would now need a way to retrieve logs from our server. There are multiple ways which people prefer. Few prefer, sending recurring emails with the log files after certain regular intervals, others prefer to ssh into the server and find the logs, while advance users would prefer to send these logs to a log processing service and then finally query them. While each of them has its pros and cons, we would today learn about the NewRelic logging infrastructure and how we can push our logs created by the Django application to the NewRelic infrastructure using the NewRelic Infrastructure agent.
  • We have to make sure that the NewRelic infrastructure monitoring agent is set up in our servers. Here are the quick installation steps which I have found to be helpful
# Add the New Relic Infrastructure Agent gpg key \
curl -s https://download.newrelic.com/infrastructure_agent/gpg/newrelic-infra.gpg | sudo apt-key add - && \
\
# Create a configuration file and add your license key \
echo "license_key: <get this from new relic dashboard>" | sudo tee -a /etc/newrelic-infra.yml && \
\
# Create the agentโ€™s yum repository \
printf "deb [arch=amd64] https://download.newrelic.com/infrastructure_agent/linux/apt focal main" | sudo tee -a /etc/apt/sources.list.d/newrelic-infra.list && \
\
# Update your apt cache \
sudo apt-get update && \
\
# Run the installation script \
sudo apt-get install newrelic-infra -y
shell script which can install the new relic infrastructure in ubuntu
Please make sure to get the license_key from the NewRelic dashboard and replace it in the about script, else your file installation we have issues

NewRelic guide is also pretty extensive on how to install the Infrastructure monitoring agent if you are using any other OS apart from ubuntu, it would be a good idea to check their guide and follow their steps.

Install the infrastructure monitoring agent for Linux | New Relic Documentation
Instructions for how to install New Relic Infrastructure for Linux systems using a package manager.
  • Once the infrastructure monitoring agent is installed you would have to configure the agent to let it know about the logging file paths which it has to read and sync to the NewRelic Service.
logs:
  - name: "django_log"
    file: /<log file path>/logs/*.log
/etc/newrelic-infra/logging.d/logs/yml
Do make sure the file name for the above configuration is same as /etc/newrelic-infra/logging.d/logs/yml, else the setup would not work.

You can check more about this configuration here.

Forward your logs using the infrastructure agent | New Relic Documentation
How to forward your logs to New Relic using our infrastructure monitoring agent.

That's it!!

Whenever you have new logs created in the file they would be synced to the NewRelic service and you can start checking them from the dashboard, write queries to filter them, add alerts on those logs, and many more custom features which you would like to incorporate.

PS- Make sure the logs created are having json format, else you will find them coming as a vanilla string field, which won't be too helpful.
Parsing log data | New Relic Documentation
How New Relic uses parsing and how to send customized log data.