I was figuring out the same thing, and the solution was as simple as you would imagine.

Updated your example code to work:


from multiprocessing import Process
import shutil
import time, os
from prometheus_client import start_http_server, multiprocess, CollectorRegistry, Counter


COUNTER1 = Counter('counter1', 'Incremented by the first child process')
COUNTER2 = Counter('counter2', 'Incremented by the second child process')
COUNTER3 = Counter('counter3', 'Incremented by both child processes')


def f1():
    while True:
        time.sleep(1)
        print("Child process 1")
        COUNTER1.inc()
        COUNTER3.inc()
    

def f2():
    while True:
        time.sleep(1)
        print("Child process 2")
        COUNTER2.inc()
        COUNTER3.inc()


if __name__ == '__main__':
    # ensure variable exists, and ensure defined folder is clean on start
    prome_stats = os.environ["PROMETHEUS_MULTIPROC_DIR"]
    if os.path.exists(prome_stats):
        shutil.rmtree(prome_stats)
    os.mkdir(prome_stats)

    # pass the registry to server
    registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(registry)
    start_http_server(8000, registry=registry)

    p = Process(target=f1, args=())
    a = p.start()
    p2 = Process(target=f2, args=())
    p2.start()

    print("collect")

    while True:
        time.sleep(1)

localhost:8000/metrics
# HELP counter1_total Incremented by the first child process
# TYPE counter1_total counter
counter1_total 9.0
# HELP counter2_total Incremented by the second child process
# TYPE counter2_total counter
counter2_total 9.0
# HELP counter3_total Incremented by both child processes
# TYPE counter3_total counter
counter3_total 18.0
Answer from potato_cannon on Stack Overflow
🌐
client_python
prometheus.github.io › client_python › exporting › http
HTTP/HTTPS | client_python
February 9, 2026 - HTTP Metrics are usually exposed over HTTP, to be read by the Prometheus server. The easiest way to do this is via start_http_server, which will start a HTTP server in a daemon thread on the given port: from prometheus_client import start_http_server start_http_server(8000) Visit ...
🌐
client_python
prometheus.github.io › client_python
client_python
This tutorial shows the quickest way to get started with the Prometheus Python library. ... from prometheus_client import start_http_server, Summary import random import time # Create a metric to track time spent and requests made. REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request') # Decorate function with metric.
Discussions

Prometheus's Python -prometheus_client-. "start_http_server" question/issue
This all fine, something is making a tcp connection and closing it too early causing the pipe error. You're seeing FIRE twice as your browser is requesting favicon.ico. More on reddit.com
🌐 r/PrometheusMonitoring
3
1
August 15, 2018
python - Prometheus how to expose metrics in multiprocess app with start_http_server - Stack Overflow
How expose metrics in multiprocess app use start_http_server I found many examples with gunicorn in internet but i want use start_http_server what should i do with code below to make it work proper... More on stackoverflow.com
🌐 stackoverflow.com
start_http_server dual stack and IPv6 literals
Version 0.13.1 Python 3.9.11 on Debian testing. I saw #567 , but this is still broken. prometheus_client.start_http_server(port=9888, addr="localhost") - only listens on IPv4 prometheus_c... More on github.com
🌐 github.com
2
March 26, 2022
python - Is there an arg to set other endpoint in start_http_server (prometheus_client) instead of /? - Stack Overflow
I'm building a Flask application and I would like to know if there is an arg on module start_http_server (from prometheus_client) that allow me to set a specific metrics endpoint instead /. Thanks! More on stackoverflow.com
🌐 stackoverflow.com
🌐
ProgramCreek
programcreek.com › python › example › 126995 › prometheus_client.start_http_server
Python Examples of prometheus_client.start_http_server
def __init__(self, data_manager, config): self.config = config self.data_manager = data_manager self.http_server = prometheus_client.start_http_server( self.config.prometheus_port, addr=self.config.prometheus_addr ) self.updated_containers_counter = prometheus_client.Counter( 'containers_updated', 'Count of containers updated', ['socket', 'container'] ) self.monitored_containers_gauge = prometheus_client.Gauge( 'containers_being_monitored', 'Gauge of containers being monitored', ['socket'] ) self.updated_all_containers_gauge = prometheus_client.Gauge( 'all_containers_updated', 'Count of total updated', ['socket'] ) self.logger = getLogger()
🌐
Reddit
reddit.com › r/prometheusmonitoring › prometheus's python -prometheus_client-. "start_http_server" question/issue
r/PrometheusMonitoring on Reddit: Prometheus's Python -prometheus_client-. "start_http_server" question/issue
August 15, 2018 -

Hi all,

I'm using Python prometheus_client's start_http_server, when I set up a service file for the script, I get a broken pipe error:

self.RequestHandlerClass(request, client_address, self)
File "/usr/lib64/python2.7/SocketServer.py", line 651, in __init__
self.finish()
File "/usr/lib64/python2.7/SocketServer.py", line 710, in finish
self.wfile.close()
File "/usr/lib64/python2.7/socket.py", line 279, in close
self.flush()
File "/usr/lib64/python2.7/socket.py", line 303, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe

