Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to redirect "print" command output to a file without changing the python code?

Tags:

python

django

I want to redirect all the output of my django (1.10.4) app to a file

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.

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:

[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?

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.

like image 892
camino Avatar asked Feb 27 '26 14:02

camino


1 Answers

I believe that > writes to the file test.log whatever gets logged to console from Django.
print('query_content:') is not getting logged, therefore is not part of Django output.

You need to create a logger for your application:

  1. In settings.py add:

    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:

  1. On handlers add:

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

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

You can customize the above even further, but that is another subject:

More info on python and django logging:

  1. https://docs.python.org/3/library/logging.html
  2. https://docs.djangoproject.com/en/2.0/topics/logging/
like image 110
John Moutafis Avatar answered Mar 02 '26 03:03

John Moutafis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!