Подскажите, пожалуйста, как реализовать ведение журнала в django таким образом, чтобы передавать журналы в базу данных, а не в файл?

Вот моя реализация

//myproject/settings.py

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sitemaps',
    'logger.apps.LoggerConfig',
]

# Logging
# https://docs.djangoproject.com/en/5.0/topics/logging/

LOGGING_CONFIG = None  # Disable the automatic configuration

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 %(asctime)s %(message)s'
        },
    },
    'handlers': {
        'database': {
            'level': 'DEBUG',
            'class': 'logger.handler.DatabaseLogHandler',
            'formatter': 'verbose'
        },
        'browser': {
            'level': 'DEBUG',
            'class': 'logger.handler.BrowserLogHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['database', 'browser'],
            'level': 'DEBUG',
            'propagate': True,
        },
        'django.request': {
            'handlers': ['database', 'browser'],
            'level': 'ERROR',
            'propagate': False,
        },
        'security': {
            'handlers': ['database', 'browser'],
            'level': 'INFO',
            'propagate': False,
        },
    },
}

//myproject/logger/apps.py

from django.apps import AppConfig


class LoggerConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'logger'

//myproject/logger/handlers.py

import logging
from django.utils.timezone import now

import logging


class DatabaseLogHandler(logging.Handler):
    def emit(self, record):
        from logger.models import LogEntry
        log_entry = LogEntry(
            level=record.levelname,
            message=record.getMessage(),
            logger_name=record.name,
            filepath=record.pathname,
            func_name=record.funcName,
            lineno=record.lineno
        )
        log_entry.save()


class BrowserLogHandler(logging.Handler):
    logs = []

    def emit(self, record):
        log_entry = {
            'logger_name': record.name,
            'level': record.levelname,
            'message': record.getMessage(),
            'timestamp': now().isoformat()
        }
        self.logs.append(log_entry)

    @classmethod
    def get_logs(cls):
        logs = cls.logs[:]
        cls.logs.clear()
        return logs

//myproject/logger/models.py

from django.db import models
from django.utils.translation import gettext_lazy as _

class LogEntry(models.Model):
    timestamp = models.DateTimeField(auto_now_add=True)
    level = models.CharField(max_length=50)
    message = models.TextField()
    logger_name = models.CharField(max_length=255)
    filepath = models.CharField(max_length=255, blank=True, null=True)
    func_name = models.CharField(max_length=255, blank=True, null=True)
    lineno = models.IntegerField(blank=True, null=True)

//myproject/logger/views.py

from django.http import JsonResponse, HttpResponse
from logger.handlers import BrowserLogHandler
import logging

# Get instances of loggers
default_logger = logging.getLogger('django')
error_logger = logging.getLogger('django.request')
security_logger = logging.getLogger('security')

def my_view(request):
    default_logger.debug('This is a debug message')
    default_logger.info('This is an info message')
    default_logger.warning('This is a warning message')
    error_logger.error('This is an error message')
    security_logger.critical('This is a critical message')
    return HttpResponse("Logging to multiple files and displaying in the browser!")

def get_logs(request):
    logs = BrowserLogHandler.get_logs()
    return JsonResponse({'logs': logs})

Когда я пытаюсь запустить миграции, когда LOGGING_CONFIG = None

Я получаю эту ошибку

Traceback (most recent call last):
  File "/home/ramses/Desktop/Themeforest/api/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
  File "/home/ramses/Desktop/Themeforest/api/venv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 329, in execute
    return super().execute(query, params)
sqlite3.OperationalError: no such table: logger_logentry

The above exception was the direct cause of the following exception:

Но файл миграции не был создан

Но когда я удаляю строку

LOGGING_CONFIG = None

Миграции выполняются успешно, но журналы не сохраняются в базе данных

Вернуться на верх