HAProxy Discovery

This document describes the use of discovery plugin for HA proxy

Introduction

This HAProxy discovery plugin for Pandora FMS is designed to automate the monitoring of your HAProxy load balancers by leveraging the detailed information exposed by the CSV stats endpoint (/stats;csv). By interacting with that endpoint, the plugin collects real-time metrics that are crucial to understanding the performance and health of your HAProxy environment, including sessions, transferred bytes, errors, queues, health checks, and much more. For every HAProxy URL configured, the plugin will create one agent in Pandora FMS with one module per available metric.

Prerrequisites

HAProxy Configuration

In order for the plugin to gather statistics, HAProxy must expose the /stats;csv endpoint. This is done by editing the haproxy.cfg file (default location: /etc/haproxy/haproxy.cfg).

Minimum configuration (no authentication, no SSL)

Add a dedicated frontend for statistics:

frontend stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s

With this configuration the plugin will consume the URL:

http://<SERVER_IP>:8404/stats

The plugin automatically normalizes the URL by appending the ;csv suffix and the norefresh parameter when missing, so it is enough to provide the base stats URL.

Configuration with basic authentication

To protect the endpoint with a username and password, define a userlist and apply http-request auth on the stats frontend:

frontend stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s

    acl auth_ok http_auth(stats_users)
    http-request auth realm stats if !auth_ok

userlist stats_users
    user admin password $6$rounds=5000$<SHA512_HASH>

Generate the password hash with mkpasswd or openssl:

mkpasswd -m sha-256 mypassword
# or
openssl passwd -6 mypassword

In the plugin, the same username and password must be provided through --user / --password (or the username / password fields in the configuration file).

Configuration with SSL/TLS

To serve the stats over HTTPS, add ssl crt to the bind directive:

frontend stats
    bind *:8404 ssl crt /etc/haproxy/certs/stats.pem
    stats enable
    stats uri /stats
    stats refresh 10s

Generate a self-signed certificate for testing with:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/haproxy/certs/stats.key \
  -out /etc/haproxy/certs/stats.crt \
  -subj "/CN=localhost"
cat /etc/haproxy/certs/stats.crt /etc/haproxy/certs/stats.key > /etc/haproxy/certs/stats.pem

In the plugin, point to the URL with the https:// scheme and set the --ssl (or verify_ssl) parameter depending on whether the certificate should be validated:

Complete configuration (SSL + authentication)

global
    maxconn 4096

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s

frontend stats
    bind *:8404 ssl crt /etc/haproxy/certs/stats.pem
    stats enable
    stats uri /stats
    stats refresh 10s
    stats admin if TRUE

    acl auth_ok http_auth(stats_users)
    http-request auth realm stats if !auth_ok

userlist stats_users
    user admin password $6$rounds=5000$<SHA512_HASH>

frontend myapp
    bind *:80
    default_backend servers

backend servers
    server s1 127.0.0.1:8080 check

After modifying haproxy.cfg, reload the service to apply the changes:

sudo systemctl reload haproxy

Verification

To confirm that the endpoint is responding correctly, you can make a manual request to the stats CSV:

curl -u admin:mypassword http://192.168.0.10:8404/stats;csv

