简体   繁体   English

如何在不更改python代码的情况下将“print”命令输出重定向到文件?

[英]how to redirect “print” command output to a file without changing the python code?

I want to redirect all the output of my django (1.10.4) app to a file 我想将我的django(1.10.4)应用程序的所有输出重定向到一个文件

Firstly, I tried: 首先,我试过:

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

But it doesn't redirect the output of the print command. 但它不会重定向打印命令的输出。

For example, in my code there is a statement: 例如,在我的代码中有一个声明:

print ('query_content:')

using command: 使用命令:

python manage.py runserver 0.0.0.0:8000

I can see that 'query_content:' is printed out on the screen. 我可以看到屏幕上打印出'query_content:'。

But with : 但是:

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

In the test.log, there are only something like this: 在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
...

One solution is: 一个解决方案是:

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

But sometimes it is impossible to change the python code, is there any solution? 但有时候改变python代码是不可能的,有什么解决方案吗?

update: 更新:

I found that if the log file already exists, then everything is fine. 我发现如果日志文件已经存在,那么一切都很好。 But if I specify a new file name, then the output of python "print ..." statement cannot save the log file. 但是如果我指定一个新的文件名,那么python“print ...”语句的输出就无法保存日志文件。

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

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

I believe that > writes to the file test.log whatever gets logged to console from Django. 我相信>写入文件test.log ,从Django登录到控制台。
print('query_content:') is not getting logged, therefore is not part of Django output. print('query_content:')没有被记录,因此不是Django输出的一部分。

You need to create a logger for your application: 您需要为您的应用程序创建一个记录器:

  1. In settings.py add: 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. Add the following were you want to log something: 如果要记录以下内容,请添加以下内容:

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

Although the above solves your immediate problem, you can take it a step further: 虽然以上解决了您的直接问题,但您可以更进一步:

Add a file handler in your LOGGER configuration: LOGGER配置中添加文件处理程序:

  1. On handlers add: 在处理程序上添加:

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

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

You can customize the above even further, but that is another subject: 您可以进一步自定义上述内容,但这是另一个主题:

More info on python and django logging: 有关python和django日志记录的更多信息:

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

TL;DR: if you have a loop in the end of a file you are feeding to manage.py shell add two newlines in the end. TL; DR:如果你在文件末尾有一个循环,那么你需要在manage.py shell添加两个换行符。

In my case the reason print s were not present in the stdout was because they were never really executed in the first place. 在我的情况下,stdout中没有print的原因是因为它们从未真正执行过。 They were in a for loop that was at the end of file without two newlines or a newline and any other line (with a comment) after it. 它们位于文件末尾的for循环中,没有两个换行符或换行符以及其后的任何其他行(带注释)。 This way the shell was left waiting for a for loop code to be finished and it never was. 通过这种方式,外壳留下等待for循环代码完成,它从来都不是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM