Reputation: 440
I would like for my python flask project to have stderr print to say "stderr.txt", and stdout to "stoud.txt"
I have looked and saw print("debug stderr", sys.stderr(file))
, but I am not understanding what does mean. There isn't a specific command that I want stderr to go to, I want all flask to print to stderr.txt
and stoud.txt
. For example, when I run python app.py
, I want to be able to do cat stderr.txt
and see only the errors, and when I cat stoud.txt
, I would like to see the output. there is no stdin.
Thank you in advance :)
Upvotes: 0
Views: 1142
Reputation: 1651
As far as I remember (need to double check) Werkzeug
doesn't use a named logger in favor of a root one, hence it's possible to change root logger behavior by passing different handlers:
from flask import Flask
import logging
from logging.handlers import RotatingFileHandler
app = Flask(__name__)
class LevelFilter(object):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno != self.level
# Redirect stdout and stderr to files
info_handler = RotatingFileHandler("info.log", backupCount=1)
info_handler.setLevel(logging.INFO)
# Don't print stack trace in info.log - optional
info_handler.addFilter(LevelFilter(logging.ERROR))
error_handler = RotatingFileHandler("err.log", backupCount=1)
error_handler.setLevel(logging.ERROR)
logging.root.handlers = [info_handler, error_handler]
@app.route("/")
def hello_world():
return "Hello, world"
@app.route("/error")
def error():
len(m) # Some dumb error
return "No wonder it crashed..."
if __name__ == "__main__":
app.run(port=8080, debug=False)
Running this app and visiting /
will produce the following output in info.log
:
* Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
127.0.0.1 - - [06/Oct/2020 15:57:11] "[37mGET / HTTP/1.1[0m" 200 -
127.0.0.1 - - [06/Oct/2020 15:57:21] "[35m[1mGET /error HTTP/1.1[0m" 500 -
Visiting /error
will print the stack trace of the error in err.log
:
Exception on /error [GET]
Traceback (most recent call last):
File "/home/anddt/.pyenv/versions/3.8.6/envs/flask-log/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/home/anddt/.pyenv/versions/3.8.6/envs/flask-log/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/anddt/.pyenv/versions/3.8.6/envs/flask-log/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/anddt/.pyenv/versions/3.8.6/envs/flask-log/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/anddt/.pyenv/versions/3.8.6/envs/flask-log/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/home/anddt/.pyenv/versions/3.8.6/envs/flask-log/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "app.py", line 16, in error
len(m) # Some dumb error
NameError: name 'm' is not defined
If you don't mind the error stack trace appearing in both logs, you can obviously spare yourself adding the filter to the handler.
Upvotes: 2