0

I'm writing a python program that will run in a container, I'm sharing a directory with this container to save all logs. But I can't redirect the output.

Are there a way inside the python code to redirect all output to file?

Python 2.7

3 Answers3

1

If this is just for some development testing, this should work ok.

>>> import sys
>>> f = open("/tmp/stdout", "w")
>>> sys.stdout = f
>>> print "Hello"
>>> print "Whoa"

> cat /tmp/stdout
Hello
Whoa

You may want to periodically call sys.stdout.flush() to get more real-time output.

You could also use a wrapper like this (stolen from Disable output buffering):

class Unbuffered(object):
   def __init__(self, stream):
       self.stream = stream
   def write(self, data):
       self.stream.write(data)
       self.stream.flush()
   def __getattr__(self, attr):
       return getattr(self.stream, attr)

Then you would do

sys.stdout = Unbuffered(open("/tmp/stdout", "w"))
print "foo"
print "bar"

if you need sys.stdout back, you should be able to do

sys.stdout = sys.__stdout__
Community
  • 1
  • 1
sberry
  • 128,281
  • 18
  • 138
  • 165
  • 1
    Or just `print >>f, "Hello"` instead of changing `sys.stdout`. – Vincent Savard Feb 11 '16 at 18:46
  • @VincentSavard I was going to suggest that, but figured the OP has a bunch of print statements that they don't want to change all over the place. – sberry Feb 11 '16 at 18:48
  • It's possible, though in this case I'd probably suggest redirecting the output with the help of his shell, e.g. `python foo.py > log.txt`. The question could benefit from additional information. – Vincent Savard Feb 11 '16 at 18:49
  • I tried it, but it write all the output just after the execution, and I want to track log on the fly. – Franciscon Santos Feb 11 '16 at 18:51
  • @VincentSavard That is also true, but I took the statement "But I can't redirect the output." to mean the OP couldn't redirect like that. – sberry Feb 11 '16 at 18:51
  • To disable buffering, it's enough to pass `buffering=0` to `open()`, no need for wrappers – Andrea Corbellini Feb 11 '16 at 21:13
1

You can give a file handle to sys.stdout and sys.stderr to redirect the output or errors to a file.

For example:

stdo=sys.stdout
# need a file handle with write mode
fhandle=open("out.txt",'w');
sys.stdout=fhandle

print "I'm the output~"
......
# reset the standard output
sys.stdout=stdo
platinhom
  • 139
  • 10
0

If you want both at the same time you can do this

class OutputLogger(object):
    def __init__(self, output_file='/tmp/output_file.txt'):
        self.std = sys.stdout
        self.outfile = open(output_file, 'w')
    def write(self, message):
        self.std.write(message)
        self.outfile.write(message)
    def flush(self):
        self.outfile.flush()
        self.std.flush()

And use it like

import sys
sys.stdout = OutputLogger(path_to_file)
print 'Hello Logger'
Mr. E
  • 2,070
  • 11
  • 23