Django 日志记录项目和应用程序命名空间

发布于 2024-12-27 16:23:58 字数 2775 浏览 0 评论 0原文

我在 Django 日志记录方面遇到问题。顺便说一句,这个问题的答案将帮助我阐明 Django 命名空间是如何工作的。

这是我的项目的结构:

MyProject:
    -App1:
         ....
         views.py
    -App2:
         ....
    urls.py
    settings.py

我喜欢将所有消息记录在一个文件中。然后我在 settings.py 中设置了以下记录器:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
            'verbose': {
                    #'format': '%(levelname)-8s %(remote_addr)-15s %(path_info)s %(asctime)s %(name)-20s %(funcName)-15s %(message)s'
                    'format': '%(levelname)-8s %(asctime)s %(name)-20s %(funcName)-15s %(message)s'
                    },
            },
    'handlers': {
            'normal': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'formatter': 'verbose',
            'filename': os.path.join('C:/dev/Instantaneus/Instantaneus/html/static', 'log', 'normal.log')
        },
            'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
            },
        },
    'loggers': {
        'MyProject': {
                'handlers': ['normal','console'],
                'level': 'DEBUG',
                #'filters': ['request'],
                'propagate': True,
                },
            }
       }

在 urls.py:

from MyProject.App1.views import EvenementDetailView,
....
url(r'App1/(?P<pk>\d+)/$', login_required(EvenementDetailView.as_view(model=Evenement)), name='evenement_details'),

和 App1/views.py: 中

from django.views.generic import DetailView
import logging
logger = logging.getLogger(__name__)

....

class EvenementDetailView(DetailView):
    print __name__
    model=Evenement
    ....
    logger.debug('blabla')

在浏览器中,当我调用 http://localhost/App1/3 时,控制台中出现以下内容:

DEBUG    2012-01-18 14:59:04,503 Myproject.evenements.views EvenementDetailView blabla
MyProject.evenements.views
evenements.views

那么我的问题是为什么 print __name__ 代码执行两次,最重要的是为什么输出不相同?

我认为 DEBUG 日志只出现一次,因为 evenement.views 无法传播到 MyProject,因为在这种情况下根是 evenements

任何想法?

解决方案,没有深入的解释,但它有效:

在我的 urls.py 中,我有一行 url(r'App1/(?P\d+)/activate/$ ', 'app1.views.activate') 其中 'activate' 是 App1/views.py 中的一个函数。我已经更改了 'MyProject.app1.views.activate' 中的 'App1.views.activate' 并且工作正常。我在控制台中只有一行 print __name__。我想我只有一行,因为 'disable_existing_loggers': True,但我无法解释的是,这个解决方案使我的views.py 只解析一次而不是之前解析两次。为了确保这一点,我在文件开头添加了一个 print "blabla" 。在第一种情况下,他打印了两次,而在第二种情况下,他只打印了一次。

I've an issue with Django logging. By the way answers to this question will help me to clarify how Django namespaces work.

Here is the structure of my project:

MyProject:
    -App1:
         ....
         views.py
    -App2:
         ....
    urls.py
    settings.py

I like to log all messages in one file. Then I've setup in settings.py the following logger:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
            'verbose': {
                    #'format': '%(levelname)-8s %(remote_addr)-15s %(path_info)s %(asctime)s %(name)-20s %(funcName)-15s %(message)s'
                    'format': '%(levelname)-8s %(asctime)s %(name)-20s %(funcName)-15s %(message)s'
                    },
            },
    'handlers': {
            'normal': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'formatter': 'verbose',
            'filename': os.path.join('C:/dev/Instantaneus/Instantaneus/html/static', 'log', 'normal.log')
        },
            'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
            },
        },
    'loggers': {
        'MyProject': {
                'handlers': ['normal','console'],
                'level': 'DEBUG',
                #'filters': ['request'],
                'propagate': True,
                },
            }
       }

In urls.py:

from MyProject.App1.views import EvenementDetailView,
....
url(r'App1/(?P<pk>\d+)/

and in App1/views.py:

from django.views.generic import DetailView
import logging
logger = logging.getLogger(__name__)

....

class EvenementDetailView(DetailView):
    print __name__
    model=Evenement
    ....
    logger.debug('blabla')

In the browser, when I call http://localhost/App1/3, the following appears in the console:

DEBUG    2012-01-18 14:59:04,503 Myproject.evenements.views EvenementDetailView blabla
MyProject.evenements.views
evenements.views

Then my question is why the print __name__ code is executed twice and most important why outputs are not the same ?

I suppose that the DEBUG log appear only one time because evenement.views can't propagate to MyProject because in this case root is evenements

Any ideas ?

Solution, not with in depth explanation but it works:

In my urls.py, I had a line url(r'App1/(?P<pk>\d+)/activate/$', 'app1.views.activate') where 'activate' is a function in App1/views.py. I've change 'App1.views.activate' in 'MyProject.app1.views.activate' and it works fine. I've only one line in the console for print __name__. I think I've only one line because of the 'disable_existing_loggers': True, but what I can't explain is that this solution made my views.py only parse one time instead of two times before. To be sure of that I've added a print "blabla" at the beginning of the file. In first case he's printed two times and only onces in second case.

, login_required(EvenementDetailView.as_view(model=Evenement)), name='evenement_details'),

and in App1/views.py:

In the browser, when I call http://localhost/App1/3, the following appears in the console:

Then my question is why the print __name__ code is executed twice and most important why outputs are not the same ?

I suppose that the DEBUG log appear only one time because evenement.views can't propagate to MyProject because in this case root is evenements

Any ideas ?

Solution, not with in depth explanation but it works:

In my urls.py, I had a line url(r'App1/(?P<pk>\d+)/activate/$', 'app1.views.activate') where 'activate' is a function in App1/views.py. I've change 'App1.views.activate' in 'MyProject.app1.views.activate' and it works fine. I've only one line in the console for print __name__. I think I've only one line because of the 'disable_existing_loggers': True, but what I can't explain is that this solution made my views.py only parse one time instead of two times before. To be sure of that I've added a print "blabla" at the beginning of the file. In first case he's printed two times and only onces in second case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

禾厶谷欠 2025-01-03 16:23:58

公平警告:我不确定这是否正确,我的一些内容是基于我记得很久以前读过的东西,但现在在谷歌中找不到。

您所看到的是 python 导入机制工作方式的副作用。导入模块时,它会被放入 sys.modules 中,但是,当可以在两个不同的虚线路径下导入模块时(在本例中,有或没有 MyProject),它可以导入两次,每个__name__下一次。

底层修复是确保 MyProject 它不在 sys.path 上 - 包含 MyProject 的目录应该是,但不是 MyProject 本身。您可以通过启动 manage.py shell 并确保 import Evenements 失败来验证这是否已完成。 manage.py 中的一些 Django 内部机制可能会让这个问题变得困难 - 但我上次遇到这个问题是在 1.0 或 1.1 左右,所以它很可能已经被修复了。

这里有一个深入的讨论:

http ://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

很长的文章,搜索“两个不同的名字”。

Fair warning: I'm not sure this is correct, and I'm basing some of this on stuff I remember reading a long time ago, but can't find in google now.

What you're seeing is a side-effect of how the python import mechanism works. When a module is imported, it's put into sys.modules, however, when it's possible to import the module under two different dotted paths (in this case, with or without MyProject) it can be imported twice, once under each __name__.

The underlying fix is to make sure MyProject it not on sys.path - the directory containing MyProject should be, but not MyProject itself. You can verify that this is done by starting a manage.py shell and making sure import evenements fails. There are some Django internals in manage.py that could make this difficult - but the last time I ran into this was back around 1.0 or 1.1, so it may well have been fixed.

There's an in-depth discussion here:

http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

It's a long article, search for "two different names".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文