Django的logging使用

本文详细介绍了Django项目的日志配置方法,包括不同模块的日志级别设置、自定义日志格式、异常邮件通知功能及日志轮换策略。通过自定义中间件记录访问日志,确保了系统的稳定运行与问题快速定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': FORMATTERS,
    'handlers': HANDLERS,
    'loggers': {
        'django': {
            'handlers': ['django', 'mail_admin', 'exception'],
            'level': 'INFO',
            'propagate': False
        },
        'django.db.backends': {
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': False
        },
        'access': {
            'handlers': ['access'],
            'level': 'INFO',
            'propagate': False
        },
        'celery.tasks': {
            'handlers': ['mail_admin'],
            'level': 'INFO',
            'propagate': False
        },
        'parso': {
            'handlers': ['parso'],
            'level': 'INFO'
        }
    },
    'root': {
        'handlers': ['default', 'mail_admin', 'exception'],
        'level': 'DEBUG'
    },
}
If the disable_existing_loggers key in the LOGGING dictConfig is set to True (which is the dictConfig default if the key is missing) then 
all loggers from the default configuration will be disabled.

FORMATTERS
FORMATTERS = {
    'access': {
        'format': '%(client_ip)s %(x_forwarded_ip)s %(asctime)s %(process)d/%(thread)d %(http_user_agent)s '
                  '%(server_name)s %(protocol)s %(path)s %(status)s %(content_length)s %(duration)s '
                  '%(levelname)s %(user)s %(last_login_role)s %(data_b)s %(message)s',
        'datefmt': "%Y/%m/%d %H:%M:%S"
    },
    'django': {
        'format': '[%(asctime)s] %(process)d/%(thread)d %(levelname)s %(message)s',
        'datefmt': "%Y/%m/%d %H:%M:%S"
    },
    'exception': {
        'format': '[%(asctime)s] %(process)d/%(thread)d %(name)s %(funcName)s %(lineno)s %(levelname)s %(message)s',
        'datefmt': "%Y/%m/%d %H:%M:%S"
    },
    'default': {
        'format': '%(asctime)s %(process)d/%(thread)d %(name)s:%(lineno)s %(levelname)s - %(message)s',
        'datefmt': "%Y/%m/%d %H:%M:%S"
    }
}

if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record.

fields:

Attribute name

Format

Description

args

You shouldn’t need to format this yourself.

The tuple of arguments merged into msg to produce message, or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).

asctime

%(asctime)s

Human-readable time when the LogRecord was created. By default this is of the form ‘2003-07-08 16:49:45,896’ (the numbers after the comma are millisecond portion of the time).

created

%(created)f

Time when the LogRecord was created (as returned by time.time()).

exc_info

You shouldn’t need to format this yourself.

Exception tuple (à la sys.exc_info) or, if no exception has occurred, None.

filename

%(filename)s

Filename portion of pathname.

funcName

%(funcName)s

Name of function containing the logging call.

levelname

%(levelname)s

Text logging level for the message ('DEBUG''INFO''WARNING''ERROR''CRITICAL').

levelno

%(levelno)s

Numeric logging level for the message (DEBUGINFOWARNINGERRORCRITICAL).

lineno

%(lineno)d

Source line number where the logging call was issued (if available).

message

%(message)s

The logged message, computed as msg args. This is set when Formatter.format() is invoked.

module

%(module)s

Module (name portion of filename).

msecs

%(msecs)d

Millisecond portion of the time when the LogRecordwas created.

msg

You shouldn’t need to format this yourself.

The format string passed in the original logging call. Merged with args to produce message, or an arbitrary object (see Using arbitrary objects as messages).

name

%(name)s

Name of the logger used to log the call.

pathname

%(pathname)s

Full pathname of the source file where the logging call was issued (if available).

process

%(process)d

Process ID (if available).

processName

%(processName)s

Process name (if available).

relativeCreated

%(relativeCreated)d

Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.

stack_info

You shouldn’t need to format this yourself.

Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record.

thread

%(thread)d

Thread ID (if available).

threadName

%(threadName)s

Thread name (if available).

你也可以自定义

建议在自定义中间件中设置

class LoggingMiddleware(object):
     def __init__(self, get_response):
         self.get_response = get_response
         self.logger = logging.getLogger('django')
         self.logger_access = logging.getLogger('access')
     
    def process_response(self, request, response):
        logging_dict = {
            'duration': time() - request.timer,
            'client_ip': request.META.get('REMOTE_ADDR'),
            'x_forwarded_ip': 
            'path': request.full_path,
            'status': response.status_code,
            'user': user_login_id,
            'last_login_role': last_login_role,
            'http_user_agent': request.META.get('HTTP_USER_AGENT'),
            'server_name': request.META.get('SERVER_NAME'),
            'content_length': request.META.get('CONTENT_LENGTH'),
            'protocol': request.META.get('SERVER_PROTOCOL'),
            'data_b': data_b
        }
        self.logger_access.info(data_c, extra=logging_dict)  # 通过关键字参数extra
HANDLERS
HANDLERS = {
'mail_admin': {
'level': 'ERROR',
'class': 'gacommon.helpers.SendEmailHandler'
},
'django': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': '/logs/server.log',
'when': 'midnight', # 时间后缀
'interval': 1,
'formatter': 'django'
},
'exception': {
'level': 'WARNING',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': '/logs/exception.log',
'when': 'midnight',
'interval': 1,
'formatter': 'exception'
},
'access': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': '/logs/access.log',
'when': 'midnight',
'interval': 1,
'formatter': 'access'
},
'parso': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'default'
},
'default': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': '/logs/default.log',
'when': 'midnight',
'interval': 1,
'formatter': 'default'
}
}

通过自定email,在异常发生时发送邮件

class SendEmailHandler(Handler):
    """An exception log handler that emails log entries to settings.EXCEPTION_MAIL_LIST.
    """
    actitve_count = 0

    @postpone
    def send_admin_mail(self, subject, message, mail_from, mail_to, fail_silently):
        if SendEmailHandler.actitve_count < 5:
            SendEmailHandler.actitve_count += 1
            send_mail(subject, message, mail_from, mail_to, fail_silently=fail_silently)
            SendEmailHandler.actitve_count -= 1
        else:
            pass

    def emit(self, record):
        if os.getenv('DONT_SEND_EXCEPTION_MAIL'):  # 应用于本地开发
            return
subject = '%s: %s %s' % ( ENV.upper(), record.levelname, record.getMessage() ) def format_subject(subject): """ Escape CR and LF characters. """ return subject.replace('\n', ' ').replace('\r', ' ') subject = format_subject(subject) # 邮件标题 message = record.getMessage() + '\n' + traceback.format_exc() self.send_admin_mail(subject, message, EXCEPTION_MAIL_FROM, EXCEPTION_MAIL_LIST, False)

settings中邮件配置

EXCEPTION_MAIL_FROM = ''
EMAIL_HOST = 'smtp.xx.com'
EMAIL_PORT = ''
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = True
EXCEPTION_MAIL_LIST = []

 

转载于:https://www.cnblogs.com/jiaqi-666/p/11097346.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值