The HAProxy Prometheus exporter should expose metrics from the running proxy without mixing monitoring traffic into application frontends. The useful proof is a dedicated metrics endpoint that returns HAProxy metric names and a Prometheus scrape job that targets that endpoint deliberately.

Current HAProxy builds can include the Prometheus exporter as a built-in service. The exporter is enabled from an HTTP frontend with http-request use-service prometheus-exporter, so no separate exporter process is required when the binary was built with that feature.

Bind the example listener to loopback or a private monitoring network, validate the file, reload HAProxy, and confirm Prometheus can scrape /metrics. Do not expose the metrics endpoint publicly because it can reveal listener names, backend names, traffic rates, and health state.

Steps to enable HAProxy Prometheus exporter:

  1. Confirm the HAProxy binary includes the Prometheus exporter service.
    $ haproxy -vv | grep -i prometheus
    Built with the Prometheus exporter as a service

    If the output does not mention the Prometheus exporter, install a package or build that includes PROMEX support before adding the frontend.

  2. Choose a metrics listener address.

    The example uses 127.0.0.1:8405 so a local Prometheus agent or tunnel can scrape it. Use a private monitoring address only when firewall rules restrict access to trusted scrapers.

  3. Open the active HAProxy configuration file.
    $ sudoedit /etc/haproxy/haproxy.cfg
  4. Add a dedicated Prometheus frontend.
    /etc/haproxy/haproxy.cfg
    frontend prometheus
        bind 127.0.0.1:8405
        mode http
        http-request use-service prometheus-exporter if { path /metrics }
        http-request return status 404
        no log

    The use-service action serves metrics only for /metrics. The fallback 404 keeps other paths from returning application traffic or stats HTML.

  5. Validate the complete HAProxy configuration.
    $ sudo haproxy -c -V -f /etc/haproxy/haproxy.cfg
    Configuration file is valid
  6. Reload HAProxy after validation succeeds.
    $ sudo systemctl reload haproxy
  7. Request the metrics endpoint from the HAProxy host.
    $ curl -sS http://127.0.0.1:8405/metrics
    # HELP haproxy_process_nbthread Number of started threads
    haproxy_process_nbthread 10
    # HELP haproxy_process_uptime_seconds How long ago this worker process was started
    haproxy_process_uptime_seconds 4
    ##### snipped #####

    The response should use Prometheus text exposition format and include haproxy_ metric names.

  8. Add a Prometheus scrape job for the endpoint.
    prometheus.yml
    scrape_configs:
      - job_name: haproxy
        metrics_path: /metrics
        static_configs:
          - targets:
              - 127.0.0.1:8405
            labels:
              role: edge-lb

    Generate the final job with stable labels, intervals, and target grouping before changing Prometheus.
    Tool: Prometheus Scrape Config Generator

  9. Reload Prometheus to load the new scrape job.
    $ sudo systemctl reload prometheus

    A container or a custom install without this service needs SIGHUP or a request to /-/reload instead.
    Related: How to reload Prometheus configuration

  10. Check that Prometheus reports the haproxy target as up.
    $ promtool query instant http://127.0.0.1:9090 'up{job="haproxy"}'
    up{instance="127.0.0.1:8405", job="haproxy", role="edge-lb"} => 1 @[1794031169.702]

    Value 1 means the last scrape succeeded, and no result appears until the first scrape finishes. The Prometheus web interface shows the same target as UP under Status → Target health at /targets.
    Related: How to check Prometheus targets

Share this guide