The output must be a CSV whose first record is the header with the column names (# pxname,svname,qcur,qmax,...) and the following rows contain the data of each frontend, backend and server.

Parameters

Simple mode

--urlsHAProxy stats endpoint URLs, comma-separated. Each URL will create one agent.
--userusername if the HAProxy endpoint requires basic authentication, optional
--passwordpassword if the HAProxy endpoint requires basic authentication, optional
--sslwhether the URL has an HTTPS certificate to be verified, optional
--prefixprefix for the module names, optional
--transfer_modedata transfer mode (native or tentacle), optional
--tentacle_iptentacle IP, optional
--tentacle_porttentacle port, optional
--intervalmonitoring interval in seconds, optional
--allow_listregular expression to include only modules whose name matches, optional
--deny_listregular expression to exclude modules whose name matches, optional
--monitor_frontendsmonitor frontend rows (type=0), optional
--monitor_backendsmonitor backend rows (type=1), optional
--monitor_serversmonitor server rows (type=2), optional

Advanced mode

--confpath to the configuration file
--conf_targetspath to the file with the HAProxy URLs (mandatory when using --conf)

Configuration file (--conf)

username= username if the HAProxy endpoint requires basic authentication, optional
password= password if the HAProxy endpoint requires basic authentication, optional
verify_ssl= whether the URL has an HTTPS certificate to be verified, optional
prefix= prefix for the module names, optional
transfer_mode= data transfer mode (native or tentacle), optional
tentacle_ip= tentacle IP, optional
tentacle_port= tentacle port, optional
agents_group= name of the agent group the created agents will be assigned to, optional
agents_group_id= ID of the agent group the created agents will be assigned to, optional
interval= monitoring interval in seconds, optional
allow_list= regular expression to include only modules whose name matches, optional
deny_list= regular expression to exclude modules whose name matches, optional
monitor_frontends= monitor frontend rows (type=0), optional
monitor_backends= monitor backend rows (type=1), optional
monitor_servers= monitor server rows (type=2), optional

Example

[CONF]
username=admin
password=12345
verify_ssl=true
prefix=haproxy_
transfer_mode=native
tentacle_ip=127.0.0.1
tentacle_port=41121
interval=300
allow_list=
deny_list=.*_wredis|.*_wretr
monitor_frontends=true
monitor_backends=true
monitor_servers=true

Targets file (--conf_targets):

http://192.168.0.10:8404/stats
http://192.168.0.11:8404/stats

Manual execution

The plugin execution format is as follows:

./pandora_haproxy --urls <HAProxy endpoint URLs comma-separated> --user <username> --password <password> --ssl <true|false> --prefix <prefix> --transfer_mode <native|tentacle> --tentacle_ip <tentacle IP> --tentacle_port <tentacle port> --interval <interval> --allow_list <regex> --deny_list <regex> --monitor_frontends <true|false> --monitor_backends <true|false> --monitor_servers <true|false> --conf <path to configuration file> --conf_targets <path to URLs file>

Examples:

to run the simple mode

./pandora_haproxy --urls http://192.168.0.10:8404/stats,http://192.168.0.11:8404/stats --user admin --password 12345 --ssl false --transfer_mode native --tentacle_ip 127.0.0.1 --tentacle_port 41121

to run the advanced mode

./pandora_haproxy --conf /etc/pandora/haproxy.conf --conf_targets /etc/pandora/haproxy_targets.conf

The execution will return a JSON output with information about the run, and will generate an XML file for every monitored agent (in tentacle mode) that will be sent to the Pandora FMS server using the transfer method configured. In native mode the data is exposed in the monitoring_data field of the JSON output to be consumed by the Discovery server.

Discovery

This plugin can be integrated with Pandora FMS Discovery.

To do so, the ".disco" package must be loaded. It can be downloaded from the Pandora FMS library:

https://pandorafms.com/library/

Once loaded, HAProxy instances can be monitored by creating Discovery tasks from the Management > Discovery > Application > HAProxy section.

Each task will require the following minimum data in the HAProxy Basic step:

In the HAProxy Advanced step the following additional options can be configured:

Successfully completed tasks will have an execution summary with the following information:

Agent and modules generated by the plugin

The plugin will create one agent for every HAProxy URL configured. The agent name is computed as an MD5 hash of the URL netloc, and the alias is set to that same netloc (for example, 192.168.0.10:8404). Each agent includes the modules obtained by parsing the HAProxy CSV stats endpoint.

The status module is created always for every row, regardless of the monitor tokens, in order to alert on DOWN/MAINT/STOP states. The remaining numeric fields are included as generic_data (integer/decimal) or generic_data_string (string) modules, following the format <pxname>_<svname>_<field>.

The main fields available in the HAProxy CSV that generate modules are:

pxname: Proxy name (frontend/backend/listener).
svname: Service name (FRONTEND/BACKEND/server name).
qcur: Current queued requests.
qmax: Max queued requests.
scur: Current sessions.
smax: Max sessions.
slim: Configured session limit.
stot: Cumulative sessions.
bin: Bytes in.
bout: Bytes out.
dreq: Requests denied (security).
dresp: Responses denied (security).
ereq: Request errors.
econ: Connection errors to backend.
eresp: Response errors.
wretr: Connection retries.
wredis: Redispatches to another server.
status: Status (UP/DOWN/MAINT/STOP/...) — always monitored.
weight: Total weight / server weight.
act: Active servers (backend) / server active.
bck: Backup servers (backend) / server backup.
chkfail: Failed health checks.
chkdown: UP->DOWN transitions.
lastchg: Seconds since last UP<->DOWN transition.
downtime: Total downtime (seconds).
qlimit: Configured maxqueue for the server.
pid: Process ID.
iid: Unique proxy ID.
sid: Server ID (unique inside the proxy).
throttle: Current throttle percentage.
lbtot: Times the server was selected.
tracked: ID of proxy/server if tracking is enabled.
type: Type (0=frontend, 1=backend, 2=server, 3=socket).
rate: Sessions per second (last second).
rate_lim: Configured limit on new sessions/s.
rate_max: Max sessions per second.
check_status: Status of the last health check.
check_code: Layer 5-7 check code.
check_duration: Time in ms of the last health check.
hrsp_1xx: HTTP responses with 1xx code.
hrsp_2xx: HTTP responses with 2xx code.
hrsp_3xx: HTTP responses with 3xx code.
hrsp_4xx: HTTP responses with 4xx code.
hrsp_5xx: HTTP responses with 5xx code.
hrsp_other: HTTP responses with other codes.
hanafail: Failed health checks details.
req_rate: HTTP requests per second.
req_rate_max: Max HTTP requests per second.
req_tot: Total HTTP requests received.
cli_abrt: Data transfers aborted by the client.
srv_abrt: Data transfers aborted by the server.
comp_in: HTTP response bytes fed to the compressor.
comp_out: HTTP response bytes emitted by the compressor.
comp_byp: Bytes that bypassed the HTTP compressor.
comp_rsp: HTTP responses that were compressed.
lastsess: Seconds since the last session was assigned.
last_chk: Last health check contents/error.
last_agt: Last agent check contents/error.
qtime: Average queue time (ms) over the last 1024 requests.
ctime: Average connect time (ms) over the last 1024 requests.
rtime: Average response time (ms) over the last 1024 requests.
ttime: Average total session time (ms) over the last 1024 requests.
agent_status: Status of the last agent check.
agent_code: Numeric code reported by the agent.
agent_duration: Time in ms of the last agent check.
check_desc: Human-readable description of check_status.
agent_desc: Human-readable description of agent_status.
check_rise: Server's rise parameter used by checks.
check_fall: Server's fall parameter used by checks.
check_health: Server's health check value.
agent_rise: Agent's rise parameter.
agent_fall: Agent's fall parameter.
agent_health: Agent's health parameter.
addr: Address:port or unix socket.
cookie: Server's cookie value or backend's cookie name.
mode: Proxy mode (tcp, http, health, unknown).
algo: Load balancing algorithm.
conn_rate: Connections over the last elapsed second.
conn_rate_max: Highest known conn_rate.
conn_tot: Cumulative number of connections.
intercepted: Cumulative intercepted requests.
dcon: Requests denied by tcp-request connection rules.
dses: Requests denied by tcp-request session rules.

The status module is translated to a numeric value according to the following mapping: 5=UP, 4=OPEN, 3=NOLB, 2=MAINT, 1=STOP/STOPPING, 0=DOWN, which allows configuring alerts based on warning (2-4) and critical (0-2) thresholds.