Как сохранять журналы в S3Boto3Storage с помощью Django Logging

Мне нужно сохранять журналы в файл на выделенном хранилище (используя S3BotoStorage). Я пока не нашел никакого рабочего решения. Кто-нибудь знает, как заставить это работать? Мне нужно включить что-то похожее на logging.handlers.RotatingFileHandler с резервными копиями.

Вот мой файл settings.py:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'standard',
            'filters': [],
        },
        'file': {
            'level': 'INFO',
            'class': 'fundamental.cdn.backends.LogsRootS3BotoStorage',
            'formatter': 'standard',
            'filename': 'logs.log',
        },
    },
    'loggers': {
        logger_name: {
            'level': 'INFO',
            'propagate': True,
            'handlers': [],#['file'],
        } for logger_name in ('django', 'django.request', 'django.db.backends', 'django.template', 'articles')
    },
    'root': {
        'level': 'DEBUG',
        'handlers': ['console'],
    }
}

это cdn.backed

from storages.backends.s3boto3 import S3Boto3Storage

...

class LogsRootS3BotoStorage(S3Boto3Storage):
    location = "logs"
    file_overwrite = False

Чтобы вести журнал непосредственно в ведро S3 в Django с помощью S3BotoStorage, вам нужно создать пользовательский обработчик журнала, который наследует от logging.Handler и использует ваш класс LogsRootS3BotoStorage для взаимодействия с S3. Этот обработчик должен форматировать записи журнала и загружать их в S3, при необходимости осуществляя ротацию журнала путем управления именами файлов или используя возможности версионирования S3. Включите этот обработчик в конфигурацию Django LOGGING, указав его в разделе обработчиков и назначив его соответствующим логгерам. примерно так:

import logging
from storages.backends.s3boto3 import S3Boto3Storage

class S3LoggingHandler(logging.Handler):
    def __init__(self, bucket_name, log_file_prefix):
        logging.Handler.__init__(self)
        self.s3_client = S3Boto3Storage(bucket_name=bucket_name)
        self.log_file_prefix = log_file_prefix

    def emit(self, record):
        log_entry = self.format(record)
        # Implement your logic for rotating file names or managing versions here
        file_name = f"{self.log_file_prefix}.log"
        self.upload_log_to_s3(file_name, log_entry)

    def upload_log_to_s3(self, file_name, log_entry):
        # Append to the file if it exists, else create a new file
        try:
            # Try to read the existing log file from S3
            content = self.s3_client.open(file_name).read()
            new_content = content + '\n' + log_entry
        except:
            new_content = log_entry
        # Write back the updated content
        self.s3_client.save(file_name, new_content)

# Example usage in settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        's3': {
            'level': 'INFO',
            'class': 'path.to.S3LoggingHandler',
            'bucket_name': 'your-s3-bucket-name',
            'log_file_prefix': 'logs/my_app_log',
        },
    },
    'loggers': {
        # Your logger configuration
    },
}

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