Logging

Back

Loading concept...

Django Logging: Your App’s Secret Diary πŸ“–

Imagine you have a magical diary that writes itself. Every time something happens in your roomβ€”a toy falls, a friend visits, or you find a lost sockβ€”the diary automatically records it. That’s exactly what logging does for your Django app!


The Story of the Helpful Diary

Once upon a time, there was a busy toy store (your Django app). The store owner needed to know everything happening insideβ€”when customers arrived, when toys broke, or when something went wrong. So they hired four special helpers:

  1. The Logging Configuration - The diary’s rulebook
  2. Loggers and Handlers - The writers and delivery people
  3. Log Levels and Formatting - The importance labels and handwriting style
  4. Built-in Loggers - Django’s own team of diarists

Let’s meet each one!


1. Logging Configuration πŸ”§

What Is It?

The logging configuration is like setting up rules for your diary. It answers questions like:

  • Where should messages go? (A file? The screen?)
  • How detailed should they be?
  • What format should they follow?

The Magic Spell (settings.py)

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'DEBUG',
    },
}

What does this mean?

Part Meaning
version: 1 Always use 1 (it’s the only version!)
disable_existing_loggers Keep Django’s own loggers working
handlers Where to send messages
root The main logger settings

Real-World Example

# A complete, beginner-friendly setup
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
        },
    },
    'loggers': {
        'myapp': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

2. Loggers and Handlers 🎭

The Story

Think of Loggers as writers who write messages. Handlers are delivery people who decide where those messages go.

graph TD A["Your Code"] --> B["Logger"] B --> C["Handler 1: Console"] B --> D["Handler 2: File"] B --> E["Handler 3: Email"] C --> F["Your Screen"] D --> G["log.txt"] E --> H["Your Inbox"]

Creating a Logger

import logging

# Create your personal writer
logger = logging.getLogger('myapp')

# Now write messages!
logger.info('A customer arrived!')
logger.warning('Running low on toys!')
logger.error('A toy broke!')

Common Handlers

Handler What It Does Example
StreamHandler Prints to screen See errors while coding
FileHandler Writes to a file Keep a permanent record
RotatingFileHandler Creates new files when full Avoid giant log files
SMTPHandler Sends emails Alert for critical errors

Example: File Handler Setup

'handlers': {
    'file': {
        'class': 'logging.FileHandler',
        'filename': 'debug.log',
        'formatter': 'simple',
    },
},

3. Log Levels and Formatting ⭐

The Importance Ladder

Not all messages are equally important. Log levels are like shouting volumes:

graph TD A["DEBUG πŸ”"] --> B["INFO ℹ️"] B --> C["WARNING ⚠️"] C --> D["ERROR ❌"] D --> E["CRITICAL 🚨"] style E fill:#ff6b6b style D fill:#ffa94d style C fill:#ffd43b style B fill:#69db7c style A fill:#748ffc
Level Number When to Use
DEBUG 10 Tiny details (for detectives)
INFO 20 Normal events (β€œUser logged in”)
WARNING 30 Something odd (β€œLow disk space”)
ERROR 40 Something broke
CRITICAL 50 EMERGENCY! App might crash

Using Levels in Code

import logging
logger = logging.getLogger('myapp')

logger.debug('Checking inventory...')
logger.info('New order placed!')
logger.warning('Only 5 toys left!')
logger.error('Payment failed!')
logger.critical('Database down!')

Formatting: Making Messages Pretty

Formatters decide how messages look. Think of it as choosing a handwriting style.

'formatters': {
    'detailed': {
        'format': '{asctime} {levelname} {name} {message}',
        'style': '{',
    },
},

Output:

2024-01-15 10:30:45 INFO myapp New order placed!

Format Variables

Variable Shows
{asctime} Date and time
{levelname} DEBUG, INFO, etc.
{name} Logger name
{message} Your message
{filename} Which file
{lineno} Which line number

4. Django Built-in Loggers 🏭

Django comes with its own team of writers, already watching different parts of your app!

The Built-in Team

graph TD A["Django Built-in Loggers"] A --> B["django"] A --> C["django.request"] A --> D["django.server"] A --> E["django.template"] A --> F["django.db.backends"] A --> G["django.security"]

What Each Logger Watches

Logger What It Records
django The parent of all Django loggers
django.request Every web request (404s, 500s)
django.server Development server messages
django.template Template errors
django.db.backends Database queries
django.security Security issues

Example: Capture Database Queries

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

Now you’ll see every database query!

Example: Catch 404 and 500 Errors

'loggers': {
    'django.request': {
        'handlers': ['file'],
        'level': 'WARNING',
    },
},

Putting It All Together 🎁

Here’s a complete, production-ready setup:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '{asctime} {levelname} {name}: {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'standard',
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'app.log',
            'formatter': 'standard',
        },
    },
    'loggers': {
        'myapp': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
        'django.request': {
            'handlers': ['file'],
            'level': 'WARNING',
        },
    },
}

Quick Reference Card πŸƒ

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LOGGING = {                        β”‚
β”‚    'version': 1,                    β”‚
β”‚    'formatters': {...},             β”‚
β”‚    'handlers': {...},               β”‚
β”‚    'loggers': {...},                β”‚
β”‚  }                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

logger = logging.getLogger('name')
logger.debug()    ← Tiny details
logger.info()     ← Normal events
logger.warning()  ← Odd things
logger.error()    ← Broken things
logger.critical() ← EMERGENCY!

You Did It! πŸŽ‰

You now understand Django logging like a pro:

βœ… Configuration - Setting up the rules βœ… Loggers - The message writers βœ… Handlers - Where messages go βœ… Levels - How important each message is βœ… Formatting - How messages look βœ… Built-in Loggers - Django’s own helpers

Your Django app now has a magical self-writing diary. Every bug, every visitor, every problemβ€”all recorded automatically. Happy logging! πŸš€

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.