I'm posting it here as it comes from the start_http_server, since thats what I use to start the server, otherwise I would have checked the "/usr/lib64/python2.7/socket.py".

Here is my service's unit systemctl file:

[Unit]
Description=Dead Exporter
After=local-fs.target network-online.target network.target
Wants=local-fs.target network-online.target network.target
[Service]
WorkingDirectory=/net/systems/tools/deadExporter
#User=blah
Type=simple
Restart=on-failure
RestartSec=30
ExecStart=/net/systems/tools/deadExporter/dead.py
[Install]
WantedBy=multi-user.target

I'll show my code and I'm pretty much sure its related to how I build the name == "main": but I cant put my finger on it.

I added the time.sleep(1) as without the while loop, I cant keep the server up, I"m guessing its the right way to do so!??

I learned the the Metrics build in to be in the file scope. So I hope thats fine.

Can anyone tell me if you see something wrong?

Code:

import sys
import time
from prometheus_client import Counter
from prometheus_client import start_http_server
from prometheus_client import CounterMetricFamily
from prometheus_client import REGISTRY

class DeadCollector(object):
    def collect(self):
        print('FIRE!')
        c = CounterMetricFamily("woohoo", 'Woohoo is the greatest', labels=['stat'])
        c.add_metric(['statVal'], 0.0)
        yield c


timer = time.time()
REGISTRY.register(DeadCollector())
print('\nFinished dead in {:.2f}sec'.format(time.time() - timer))


if __name__ == '__main__':
    # start the server
    start_http_server(9366)
    try:
        while True:
            time.sleep(1)

    except KeyboardInterrupt:
        print('\nYou killed Kenny, you bastard!\n')
        sys.exit()

One last thing, The serer runs, the error comes only from the systemctl service unit, however... you see that "FIRE!" print, when I run this locally, just a simple (shell)

clear;python dead.py

everytime I refresh the browser, I get the FIRE twice! once as I press reload and once when its done.

I am missing something again? Shouldn't it run just once?

Any help will do, Thank you!

🌐
PyPI
pypi.org › project › prometheus-client › 0.14.1
prometheus-client · PyPI
The official Python client for Prometheus. ... from prometheus_client import start_http_server, Summary import random import time # Create a metric to track time spent and requests made.
🌐
Linux Hint
linuxhint.com › monitor-python-applications-prometheus
Monitoring Python Applications using Prometheus – Linux Hint
I will call it python-prometheus/. I will create the python-prometheus/ project directory in the ~/projects directory in this article. Create a new file hello_world.py and type in the following lines of codes. import http.server from prometheus_client import start_http_server class ServerHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.end_headers() self.wfile.write(b"Hello World!") if __name__ == "__main__": start_http_server(8000) server = http.server.HTTPServer(('', 8001), ServerHandler) print("Prometheus metrics available on port 8000 /metrics") print("HTTP server available on port 8001") server.serve_forever()
Top answer
1 of 1
15

I was figuring out the same thing, and the solution was as simple as you would imagine.

Updated your example code to work:


from multiprocessing import Process
import shutil
import time, os
from prometheus_client import start_http_server, multiprocess, CollectorRegistry, Counter


COUNTER1 = Counter('counter1', 'Incremented by the first child process')
COUNTER2 = Counter('counter2', 'Incremented by the second child process')
COUNTER3 = Counter('counter3', 'Incremented by both child processes')


def f1():
    while True:
        time.sleep(1)
        print("Child process 1")
        COUNTER1.inc()
        COUNTER3.inc()
    

def f2():
    while True:
        time.sleep(1)
        print("Child process 2")
        COUNTER2.inc()
        COUNTER3.inc()


if __name__ == '__main__':
    # ensure variable exists, and ensure defined folder is clean on start
    prome_stats = os.environ["PROMETHEUS_MULTIPROC_DIR"]
    if os.path.exists(prome_stats):
        shutil.rmtree(prome_stats)
    os.mkdir(prome_stats)

    # pass the registry to server
    registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(registry)
    start_http_server(8000, registry=registry)

    p = Process(target=f1, args=())
    a = p.start()
    p2 = Process(target=f2, args=())
    p2.start()

    print("collect")

    while True:
        time.sleep(1)

