Django – Logging to File and Sending Emails when Exceptions Occurs

Categories Django, Python

Logging in any application is an important aspect of application design. Making sure that all errors/exceptions get logged in production help in finding issues. In this article, I am going to show how to do logging in a Django application.

Django usages python’s logging module for logging.  Logging configuration in python consists of 4 parts- Loggers, Handlers, Filters, Formatters. You can read more about these in Django documentation, but here is quick overview:

Formatters – As the name suggests, this describes the format of log text.

Filters – Filters can be used to filter out log records or to modify log records before they are logged.

Handlers – Handlers determine what happens to the log message. Log message can be written to file, printed on the screen,  emailed etc.

Loggers – Loggers are the entry point for logging. Here you define the handlers for the log, level of logging etc.

To configure logging in Django, a configuration dictionary needs to be provided to Django’s LOGGING settings.

Here is a sample configuration which logs to file and also sends emails to admins:

ADMINS = (('Harshveer', 'harshveer1889@gmail.com'), ('Harshveer', 'admin@harshveers.com'))
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'filters': {

    },
    'handlers': {
		'file': {
            'level': 'WARNING',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, "pyserver.log"),
			'formatter': 'verbose'
        },
        'mail_admins': {
            'level': 'WARNING',
            'class': 'django.utils.log.AdminEmailHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['file', 'mail_admins'],
            'propagate': True,
            'level': 'WARNING',
        },
        'LoggerApp': {
            'handlers': ['file', 'mail_admins'],
            'propagate': True,
            'level': 'WARNING',
        }
    }
}

Now whenever an exception occurs in LoggerApp or django app, it will be logged to pyserver.log and also an email will be sent to users defined in ADMINS setting.

To log message manually logging module can be used as below:

from django.http import HttpResponse
import logging

# Get an instance of a logger
logger = logging.getLogger(__name__)

def log_error(request):
	logger.error('This is the manual error logging.')
	return HttpResponse("Logged manual error.")

That’s all about configuring logging in Django app. You can find complete project code for this on GitHub.

If you liked the post or have any suggestions, leave a comment 🙂

Sending Template Based Emails from Django

Categories Django, Python

Sending Emails from Django is quick and easy. In this post I will show a basic setup for sending Emails from Django using Email templates. Using templates give us the advantage of using one Email template to send Emails to different users with different data.

First we ned to setup a SMTP server locally for development environment. There are many ways to setup SMTP server for development environments.

One of them is to use Python’s build-in way to start a “dumb” SMTP server. Run this command in terminal to start python SMTP server on local environment:

python -m smtpd -n -c DebuggingServer localhost:25

This will show Emails in terminal itself. There are other SMTP servers available with UI also. The one I user is MailSlurper. This runs locally and has browser based UI.

We need to define SMTP host and port in Django projects’s settings.py:

SERVER_EMAIL = 'root@localhost'
EMAIL_HOST = 'localhost'
EMAIL_PORT = '25'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''

Create a directory for Email templates in you project, let’s say template. Add this directory to TEMPLATES setting of Django project’s settings.py.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Create a template for subject email_subject.html with content as template for subject. Don’t use new lines in subject template. Add {{ subject }} to contents of email_subject.html file.

Create template for body of email named email_body.html. Add following content to this template:

Hi {{ name }},

This is a demo for sending emails from django using email templates.<br/>

Thanks,
{{ sender }}

In Django view import settings, loader and send_mail:

from django.template import loader
from django.core.mail import send_mail
from MailProject import settings

To send Email in Django view’s function, we will first get and parse Email templates and then send the Email:

def send_email(request):
	# Data for parsing email templates
	context_data = {
		'subject': 'Sent from django',
		'name': 'Harshveer Singh',
		'sender': 'Django Server'
	}

	# Get Subject template
	subject_t = loader.get_template('email_subject.html')
	# Parse Subject template
	subject = subject_t.render(context_data)
	# Get Body template
	body_t = loader.get_template('email_body.html')
	# Parse Body template
	body = body_t.render(context_data)
	
	try:
		# Send mail
		send_mail(subject, body, settings.SERVER_EMAIL, ['harshveer1889@gmail.com'], fail_silently=False,)
	except:
		return HttpResponse("Failed to send email.")

	return HttpResponse("Email sent successfully.")

