Logging uWSGI application stop in Python - python

I have a Flask app that I run with uWSGI. I have configured logging to file in the Python/Flask application, so on service start it logs that the application has been started.
I want to be able to do this when the service stops as well, but I don't know how to implement it.
For example, if I run the uwsgi app in console, and then interrupt it with Ctrl-C, I get only uwsgi logs ("Goodbye to uwsgi" etc) in console, but no logs from the stopped python application. Not sure how to do this.
I would be glad if someone advised on possible solutions.
Edit:
I've tried to use Python's atexit module, but the function that I registered to run on exit is executed not one time, but 4 times (which is the number of uWSGI workers).

There is no "stop" event in WSGI, so there is no way to detect when the application stops, only when the server / worker stops.

Related

How to stop a Heroku dyno using the Heroku API so it doesn't restart

How can a fully stop a Heroku dyno using the Heroku API so it doesn't restart?
I have Heroku set up to run a Python script that always loops and never exits to check sensors. This main.py script is run as a Dyno worker via my Procfile. Right now, it always runs as anticipated. It even restarts upon a crash, which is also helpful for this app.
Using the Heroku API, I would like to be able to completely stop this process. This won't be reoccurring often, just a failsafe kill-switch. I can stop the dyno worker by logging in to Heroku and clicking the edit button in the Resources tab and turn off the worker. But, I would like to turn off the worker via the API.
I have tried the following API calls (via Postman), which both stop the current process, but after a few seconds, Heroku starts the worker back up again.
Stop the current Dyno
POST https://api.heroku.com/apps/<app_id>/dynos/worker.1/actions/stop
Deletes / restarts all dynos in the app
DELETE https://api.heroku.com/apps/<app_id>/dynos
Also, I can put the app in to maintenance mode, but that only stops HTTP traffic, not the Dynos
PATCH https://api.heroku.com/apps/<app_id>
with payload of {"maintenance":true}
One option is completely deleting the app, but that's a bit too much for me as it will also remove all log files, and be a pain to set it back up again.
DELETE https://api.heroku.com/apps/<app_id>
Is there any way to completely stop a Dyno or app via the API until I manually start it back up again?
You have to use Heroku Formation API to scale the processes up and down, it will not restart the App by itself.
For detailed answer check this.
Seems like you are stoping the worker rather than a dyno. You have to provide a dyno id.
Stoping dyno
After stopping correctly restart to start it again.
restarting the dyno

Why Fabric run app terminate?

I have been trying to start app in remote hosts using Fabric.
I was running a daemonized Java app, which run perfectly fine when I logged in and run it manually. The app keep running even after I exit the session.
But when I use Fabric run(), my app terminates once the session ends.
Although run(command, pty=False) solved my problem (It is roughly documented here), I still can not see why these are relevant. I am a python newbie, can anyone explain the difference between:
start daemon with ssh logged in and start manually
start daemon using Fabric with pty=True
start daemon using Fabric with pty=False

How to Make uWSGI die when it encounters an error?

I have my Python app running through uWSGI. Rarely, the app will encounter an error which makes it not be able to load. At that point, if I send requests to uWSGI, I get the error no python application found, check your startup logs for errors. What I would like to happen in this situation is for uWSGI to just die so that the program managing it (Supervisor, in my case) can restart it. Is there a setting or something I can use to force this?
More info about my setup:
Python 2.7 app being run through uWSGI in a docker container. The docker container is managed by Supervisor, and if it dies, Supervisor will restart it, which is what I want to happen.
After an hour of searching, I finally found a way to do this. Just pass the --need-app argument when starting uWSGI, or add need-app = true in your .ini file, if you run things that way. No idea why this is off by default (in what situation would you ever want uWSGI to keep running when your app has died?) but so it goes.

How to setup WSGI server to run similarly to Apache?

I'm coming from PHP/Apache world where running an application is super easy. Whenever PHP application crashes Apache process running that request will stop but server will be still ruining happily and respond to other clients. Is there a way to have Python application work in a smilar way. How would I setup wsgi server like Tornado or CherryPy so it will work similarly? also, how would I run several applications from one server with different domains?
What you are after would possibly happen anyway for WSGI severs. This is because any Python exception only affects the current request and the framework or WSGI server would catch the exception, log it and translate it to a HTTP 500 status page. The application would still be in memory and would continue to handle future requests.
What we get down to is what exactly you mean by 'crashes Apache process'.
It would be rare for your code to crash, as in cause the process to completely exit due to a core dump, the whole process. So are you being confused in your terminology in equating an application language level error to a full process crash.
Even if you did find a way to crash a process, Apache/mod_wsgi handles that okay and the process will be replaced. The Gunicorn WSGI server will also do that. CherryPy will not unless you have a process manager running which monitors it and the process monitor restarts it. Tornado in its single process mode will have the same problem. Using Tornado as the worker in Gunicorn is one way around that plus I believe Tornado itself may have some process manager in it now for running multiple process which allow it to restart processes if they die.
Do note that if your application bug which caused the Python exception is bad enough and it corrupts state within the process, subsequent requests may possibly have issues. This is the one difference with PHP. With PHP, after any request, whether successful or not, the application is effectively thrown away and doesn't persist. So buggy code cannot affect subsequent requests. In Python, because the process with loaded code and retained state is kept between requests, then technically you could get things in a state where you would have to restart the process to fix it. I don't know of any WSGI server though that has a mechanism to automatically restart a process if one request returned an error response.
If you're in an UNIX-like environment, you can run mod_wsgi under Apache in Daemon Mode. This means there will be a separate process for the Python code, and even if it crashes the server will continue running normally (and hopefully the WSGI process will restart itself). A WSGI application can run under multiple processes and multiple threads per process.
As for running multiple domains in the same server, check Name-Based Virtual Hosts.

How to get Intellij-idea close Flask dev server properly?

I use IDEA 10.5 for my Flask experimentation. Flask has en embedded test server (like Django does)
When I launch my test class, the dev server launches as well on port 5000. All good.
* Running on http://127.0.0.1:5000/
When I click on the "Stop process" button (red square), I get the message saying the process is finished :
Process finished with exit code 143
However the server is still alive (responds to requests) and I can see I still have a python process running.
Obviously this prevents me from relaunching the test straight away, I have to kill the server process first.
How do you manage to get both your program and the server ending at the same time ?
I guess what happens is that you start your flask app which then is forking the development server as a new process. If you stop the app the forked process is still running.
This looks like a problem, that cannot easily be solved within the means of your IDE. You could add something to your main to kill the already running server process, before starting the app again, but that seems ugly.
But why don't you just start your app with app.run(debug=True) as described in flask doc? The server will reload automatically everytime you changed your app so you don't have to stop and restart it manually.
EDIT:
Something a bit quirky just came to my mind: if you just need a comfortable way to kill the server from within the IDE all you have to do is to introduce a syntactical error in one of the places the reloader monitors, save the file and the server will choke on it and die :)
This doesn't happen anymore with newer versions (tested with PyCharm 2.0)

Categories

Resources