-->

Where does stuff “print” to when not running appli

2019-05-26 20:21发布

问题:

So I have a python application that is being bundled into a .app using py2app. I have some debugging print statements in there that would normally print to stdout if I was running the code in the terminal. If I just open the bundled .app, obviously I don't see any of this output. Is any of this actually being printed somewhere even though I don't see it?

回答1:

It goes to standard output (so in the command line, if you are opening it in command line, or eg. to the log, if you are running it with cron jobs).

For more advanced and flexible usage try using built-in logging support (logging module). It allows you to direct messages to the console, to the file, stream (like external logging server), syslog process, email etc., as well as filter based on log message level. Debug statements (logging statements) can then be still placed in the production code, but configured to not cause any logging other than errors. Very useful and simplifies logging a lot.



回答2:

Where the stdout and stderr streams are redirect to depends on how you run the application, and on which OSX release you are.

When you run the application from the Terminal ("MyApp.app/Contents/MacOS/MyApp") the output ends up in the terminal window.

When you run the application by double clicking, or using the open(1) command, the output ends up in Console.app when using OSX before 10.8 and is discarded on OSX 10.8.

I have a patch that redirects output to the logs that Console.app reads even for OSX 10.8, but that is not in a released version at this point in time.

P.S. I'm the maintainer of py2app.



回答3:

I think you may want to take a look at module named logging

You can than use this module to write your own logs into a separate file, for example, that's how I do this:

import logging

# Create a log file for the future debug
LOG_FILE_NAME = 'my-script.log'
log_path = path = os.path.join(os.path.expanduser('~'), '/mnt/logs/') 
if not os.path.exists(log_path):
    os.makedirs(log_path)
logger = logging.getLogger('my-script')
logger.setLevel(logging.DEBUG)
file_handler = logging.FileHandler(log_path+LOG_FILE_NAME)
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(message)s')
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)

class Foo()

    def log(self, msg, level=None):
        print "LOG %s" % msg
        if level is not None:
            if level == 'INFO':
                logger.info(msg)
            elif level == 'WARNING':
                logger.warn(msg)
            elif level == 'ERROR':
                logger.error(msg)
            elif level == 'CRITICAL':
                logger.critical(msg)
        else:
            logger.debug(msg) # DEBUG

    self.log('Some text here', 'DEBUG') # I use self.log instead of print