Now, if we call this method, it will send the Email and we can see this message in MailSlurper.

That’s all about sending Emails in Django using Templates. You can find complete project code for this on GitHub.

If you liked the post or have any suggestions, leave a comment 🙂

Automatically Mounting Partitions in Ubuntu

Categories Ubuntu

If you have many partitions of your disk then you can see that when you start Ubuntu all partitions doesn’t get mounted automatically. If you want all of your partitions or a particular partition to be mounted automatically, it can be done easily with method given below (Taken from Ubuntu documentation) :

First of all run following command in terminal to list the partition table of all disks present on your computer:

user@ubuntu:~$ sudo fdisk -l

Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x1276c8c9

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
/dev/sda2          206848   209922047   104857600    7  HPFS/NTFS/exFAT
/dev/sda3       209922048   914837489   352457721    7  HPFS/NTFS/exFAT
/dev/sda4       914837490   976768064    30965287+   7  HPFS/NTFS/exFAT
user@ubuntu:~$

This command displays all of your partitions on all disks. First column named ‘Device’ is your partition. The last column displays the System name of your partition. The following table displays the System name to linux type of some common System types:

System name
English name
Linux type
W95 FAT32
Microsoft FAT32
vfat
W95 FAT32 (LBA)
Microsoft FAT32
vfat
W95 FAT16 (LBA)
Microsoft FAT16
vfat
W95 Ext’d (LBA)
Microsoft extended partition
Not used
NTFS volume set
Microsoft NTFS
ntfs
NTFS volume set
Microsoft NTFS with read-write access
ntfs-3g
Apple_HFS
Apple HFS
hfsplus

Now our next step is to create location where we want to mount our partitions. For this purpose run following commands in terminal:

user@ubuntu:~$ sudo mkdir /media/a

For all partitions you want to mount and replace ‘a’ with the name you want to give your partition mount location.
Now our next step is to edit Ubuntu’s file system table. To do this run following command in terminal:

user@ubuntu:~$ sudo gedit /etc/fstab

and place following line at the end of file:

/dev/sda3  /media/a  ntfs  user,fmask=0111,dmask=0000  0  0

Here replace /dev/sda3 with your ‘Device’ name, /media/a with the path you created for mounting your disk, ntfs with ‘Linux type’ of your partition user,fmask=0111,dmask=0000 is additional option for permissions of partition for ntfs type partition. You can replace it with according to your partition type using table below:

Description Accessible by everyone Accessible by a subset of users
FAT(16/32) partition
user,auto,fmask=0111,
dmask=0000
user,auto,fmask=0177,
dmask=0077,uid=1000
NTFS partition
rw,auto,user,fmask=0111,
dmask=0000
rw,user,auto,fmask=0177,
dmask=0077,uid=1000
Apple Partition
user,auto,file_umask=0111,
dir_umask=0000
user,auto,file_umask=0177,
dir_umask=0077,uid=1000

For more on these options see man mount.
Now restart your system and see all partitions you want have been mounted automatically. 🙂

Embedding terminal in Gedit

Categories Editor, Ubuntu

You can embed terminal right in gedit in it’s bottom panel. Gedit has a plugin called “embedded terminal” which is by default not there in plugin lists of gedit. But you can install all remaining plugins using simple command:

user@ubuntu:~$ sudo apt-get install gedit-plugins

After that go to gedit edit>Preferences>Pluins and activate “embedded terminal”. You can see that you also got some new cool plugins. You can activate them according to your need to extend your Gedit.

Screenshot at 2012-02-07 20-27-41

But after activating Embedded Terminal you can see that theme of embedded terminal does not match with your default terminal.

Screenshot at 2012-02-07 20-36-02

You can fix that. But first you need to install dconf-tools. You can do this by issuing following command in terminal:

user@ubuntu:~$ sudo apt-get install dconf-tools
Now start dconf-editor by issuing command dconf-editor or from application menu.
In dconf-editor navigate to org>gedit>plugins>terminal.
Here you can edit background-color, foreground-color, fonts etc. according to your choice.

Screenshot at 2012-02-07 20-43-37

And you can get the look and feel you want for your embedded terminal in Gedit.

Screenshot at 2012-02-07 20-48-11

HAPPY PROGRAMMING!!! 🙂