【问题标题】:how to redirect "print" command output to a file without changing the python code?如何在不更改 python 代码的情况下将“打印”命令输出重定向到文件?
【发布时间】:2018-04-18 03:01:27
【问题描述】:

我想将我的 django (1.10.4) 应用程序的所有输出重定向到一个文件

首先,我尝试了:

python manage.py runserver 0.0.0.0:8000 >test.log 2>&1

但它不会重定向打印命令的输出。

例如,在我的代码中有一条语句:

print ('query_content:')

使用命令:

python manage.py runserver 0.0.0.0:8000

我可以看到屏幕上打印出“query_content:”。

但是有:

python manage.py runserver 0.0.0.0:8000 >test.log 2>&1

在 test.log 中,只有这样的内容:

[05/Nov/2017 20:38:20] "GET ... HTTP/1.1" 200 22404
[05/Nov/2017 20:38:26] "POST ... HTTP/1.1" 200 13
[05/Nov/2017 20:38:26] "GET .... HTTP/1.1" 200 16800
[05/Nov/2017 20:38:30] "GET ... 200 22430
...

一种解决方案是:

import sys
sys.stdout = open('file', 'w')
print 'test'

但有时无法更改python代码,有什么解决办法吗?

更新:

我发现如果日志文件已经存在,那么一切都很好。 但是如果我指定一个新的文件名,那么python“print ...”语句的输出就不能保存日志文件了。

【问题讨论】:

  • 可能预期的输出实际上是正确输出的,但它是缓冲的,因此如果它与 stderr 输出混合,可能不会出现在您预期的位置。考虑在启动服务器时对 python 使用“-u”选项(这会影响性能)
  • 无法复制。在我的 Django 1.10 中运行良好。
  • @JohnAnderson 看来问题与缓存有关。
  • 没有办法,除了源代码,你不能干涉一个进程。您可以通过监听本地环回地址(原始套接字)的 8000 端口来做到这一点。

标签: python django


【解决方案1】:

我相信 > 写入文件 test.log 任何从 Django 登录到控制台的内容。
print('query_content:') 没有被记录,因此不是 Django 输出的一部分。

您需要为您的应用程序创建一个记录器:

  1. settings.py 中添加:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
        'standard': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
    },
    'handlers': {
        # This logs to the console
        'console':{
            'level':'INFO',
            'class':'logging.StreamHandler',
            'formatter': 'standard'
        },
    },
    'loggers': {
        'django': {
            'handlers':['console'],
            'propagate': True,
            'level':'INFO',
         },
    },
    
  2. 如果您想记录一些内容,请添加以下内容:

    import logging
    mylogger = logging.getLogger(__name__)
    
    
    ...
    logger.info('query content: {}'.format(your_query_content))
    ...
    

虽然以上解决了你眼前的问题,但你可以更进一步:

LOGGER 配置中添加文件处理程序:

  1. 在处理程序上添加:

    'file': {  
        'class': 'logging.FileHandler',
        'filename': 'a/file/location/logs.log',  
        'formatter': 'standard'
    },
    
  2. loggers.django 上更新处理程序:

    'handlers':['console', 'file'], 
    

您可以进一步自定义上述内容,但这是另一个主题:

有关 python 和 django 日志记录的更多信息:

  1. https://docs.python.org/3/library/logging.html
  2. https://docs.djangoproject.com/en/2.0/topics/logging/

【讨论】:

  • 看来你是对的,谢谢!我明天试试你的建议
  • @int_ua 让我知道结果。我建议使用文件记录方法!
  • TL;DR:你得到了赏金。在此过程中,我找到了问题的真正原因,并将其作为单独的答案发布。另外,我没有时间真正测试这个建议,但它绝对很有趣,所以我要奖励赏金。真正的测试取决于您或任何未来的读者。
  • @int_ua 好的,伙计!快乐编码,期待您的回答!
【解决方案2】:

我认为这个shell命令可能可以输出结果。

python manage.py runserver 0.0.0.0:8000 2>&1 | tee file.txt

【讨论】:

  • 查询不是输出!
【解决方案3】:

TL;DR:如果您要提供给manage.py shell 的文件末尾有一个循环,请在末尾添加两个换行符。

在我的情况下,prints 没有出现在标准输出中的原因是因为它们从一开始就没有真正执行过。它们位于文件末尾的for 循环中,没有两个 换行符或换行符和任何其他行(带有注释)之后。这样一来,shell 就一直在等待 for 循环代码完成,但它从来没有完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-02
    • 2014-09-05
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 2011-05-05
    相关资源
    最近更新 更多