【问题标题】:How to get logging working with django?如何使用 django 进行日志记录?
【发布时间】:2018-04-23 15:04:36
【问题描述】:

我正在测试我自己的身份验证后端,如 here 所述。我添加了一些日志记录。请排除这两个我知道的问题:

  • 我正在使用root 记录器(坏)
  • 我正在使用error 日志级别(错误)

(我只是想找出为什么我的日志消息没有显示,并想确保我达到了一个工作记录器/级别)

import logging

from django.conf import settings
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import User


class SettingsBackend:
    """
    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

    Use the login name and a hash of the password. For example:

    ADMIN_LOGIN = 'admin'
    ADMIN_PASSWORD = 'pbkdf2_sha256$30000$Vo0VlMnkR4Bk$qEvtdyZRWTcOsCnI/oQ7fVOu1XAURIZYoOZ3iq8Dr4M='
    """

    def authenticate(self, request, username=None, password=None):
        logging.error('authenticate')
        login_valid = (settings.ADMIN_LOGIN == username)
        pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
        logger.error('username={} login_valid={} pwd_valid={}'.format(username, login_valid, pwd_valid))
        if login_valid and pwd_valid:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # Create a new user. There's no need to set a password
                # because only the password from settings.py is checked.
                user = User(username=username)
                user.is_staff = True
                user.is_superuser = True
                user.save()
            return user
        return None

    def get_user(self, user_id):
        logging.error('get_user')
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

    def has_perm(self, user_obj, perm, obj=None):
        logging.error('has_perm')
        return user_obj.username == settings.ADMIN_LOGIN

我已将此设置为我唯一的身份验证后端:

AUTHENTICATION_BACKENDS = (
    'extras.auth.SettingsBackend',
    # 'django.contrib.auth.backends.ModelBackend',
    # 'allauth.account.auth_backends.AuthenticationBackend',
)

我已经配置了我的管理员用户:

# Used by SettingsBackend

ADMIN_LOGIN = 'admin'
ADMIN_PASSWORD = 'pbkdf2_sha256$36000$9pA3fTzM4yL9$whatever'

我这里有很多问题:

  1. 日志条目没有显示,也没有被 django 调试工具栏截获。
  2. 身份验证根本不起作用。即使强制login_valid = Truepwd_valid = True,我也无法获得经过身份验证的用户。

我知道authenticate 方法被命中,因为如果我重命名它,我会得到一个异常 ('SettingsBackend' object has no attribute 'authenticate'),正如预期的那样。

我有两个问题:

第一个问题:如何让日志条目显示出来?把它们放在顶级作品中!如图所示:

import logging

from django.conf import settings
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import User

logging.error('Loading module')

...

这给了我,正如预期的那样(加载模块时一次):

ERROR:root:Loading module

第二个问题:为什么authenticate 方法会失败? (这不是那么重要,我想一旦我开始记录工作,我就能找出它的问题所在)

注意:为了记录,应用程序在gunicorn下以wsgi应用程序运行。

编辑

我正在使用:

  • Django 1.10.8
  • Python 3.5.2

【问题讨论】:

  • 您的 authenticate 方法在我的开发(包括日志记录)中使用 Django 1.11.2 和 Python 3.5.2 效果很好(顺便说一句,您有一个小错字 logger.error)。您是否在开发中的 runserver 上尝试过常规的 print
  • @SébastienDeprez 感谢您的试用!还没有,我一大早就试试。我尝试了常规的print 调用,但wsgi 应用程序不允许使用它们,我想让开发和产品保持一致。错字不是这样的:我想实际使用logging.error 而不是logger.error(实际上我正在删除logger,因为它具有误导性)。我想使用根记录器。
  • @SébastienDeprez in dev (with manage.py runsslserver) 我没有让它工作,即使是print 电话。看起来,虽然authenticate 方法以某种方式被访问,但它并没有被执行:放置一个错误的语句XXX 没有效果。
  • @SébastienDeprez 我发现了问题:authenticate 的签名已从 Django 1.10 -> Django 1.11 更改。我从 Django 1.11 开始,authenticate 方法正在工作,在某些时候我因为其他问题降级到 Django 1.10。进行降级时,我不知道此签名更改。现在我正在测试它,它默默地失败了(不知道为什么),而且很难理解为什么。
  • 好的,很高兴你找到它!您可能可以自己回答以帮助未来的读者。

标签: django authentication logging django-debug-toolbar


【解决方案1】:

问题与 Django 版本的降级有关,从 Django 1.11 降级到 Django 1.10authenticate 方法的签名已更改。它正在被访问,但不知何故没有被执行,也没有生成日志条目。

我不完全明白为什么:

  1. authenticate 方法没有被执行。签名已更改,但它具有默认值,它应该仍然有效(为参数分配了错误的值)
  2. 如果有什么东西阻止了authenticate 方法的执行,为什么没有产生异常?

无论如何,在将签名调整为 Django 1.10 所期望的签名后,一切都开始按预期工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2011-10-21
    • 2015-12-14
    • 1970-01-01
    • 2016-06-05
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多