13

I have three classes in python and they run in different threads. I would like to have output to the same file from all classes. Right now I created output method in main class and passing it through constructors to other classes. Is there way to handle it better? How I can pass the logger between classes except using contructors?

Perhaps python supports something like static method in Java, so I can write like Logger.info(message) in all three classes?

Another way probably could be redirecting global sys.stdout to the file, i.e specifying

logger = open('debug.txt', 'w')
sys.stdout = logger

Then using calls sys.stdout in all classes.

What do you think?

1 Answer 1

25
import logging
log = logging.getLogger("mylog")
log.setLevel(logging.DEBUG)

formatter = logging.Formatter(
    "%(asctime)s %(threadName)-11s %(levelname)-10s %(message)s")
# Alternative formatting available on python 3.2+:
# formatter = logging.Formatter(
#     "{asctime} {threadName:>11} {levelname} {message}", style='{')

# Log to file
filehandler = logging.FileHandler("debug.txt", "w")
filehandler.setLevel(logging.DEBUG)
filehandler.setFormatter(formatter)
log.addHandler(filehandler)

# Log to stdout too
streamhandler = logging.StreamHandler()
streamhandler.setLevel(logging.INFO)
streamhandler.setFormatter(formatter)
log.addHandler(streamhandler)

# Test it
log.debug("Some message")
log.error("An error!")
try:
    something()
except:
    log.exception("An exception occured!")

And get in debug.txt:

2011-01-18 12:07:24,943  MainThread  DEBUG      Some message
2011-01-18 12:07:24,943  MainThread  ERROR      An error!
2011-01-18 12:07:24,943  MainThread  ERROR      An exception occured!
Traceback (most recent call last):
  File "./logtest.py", line 17, in 
    something()
NameError: name 'something' is not defined

Note that the order in which the messages appear in the log file may not correspond exactly to the order in which they happened when you're logging from several threads.

Sign up to request clarification or add additional context in comments.

9 Comments

@lazyr. Thank you for the answer. How I can pass the log object between classes so all three files and it will write to the same log file?
I have the code above in a separate file, say log.py, then I go "from log import log" in each of my other modules. Python only loads a module once -- any import statements after the first merely fetch what has already been loaded -- so it will be the same log object in all your threads.
@lazyr: In case of the logging module, you don't need to do that -- logging module itself keeps the loggers it creates inside its own module. You can just run logging.getLogger again in another module and you'll get the same object.
It looks nice and organized, but i tried it and it didn't work. This is the Output: pastebin.com/86mKZp8r
@athspk It's part of the old-style python string formatting specification, and it means to left adjust with a field width of 24. Please learn and use the new string formatting mini-language instead of the old one if you start from scratch, since it has numerous improvements over the old one.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.