Django 日志记录项目和应用程序命名空间
我在 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
其中 '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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
公平警告:我不确定这是否正确,我的一些内容是基于我记得很久以前读过的东西,但现在在谷歌中找不到。
您所看到的是 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 onsys.path
- the directory containingMyProject
should be, but notMyProject
itself. You can verify that this is done by starting amanage.py shell
and making sureimport evenements
fails. There are some Django internals inmanage.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".