title: Collecting prometheus metrics from a separate port using flask and gunicorn with multiple workers
body: <p>I run a small flask application with gunicorn and multiple worker processes on kubernetes. I would like to collect metrics from this application with prometheus, but the metrics should only be accessible cluster internally on a separate port (as this required in our current setting). </p>
  
  <p>For one gunicorn worker process I could use the <code>start_http_server</code> fucntion from the python client library to expose metrics on a different port than the flask app. </p>
  
  <p>A minimal example may look like this:</p>
  
  <pre><code>from flask import Flask
  from prometheus_client import start_http_server, Counter
  
  NUM_REQUESTS = Counter("num_requests", "Example counter")
  
  app = Flask(__name__)
  
  @app.route('/')
  def hello_world():
      NUM_REQUESTS.inc()
      return 'Hello, World!'
  
  start_http_server(9001)
  </code></pre>
  
  <p>To start the app do the following: </p>
  
  <pre><code>gunicorn --bind 127.0.0.1:8082 -w 1 app:app
  </code></pre>
  
  <p>However this only works for one worker process. </p>
  
  <p>In the documentation of the client library is also a <a href="https://github.com/prometheus/client_python#multiprocess-mode-gunicorn" rel="noreferrer">section</a> on how to use prometheus and gunicorn with multiple worker processes by specifying a shared directory for the worker processes as an environment variable where metrics are written to (<code>prometheus_multiproc_dir</code>). </p>
  
  <p>So following the documentation the above example for  multiple workers would be:</p>
  
  <p>A gunicorn config file: </p>
  
  <pre><code>from prometheus_client import multiprocess
  
  def worker_exit(server, worker):    
      multiprocess.mark_process_dead(worker.pid)
  </code></pre>
  
  <p>The application file:</p>
  
  <pre><code>import os
  from flask import Flask
  from prometheus_client import Counter
  
  NUM_REQUESTS = Counter("num_requests", "Example counter")
  
  app = Flask(__name__)
  
  @app.route('/')
  def hello_world():
      NUM_REQUESTS.inc()
      return "[PID {}]: Hello World".format(os.getpid())
  </code></pre>
  
  <p>To start the app do:</p>
  
  <pre><code>rm -rf flask-metrics/
  mkdir flask-metrics
  export prometheus_multiproc_dir=flask-metrics
  gunicorn --bind 127.0.0.1:8082 -c gunicorn_conf.py -w 3 app:app
  </code></pre>
  
  <p>However in this setting I don't really know how to accesses the metrics stored in flask-metrics on a separate port. Is there way to get this done?</p>
  
  <p>I am a bit new to these things, so if I am approaching the problem in the wrong way I am also happy for advice what would be the best way to address my case. </p>