-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flask app errors logged to stdout, not captured by Gunicorn logging facility #1124
Comments
I am sorry that I do not fully understand the first part where you describe the problem and the change that happened.
|
To clarify: Before, it used to go to gunicorn logs. In flask, we created a Then, we found the error stream going to gunicorn's stdout, instead of the error log. To route the errors to gunicorn's error log, now we must use |
Did you change anything else? Using different options (like |
Oh, this was not a Gunicorn version update? |
Same version of Gunicorn, same Gunicorn settings. Sorry, I must not be being clear about this. :) We run many Flask apps via Gunicorn. These all log normally. We always create a The only thing that makes this app any different from the others is that this app is primarily built atop flask-restful. No other logging paradigms have changed -- except now, we must extend flask's handlers by capturing Gunicorns handlers, and explicitly pass them to flask. Otherwise, Gunicorn will not catch errors from the app into it's error log - instead, they go to stdout/stderr. Here's the config:
|
not sure to understand the issue there. If you want to log the error using the gunicorn error handler, you could simply using the python Logging module and write to the |
I'll try to help explain. Historically our flask apps have been configured to log following the comment that can be found at #379 (comment) This has always worked well for us. When logging using Recently, in a new application configured the same way (the only difference being that we are using flask-restful), these logged messages no longer showed up in the gunicorn error.log file. These logs are now being caught by upstart which handles running gunicorn for us. I think the short of it is:
In order to achieve similar results, where we could use the logger in the flask app object, we added the handlers from No where has there ever been reference to In all of our applications, we are either using gunicorn 19.2.x or 19.3.x. It looks like the issue/comment that I reference above, may actually give us the answer, but all the dates seem to be pretty far in the past, so I am unsure as to why we recently started seeing this issue. Also, to explicitly ask; When using flask and wanting to use |
No idea! That's why I was double-checking version numbers and things :). Thanks for your patience.
Again... no idea :(. But it sounds like it might be the expected behavior. :/ Here is where flask configures the application logger: https://github.com/mitsuhiko/flask/blob/6e77cd709e16f7d1d654f67a5fc82e54bceae432/flask/logging.py#L83 From that it looks like here, if there is no |
I also add a Streamlogger to my Flask apps and I don't have this problem. I'm using
and the logs always go to Gunicorns stderr log. |
@sivel were you using the |
Actually, forget that question. I misread. |
At least I know how this is supposed to work now. I wonder if maybe you're running this app in debug? Flask logs to the default Flask logs to the default Gunicorn sets So, with Is this what you see? |
I created this as a demo: https://gist.github.com/angstwad/527783c47a108c645cdd. I provided the sample file, the output from my terminal window when running, tailing the error and access logs, and a pip freeze of my virtualenv. Setting an error-logfile and and access-logfile when running this logs to stderr, not the error.log. |
I described and linked to the various code paths that are involved in the expected behavior. If someone could step through their own code and see whether flask logs to |
@tilgovi the part of Flask you are referring to is the dev (0.11) version but @angstwad is using 0.10.1 (same as me) where the 'LOGGING_HANDLER_POLICY' does not exist. |
I am not sure I understand this issue. Gunicorn error log is here to log errors from Gunicorn, not from another application. We stopped to reroute logs from stdout awhile ago for that reason. So questions:
@romabysen |
bump. anything to add to this issue? It's not clear actually if gunicorn is working s expected or if the user expectation is not achieved.By default, gunicorn should not reroute logs to stdout. If something is not working let me know. |
This issue is getting in my way so much too! I never seem to manage to get gunicorn to log stuff properly. I had problems from both Django and Flask, where no matter what I tried I only get logs like:
No stack trace or anything that lets me figure out what the problem is. I tried to set Flask to log stuff to stdout, change log levels to DEBUG and a bunch of settings with the arcane Python log config format. This is such basic functionality that I would really expect it to work more smoothly. In all other environments I worked in, e.g. Rails, it was just a no-brainer. Some things that I would expect to come out of the box:
If someone has working recipes for how a Django & Flask app should be "properly" configured to work this way, including that in the official Gunicorn docs would be so much help to me – and I assume other newcomers. I would also be very grateful for any tips on where to look for good working examples. |
@metakermit actually did you configure it to print to wsgi.errors or gunicorn.errors handler? This will be the only way to have an application error displayed in gunicorn logs. This has been changed 2 years ago: 4152318 And for the why: #309 (comment) and some other comments at that time. Capturing STDOUT from the worker may introduce some issues with the current design. This can be changed when the new IPC architecture will take place |
I don't know. I tried quite a few combinations and have just given up for now and I start the app using |
I am also having trouble with logging. I have these flags set:
I am getting stuff in the error.log but it is not very helpful. When unexpected errors occur in production error.log shows that 'something' happened and that the gunicorn server has restarted itself but there is currently no way to tell what the exception was. Adding my own application level logging is not really a solution because I can only catch and log expected errors. I keep adding more logging hoping to catch the issue but what I really want is for gunicorn to catch unhandled errors that cause my app to crash and log them to error.log and not just tell me something bad occurred. Right now it seems impossible to get a stacktrace from an unexpected error. I have some mysterious problems occurring in my production environment and right now I have no idea what is going on--only that sometimes my process crashes and restarts. I am new to gunicorn so apologies if I am missing something obvious here, but right now I am super stuck. |
@danielrmeyer You can increase the log level using the |
@benoitc Thanks, I will mess with that and post here if I fix my problem. I did see that option though (I'm running 19.4):
I did not try changing it because it looks like it defaults to [info], which in my understanding would capture errors at info level and more severe levels like [error] level severity. Is my thinking on this wrong? In any case I'll explicitly set it and see what happens. |
I did some experiments raising exceptions at various places in my code and was surprised to see the correct thing occur with the exceptions showing up in the log--so I think the gunicorn logging is working how I expect. When my mystery problem occurs (which I now am pretty sure is temporary loss of connectivity to the DB) this is what I see happen in the error log:
This is giving me the impression that something had crashed and an exception was being swallowed, so I've been fighting with logging thinking that was my issue; however, like I said when I put explicit 'raise Exception' in various places I see that gunicorn is in fact not swallowing the exception and logging it properly. So I am now thinking there is some behavior I don't understand going on. Still, I am mystified as to why all I see is evidence that the worker is restarting with no underlying stack trace pinpointing where in the code the exception was raised. |
Folks, I am sorry for the noise here. The issue has nothing to do with gunicorn and gunicorn logging is working perfectly. If anyone else comes here with the same issue read about the gunicorn graceful restart feature. I was getting loss of db connectivity and gunicorn was restarting the workers before an exception was being thrown by my DB client. Again, I apologize for the noise here. |
Please add that to the documentation! The only thing the docs have to say about the |
I started assembling an example Django app that would fulfil the requirements from my past comment as project fail-nicely-django. Hopefully there'll be a fail-nicely-flask too in the future when I get to it. Maybe someone finds this useful regarding the scattered pieces of info we mentioned in this issue thread. Suggestions/contributions welcome 😄 |
@metakermit I tweeted it :) |
@benoitc cool, thanks for the help :) |
What had previously worked for us had suddenly stopped working. Running Flask 0.10.1 (and Flask-Restful) and Gunicorn 19.3.0, we set up a warning stream handler for errors. These errors were previously captured by Gunicorn, but were instead logging out to the Gunicorn process' stdout/stderr, instead of being captured to the access and error logs (which were and always have been configured).
In order to resolve this issue, we had to add the
gunicorn.error
logging facilities to the Flask app's handlers. Here's a snippet where we setup and then extend Flask's handlers in order to achieve "normal" logging by Gunicorn:The text was updated successfully, but these errors were encountered: