django-prometheus icon indicating copy to clipboard operation
django-prometheus copied to clipboard

Avoid different ports after reloading uwsgi

Open PabloCastellano opened this issue 5 years ago • 6 comments
trafficstars

Hello.

In my environment I'm running Django in 2 uwsgi processes and my settings.py contains

PROMETHEUS_METRICS_EXPORT_PORT_RANGE = range(8070, 8079)

When I run it the first time, ports 8070 and 8071 serve the metrics and everything works fine.

However sometimes I need to reload/restart uwsgi. It happens sometimes that I don't get the same ports allocated. Instead, I may get 8071 and 8072. This breaks my monitoring system and I get flooded in alerts, because my setup expects two processes running and exposing metrics at ports 8070 and 8071.

I'm wondering if it makes sense to wait some little time and retry in case that a port is not yet available. I have quickly made this change note: I haven't tested it and would like to know if you find any issue with this approach or would you accept a patch to have it as a feature.

https://github.com/PabloCastellano/django-prometheus/commit/7ff2e9dffd89df67db4a287ef570e04d0ec2ee1e

PabloCastellano avatar Sep 28 '20 18:09 PabloCastellano

@PabloCastellano were you able find any possible solution to this issue?

justjais avatar May 02 '23 13:05 justjais

@justjais Nope, I migrated to asgi and never had this issue again

PabloCastellano avatar May 02 '23 13:05 PabloCastellano

@PabloCastellano thanks for your confirmation.

@korfuri and @asherf please excuse me for personally tagging you, but I needed to know if you had a possible solution to this problem. As this appears to be a very common issue, in a production environment, this scenario could easily result in pseudo failures where the uWSGI worker is exporting to a different port and the Prometheus config file is attempting to scrap metrics from a static port that is no longer being used by the respective uWSGI worker, resulting in failure scenarios.

justjais avatar May 04 '23 04:05 justjais

You don’t have to use this package in this way. You can just mount the views defined in this package using your own url file. This way this package is not using ports directly and that responsibility is up to your own Django app

asherf avatar May 04 '23 13:05 asherf

@asherf Thanks so much for your response; but I am unable to follow your suggested solution. To better explain the use case, my Django app has 5 uWSGI workers, and I've used PROMETHEUS_METRICS_EXPORT_PORT_RANGE= range(8001, 8011) to export the /metrics globally for each of the 5 workers, and it works as intended. However, in this scenario, I'm scraping metrics via a Prometheus config file that defines the ports statically, but if the ports are updated to a different port and uWSGI workers begin exporting from a different port from the available port range, the static port scraping fails with a host unreachable error, which is a pseudo failure because the workers are exporting metrics but to a different port now. So, my question is, is there a way to learn the ports of the 5 workers from which metrics are exported, so that I can update that information to target JSON, and Prometheus can then scrape metrics from defined ports using the dynamic target JSON.

justjais avatar May 04 '23 14:05 justjais

@justjais if you enable the multi-process mode, then this becomes very easy. Take a look at https://github.com/korfuri/django-prometheus/blob/master/documentation/exports.md#exporting-metrics-in-a-wsgi-application-with-multiple-processes-globally to see how to get going. Add the prometheus urls to your url conf, and when you call the API, it will automatically collect the metrics from all running processes.

andrew-cybsafe avatar May 09 '23 20:05 andrew-cybsafe