localhost:8000/metrics
# HELP counter1_total Incremented by the first child process
# TYPE counter1_total counter
counter1_total 9.0
# HELP counter2_total Incremented by the second child process
# TYPE counter2_total counter
counter2_total 9.0
# HELP counter3_total Incremented by both child processes
# TYPE counter3_total counter
counter3_total 18.0
🌐
GitHub
github.com › prometheus › client_python › pull › 128 › files
Return thread object from start_http_server by bdkearns · Pull Request #128 · prometheus/client_python
When starting a server using port 0 (to allow the OS to choose an open port), one needs to retrieve the selected port after HTTPServer creation. This PR allows doing so through: t = start_http_serv...
Author: prometheus
Find elsewhere
🌐
GitHub
github.com › valohai › prometheus-client-python
GitHub - valohai/prometheus-client-python: Prometheus instrumentation library for Python applications · GitHub
The official Python 2 and 3 client for Prometheus. ... from prometheus_client import start_http_server, Summary import random import time # Create a metric to track time spent and requests made.
Author: valohai
🌐
GitHub
github.com › prometheus › client_python › issues › 791
start_http_server dual stack and IPv6 literals · Issue #791 · prometheus/client_python
March 26, 2022 - Version 0.13.1 Python 3.9.11 on Debian testing. I saw #567 , but this is still broken. prometheus_client.start_http_server(port=9888, addr="localhost") - only listens on IPv4 prometheus_client.start_http_server(port=9888, addr="::") - do...
Author: prometheus
🌐
Medium
medium.com › @simrankumari1344 › setting-up-prometheus-server-with-a-python-app-a-step-by-step-guide-fadba7d35dbe
Setting Up Prometheus Server with a Python App: A Step-by-Step Guide | by Simran Kumari | Medium
January 13, 2025 - 2. Write the Python App The Python app uses Flask for routing and the Prometheus client to track metrics. Key points: Starts an HTTP server on port 8000 to expose metrics at /metrics.
🌐
Robust Perception
robustperception.io › instrumenting-python-with-prometheus
Instrumenting Python with Prometheus – Robust Perception | Prometheus Monitoring Experts
This only needs to be done once, often in your __main__. The simplest way is to start up a server on a port for Prometheus, but it's also possible to expose via frameworks like Django. from prometheus_client import start_http_server if __name__ == '__main__': start_http_server(8000)
🌐
Google Groups
groups.google.com › g › prometheus-users › c › 1Rm-G-MmUR4
Add a /health endpoint using the Prometheus Python client library
May 20, 2022 - import time from prometheus_client import start_http_server from prometheus_client.core import GaugeMetricFamily, REGISTRY def costly_function(): "E.g., queries someone else's API and uses up API credits, etc..." return ('dev', 'uat', 'prod') class Collector: def collect(self): gauge = GaugeMetricFamily('example_gauge', 'Example gauge', labels=["environment"]) for environment in costly_function(): print("adding sample for environment=%s" % environment) gauge.add_metric([environment], 1) yield gauge REGISTRY.register(Collector()) start_http_server(8080) print("server listening on port 8080") while True: time.sleep(60) When we hook these kinds of exporter up in Google's GKE, and expose them via ILB Services, the ILB health checks query them for health via a /healthz endpoint.
🌐
O'Reilly
oreilly.com › library › view › prometheus-up › 9781492034131 › ch03.html
3. Instrumentation - Prometheus: Up & Running [Book]
July 9, 2018 - If you run it with Python 3 and then visit http://localhost:8001/ in your browser, you will get a Hello World response. import http.server from prometheus_client import start_http_server class MyHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.end_headers() self.wfile.write(b"Hello World") if __name__ == "__main__": start_http_server(8000) server = http.server.HTTPServer(('localhost', 8001), MyHandler) server.serve_forever()
Author: Brian Brazil
Published: 2018
Pages: 386
🌐
Frama
gdevops.frama.io › opsindev › sysops › observability-and-analysis › monitoring › prometheus › clients › python › python.html
prometheus client python (Prometheus instrumentation library for Python applications) — devops/sysops
... from prometheus_client import start_http_server, Summary import random import time # Create a metric to track time spent and requests made. REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request') # Decorate function with metric.
🌐
Stack Overflow
stackoverflow.com › questions › 52103283 › is-there-an-arg-to-set-other-endpoint-in-start-http-server-prometheus-client-i
python - Is there an arg to set other endpoint in start_http_server (prometheus_client) instead of /? - Stack Overflow
When using the Prometheus client with flask, you don't need to start the http server on your own but you can enable the wsgi middleware and specify the route you want to serve your metrics on your existing app. app = Flask(__name__) app_dispatch ...
🌐
GitHub
github.com › prometheus › client_python › issues › 567
start_http_server incapable to listen on IPv6 sockets · Issue #567 · prometheus/client_python
July 23, 2020 - + if getattr(server_cls, 'address_family') == socket.AF_INET: + class server_cls(server_cls): + address_family = socket.AF_INET6 + httpd = make_server(addr, port, app, server_cls, handler_class=_SilentHandler) t = threading.Thread(target=httpd.serve_forever) t.daemon = True t.start() ... # python3.8 Python 3.8.5 (default, Jul 23 2020, 07:58:41) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import prometheus_client >>> prometheus_client.start_http_server(port=9097, addr='::') >>> prometheus_client.start_http_server(port=9098) >>>
Author: prometheus
🌐
GitHub
github.com › prometheus › client_python
GitHub - prometheus/client_python: Prometheus instrumentation library for Python applications · GitHub
The official Python client for Prometheus. ... This package can be found on PyPI. Documentation is available on https://prometheus.github.io/client_python
Author: prometheus