Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask logging - Cannot get it to write to a file

Ok, here's the code where I setup everything:

if __name__ == '__main__':     app.debug = False      applogger = app.logger      file_handler = FileHandler("error.log")     file_handler.setLevel(logging.DEBUG)      applogger.setLevel(logging.DEBUG)     applogger.addHandler(file_handler)      app.run(host='0.0.0.0') 

What happens is

  1. error.log gets created
  2. Nothing is ever written to it
  3. Despite not adding a StreamHandler and setting debug to false I still get everything to STDOUT (this might be correct, but still seems weird)

Am I totally off here somewhere or what is happening?

like image 621
fleshgolem Avatar asked Jul 19 '13 09:07

fleshgolem


People also ask

How do you make a log file in Flask?

Logging To A FileFirst, you need to remove the default handler Flask provides, so you can later use your own. Then choose a folder and a filename in which you will keep to logs. If the directory does not exist, the program will create it.

What is debug mode in Flask?

Flask Debug mode allows developers to locate any possible error and as well the location of the error, by logging a traceback of the error. The Flask debug mode also enables developers to interactively run arbitrary python codes, so that one can resolve and get to the root cause on why an error happened.

Where do Flask logs go?

Using the Default Logging System for Flask Flask uses the Python logging system itself to trace out events during the application's run-time. Python Logging has a default Logger – BasicConfig which we can use to log our messages. The logs are stored in files with . log extension.


2 Answers

Why not do it like this:

if __name__ == '__main__':     init_db()  # or whatever you need to do      import logging     logging.basicConfig(filename='error.log',level=logging.DEBUG)      app.run(host="0.0.0.0") 

If you now start you application, you'll see that error.log contains:

INFO:werkzeug: * Running on http://0.0.0.0:5000/ 

For more info, visit http://docs.python.org/2/howto/logging.html

Okay, as you insist that you cannot have two handler with the method I showed you, I'll add an example that makes this quite clear. First, add this logging code to your main:

import logging, logging.config, yaml logging.config.dictConfig(yaml.load(open('logging.conf'))) 

Now also add some debug code, so that we see that our setup works:

logfile    = logging.getLogger('file') logconsole = logging.getLogger('console') logfile.debug("Debug FILE") logconsole.debug("Debug CONSOLE") 

All what is left is the "logging.conf" program. Let's use that:

version: 1 formatters:   hiformat:     format: 'HI %(asctime)s - %(name)s - %(levelname)s - %(message)s'   simple:     format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' handlers:   console:     class: logging.StreamHandler     level: DEBUG     formatter: hiformat     stream: ext://sys.stdout   file:     class: logging.FileHandler     level: DEBUG     formatter: simple     filename: errors.log loggers:   console:     level: DEBUG     handlers: [console]     propagate: no   file:     level: DEBUG     handlers: [file]     propagate: no root:   level: DEBUG   handlers: [console,file] 

This config is more complicated than needed, but it also shows some features of the logging module.

Now, when we run our application, we see this output (werkzeug- and console-logger):

HI 2013-07-22 16:36:13,475 - console - DEBUG - Debug CONSOLE HI 2013-07-22 16:36:13,477 - werkzeug - INFO -  * Running on http://0.0.0.0:5000/ 

Also note that the custom formatter with the "HI" was used.

Now look at the "errors.log" file. It contains:

2013-07-22 16:36:13,475 - file - DEBUG - Debug FILE 2013-07-22 16:36:13,477 - werkzeug - INFO -  * Running on http://0.0.0.0:5000/ 
like image 195
HolgerSchurig Avatar answered Sep 28 '22 01:09

HolgerSchurig


Ok, my failure stemmed from two misconceptions:

1) Flask will apparently ignore all your custom logging unless it is running in production mode

2) debug=False is not enough to let it run in production mode. You have to wrap the app in any sort of WSGI server to do so

After i started the app from gevent's WSGI server (and moving logging initialization to a more appropriate place) everything seems to work fine

like image 36
fleshgolem Avatar answered Sep 28 '22 03:09

fleshgolem