Metadata-Version: 2.3
Name: django-discordo
Version: 0.2.0
Summary: Discord webhook handler for Django logging
Keywords: django,discord,logging,webhook,handler
Author: Evan Chen
Author-email: Evan Chen <evan@evanchen.cc>
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Logging
Requires-Dist: django>=3.2
Requires-Dist: requests>=2.25.0
Requires-Python: >=3.8
Project-URL: Homepage, https://github.com/vEnhance/django-discordo
Project-URL: Issues, https://github.com/vEnhance/django-discordo/issues
Project-URL: Repository, https://github.com/vEnhance/django-discordo
Description-Content-Type: text/markdown

# django-discordo

A janky Discord webhook handler for Django logging
originally written for [OTIS-WEB](https://github.com/vEnhance/otis-web).

## Features, apparently

- 🎨 Color-coded log levels with emoji indicators
- 📝 Automatic formatting of Django request data
- 🔒 Automatic redaction of sensitive data (passwords, tokens)
- 🎯 Support for custom log levels (VERBOSE, SUCCESS, ACTION)
- 🔧 Configurable webhook URLs per log level
- 📊 Rich metadata including user info, status codes, and stack traces

## Installation

For example, if using `uv`:

```bash
uv add django-discordo
```

## Configuration

### 1. Create a Discord Webhook

1. Go to Server Settings → Integrations → Webhooks
2. Click "New Webhook"
3. Copy the webhook URL

### 2. Configure Webhook URL

There are two possible ways to do this (first one takes precedence):

#### Use settings.py

Add your webhook URL to your Django `settings.py`:

```python
# Simple configuration - single webhook for all log levels
DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/YOUR_WEBHOOK_URL"

# OR: Advanced configuration - different webhooks per log level
DISCORD_WEBHOOK_URLS = {
    "CRITICAL": "https://discord.com/api/webhooks/CRITICAL_WEBHOOK",
    "ERROR": "https://discord.com/api/webhooks/ERROR_WEBHOOK",
    "WARNING": "https://discord.com/api/webhooks/WARNING_WEBHOOK",
    "DEFAULT": "https://discord.com/api/webhooks/DEFAULT_WEBHOOK",  # Fallback for other levels
}
```

(Webhook URL's are considered secrets,
so you probably don't want to actually hardcode the URL's into `settings.py`
if your source code is public.)

#### Using environment variables directly

If the URL's are not configured in `settings.py` then `django-discordo` will
check environment variables instead:

```bash
# In your .env file
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_URL
# Or level-specific
DISCORD_WEBHOOK_URL_ERROR=https://discord.com/api/webhooks/YOUR_ERROR_WEBHOOK_URL
```

### 3. Update Django Settings

Add the Discord handler to your Django `settings.py`, e.g.

```python
import logging

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "discord": {
            "class": "django_discordo.DiscordWebhookHandler",
            "level": "WARNING",
        },
    },
    "root": {
        "handlers": ["discord"],
        "level": "INFO",
    },
}
```

## Custom Log Levels

django-discordo provides three custom log levels in addition to Django's standard levels:

- **VERBOSE** (level 15): Between DEBUG and INFO, for detailed but not critical information
- **SUCCESS** (level 25): Between INFO and WARNING, for successful operations
- **ACTION** (level 35): Between WARNING and ERROR, for important user actions

### Usage Example

```python
import logging
from django_discordo import VERBOSE_LOG_LEVEL, SUCCESS_LOG_LEVEL, ACTION_LOG_LEVEL

logger = logging.getLogger(__name__)

# Using custom log levels
logger.log(VERBOSE_LOG_LEVEL, "Student has submitted the problem set.")
logger.log(SUCCESS_LOG_LEVEL, "Student has found new diamond.")
logger.log(ACTION_LOG_LEVEL, "Student has updated a link in ARCH, please check it.")
```

## Advanced Configuration

### Filtering Logs

You can add filters to prevent certain logs from being sent to Discord;
e.g. OTIS-WEB filters out certain 404 errors

```python
def filter_useless_404(record):
    if record.args and len(record.args) >= 2:
        return "wp-include" not in str(record.args[1])
    return True

LOGGING = {
    "filters": {
        "filter_useless_404": {
            "()": "django.utils.log.CallbackFilter",
            "callback": filter_useless_404,
        },
    },
    "handlers": {
        "discord": {
            "class": "django_discordo.DiscordWebhookHandler",
            "level": "WARNING",
            "filters": ["filter_useless_404"],
        },
    },
}
```

## Testing Mode

When running tests, you may want to disable Discord logging to avoid spam:

```python
import logging
from django_discordo import ACTION_LOG_LEVEL

if TESTING:
    logging.disable(ACTION_LOG_LEVEL)
```

This disables all logs at ACTION level and below (including SUCCESS, INFO, VERBOSE, and DEBUG).

## How It Works

When a log record is emitted:

1. The handler formats the log message with appropriate emoji and color
2. Extracts metadata (user, module, filename, line number, status code)
3. Includes Django request details (method, path, user agent, POST data)
4. Redacts sensitive fields (passwords, tokens)
5. Sends a beautifully formatted embed to Discord via webhook

## Discord Embed Format

Each log message appears as a Discord embed with:

- **Title**: Log message (with emoji indicator)
- **Color**: Coded by log level (red for errors, yellow for warnings, etc.)
- **Fields**: Status code, log level, module, user, filename
- **Description**: Detailed message, exception traceback, and request data
