Enterprise modules
Traffic mirroring
This page applies to:
- HAProxy Enterprise 1.9r1 and newer
HAProxy Enterprise can mirror traffic to a different environment, even one on a different network. Traffic mirroring, also called traffic shadowing, can be useful for copying live production traffic to another environment for such purposes as:
- QA
- Staging
- Auditing
- Network analytics
- Security applications (such as IDS)
Traffic mirroring has almost no impact on clients because the load balancer does not wait for a response from the mirrored environment. The mirroring process is basically “fire and forget”, where requests are copied to the mirrored environment and forgotten. Only HTTP traffic can be mirrored.
Architecture Jump to heading
A mirroring deployment consists of these components:
- The server where the load balancer resides.
- The Stream Processing Offload Engine (SPOE) mirroring engine, also running on the load balancer server.
- The production web servers.
- The mirror server that receives the copied traffic sent by the mirroring engine. This is the server running the mirrored services described previously, such as QA, auditing, or analytics.

The data flow occurs as follows:
- The user client sends a request to the load balancer frontend.
- The frontend sends the request to the regular (production) backends and mirror backends.
- The regular backend processes the request normally, sending the request to the production web servers.
- The mirror backend copies the request, sending it to the SPOE mirror engine.
- The SPOE mirror engine sends the request to the mirror server in the secondary environment used for testing, auditing, or other purposes.
Configure traffic mirroring Jump to heading
To configure mirroring of traffic:
- 
Install the required packages on the HAProxy Enterprise node: nixsudo apt-get install hapee-extras-spoa-mirrornixsudo apt-get install hapee-extras-spoa-mirrornixsudo yum install hapee-extras-spoa-mirrornixsudo yum install hapee-extras-spoa-mirrornixsudo zypper install hapee-extras-spoa-mirrornixsudo zypper install hapee-extras-spoa-mirrornixsudo pkg install hapee-extras-spoa-mirrornixsudo pkg install hapee-extras-spoa-mirror
- 
Configure HAProxy Enterprise to send traffic to the agent. Add a filter spoedirective to your frontend, as shown:haproxy# Production frontendfrontend fe_mainmode httpbind :80option http-buffer-requestdefault_backend be_serversfilter spoe engine mirror config /etc/hapee-extras/hapee-mirror-spoe.cfghaproxy# Production frontendfrontend fe_mainmode httpbind :80option http-buffer-requestdefault_backend be_serversfilter spoe engine mirror config /etc/hapee-extras/hapee-mirror-spoe.cfgThis directive specifies the mirror engine name and the mirror configuration file name. We cover these items in a later section. 
- 
In addition to the backend that specifies your production servers, add a backend that specifies the server and port of the SPOE mirror agent. Here’s an example: haproxy# Mirror agentsbackend mirroragentsmode tcpbalance roundrobintimeout connect 5stimeout server 10soption spop-checkserver spoe-mirror-agent1 127.0.0.1:12345 checkhaproxy# Mirror agentsbackend mirroragentsmode tcpbalance roundrobintimeout connect 5stimeout server 10soption spop-checkserver spoe-mirror-agent1 127.0.0.1:12345 checkThis example also uses option spop-check, which enables health checking of SPOE agents via the SPOE protocol.
- 
Edit the mirror engine configuration file, /etc/hapee-extras/hapee-mirror-spoe.cfg, specified by thefilter spoedirective in the HAProxy Enterprise configuration file.Add the following content to the mirror engine configuration file: hapee-mirror-spoe.cfgini[mirror]spoe-agent mirrorlog globalmessages mirroruse-backend mirroragentstimeout hello 500mstimeout idle 5stimeout processing 5sspoe-message mirrorargs arg_method=method arg_path=url arg_ver=req.ver arg_hdrs=req.hdrs_bin arg_body=req.bodyevent on-frontend-http-requesthapee-mirror-spoe.cfgini[mirror]spoe-agent mirrorlog globalmessages mirroruse-backend mirroragentstimeout hello 500mstimeout idle 5stimeout processing 5sspoe-message mirrorargs arg_method=method arg_path=url arg_ver=req.ver arg_hdrs=req.hdrs_bin arg_body=req.bodyevent on-frontend-http-requestThis file configures how HAProxy Enterprise communicates with the SPOE mirror agent. 
- 
The agent mirrors data to http://localhost:10100/by default. To change this URI, edit the configuration file:- On Debian/Ubuntu, /etc/default/hapee-extras-spoa-mirror
- On Alma/Oracle/Red Hat/Rocky, /etc/sysconfig/hapee-extras-spoa-mirror
 Modify the -uoption in theMIRROR_OPTIONSenvironment variable to send traffic to a new URL. You can specify a domain or an IP address. The port is optional. You may define only one destination URL. Examples:hapee-extras-spoa-mirrortext# Set destination URL to an FQDN without portMIRROR_OPTIONS="-D -r0 -uhttp://mirror.mysite.com/"# Set destination URL to an IP address with portMIRROR_OPTIONS="-D -r0 -uhttp://192.168.41.10:10100"# Set destination URL to localhost with portMIRROR_OPTIONS="-D -r0 -uhttp://localhost:8100/"hapee-extras-spoa-mirrortext# Set destination URL to an FQDN without portMIRROR_OPTIONS="-D -r0 -uhttp://mirror.mysite.com/"# Set destination URL to an IP address with portMIRROR_OPTIONS="-D -r0 -uhttp://192.168.41.10:10100"# Set destination URL to localhost with portMIRROR_OPTIONS="-D -r0 -uhttp://localhost:8100/"
- On Debian/Ubuntu, 
- 
Enable the mirror agent: nixsudo systemctl enable hapee-extras-spoa-mirrornixsudo systemctl enable hapee-extras-spoa-mirror
- 
Restart the mirror agent and HAProxy Enterprise: nixsudo systemctl restart hapee-extras-spoa-mirrorsudo systemctl restart hapee-3.2-lbnixsudo systemctl restart hapee-extras-spoa-mirrorsudo systemctl restart hapee-3.2-lb
Logging Jump to heading
Mirrored requests are logged to the file /var/log/hapee-3.2/lb-access-<date>.log by default.
An example log statement is shown below:
lb-access-20231205.logtext
lb-access-20231205.logtext
An st (status code) value of 0 indicates success.
Tune mirrored traffic Jump to heading
There are several ways to tune the traffic that is mirrored.
- Filtering
- Sampling
- Mapping key-value pairs
- Making runtime changes using the Data Plane API
Filtering Jump to heading
You can add an ACL that limits the requests that are captured. For instance, if you only want to mirror traffic for requests to the /search feature on your site, you would  ignore all requests except those that have a URL path beginning with /search, as shown:
hapee-mirror-spoe.cfgini
hapee-mirror-spoe.cfgini
You can also define named ACLs that do the same thing:
hapee-mirror-spoe.cfgini
hapee-mirror-spoe.cfgini
Sampling Jump to heading
Suppose you don’t want to capture all traffic but rather only a portion of it. You would add an ACL that collects a random sample of requests. In the next example, we generate a random number between 1 and 100 and only mirror the request if that number is less than or equal to 10:
hapee-mirror-spoe.cfgini
hapee-mirror-spoe.cfgini
Mapping key-value pairs Jump to heading
Your ACL statements can also check values from map files. For example, you can switch mirroring on or off by using a map file that contains a key-value pair like mirroring on. Then, check the map file from your hapee-mirror-spoe.cfg file like this:
hapee-mirror-spoe.cfgini
hapee-mirror-spoe.cfgini
Use the HAProxy Enterprise Runtime API to change the value in the map file to off.
nix
nix
Make changes using the Data Plane API Jump to heading
You can also use the Data Plane API to add or remove filter spoe lines from the HAProxy Enterprise configuration file dynamically. In the following example, we show the existing filters, then add a new one, and then remove it:
Show existing filters:
nix
nix
Add a filter line:
nix
nix
outputtext
outputtext
Remove a filter line:
nix
nix
Tip
Here are a few ways to get the most out of traffic mirroring.
- After setting up monitoring, compare the errors you get from your production servers with those you get from the new version to which you’re mirroring traffic. Having a monitoring strategy in place will be key to validating a release.
- Make sure the feature you’re testing has URL paths and parameters that match the existing feature so that it is forward compatible with mirrored traffic. Forward compatibility may be a valuable test in and of itself.
Troubleshooting Jump to heading
Traffic mirroring in HAProxy Enterprise allows you to replicate network traffic to a separate destination for monitoring and analysis purposes. Here are some suggestions to help you diagnose and resolve common problems with traffic mirroring functionality.
Confirm the HAProxy Enterprise version Jump to heading
Make sure you are using a version of HAProxy Enterprise that supports traffic mirroring. The mirroring feature was introduced in version 1.9.0, so if you’re using an older version, consider upgrading to a compatible release.
nix
nix
outputtext
outputtext
Check network connectivity Jump to heading
Ensure that the destination IP address and port specified for mirroring are reachable from the HAProxy Enterprise server. Verify the network connectivity between the two systems using tools like ping or telnet. If there are any firewalls, security groups, or access control lists in place, ensure they allow traffic between HAProxy Enterprise and the mirroring destination.
Monitor resource utilization Jump to heading
Traffic mirroring can be resource-intensive, especially if the mirrored traffic volume is significant. Monitor the resource utilization of the HAProxy Enterprise, including CPU, memory, and network usage. Ensure that the server has enough capacity to handle the additional load caused by mirroring.
Check SPOE mirror agent activity status Jump to heading
Check if the agent is running on the system:
nix
nix
outputtext
outputtext
You can also check via the system status command:
nix
nix
outputtext
outputtext
If the process is in an error state, you can run journalctl -xe| grep -A3 -B3 -i spoa for more details.
Check the logs Jump to heading
- 
Search the /var/log/hapee-3.2/logs for any issues. For example,st=0means a successful response.lb-access-20231205.loginiMay 31 16:59:51 ip-172-31-13-131 hapee-lb[713]:: SPOE: [mirror] <EVENT:on-frontend-http-request> sid=52 st=0 0/0/0/0/0 1/1 0/0 1/25lb-access-20231205.loginiMay 31 16:59:51 ip-172-31-13-131 hapee-lb[713]:: SPOE: [mirror] <EVENT:on-frontend-http-request> sid=52 st=0 0/0/0/0/0 1/1 0/0 1/25
- 
Enable logging for the mirroring agent: nixsudo touch /var/log/hapee-mirror.logsudo chown hapee-mirror:hapee /var/log/hapee-mirror.lognixsudo touch /var/log/hapee-mirror.logsudo chown hapee-mirror:hapee /var/log/hapee-mirror.log
- 
Use your editor to add --logfile=a:to the startup script:- On Debian/Ubuntu, /etc/default/hapee-extras-spoa-mirror
- On Alma/Oracle/Red Hat/Rocky, /etc/sysconfig/hapee-extras-spoa-mirror
 This option determines the mode of logging, which allows opening and writing at end-of-file. If a capital letter is used for the mode, then line buffering is used when writing to the log file. hapee-extras-spoa-mirroriniMIRROR_OPTIONS="-D -r0 -uhttp://10.0.1.4:8080/ --logfile=A:/var/log/hapee-mirror.log"hapee-extras-spoa-mirroriniMIRROR_OPTIONS="-D -r0 -uhttp://10.0.1.4:8080/ --logfile=A:/var/log/hapee-mirror.log"The mirror agent will fail to start if mode is used without a defined log file. 
- On Debian/Ubuntu, 
Traffic mirroring reference Jump to heading
The SPOE mirror engine uses Stream Processing Offload Protocol (SPOP). The file /etc/hapee-extras/hapee-mirror-spoe.cfg configures how HAProxy Enterprise communicates with the SPOE mirror agent.
hapee-mirror-spoe.cfgini
hapee-mirror-spoe.cfgini
It supports the following directives in the spoe-agent section:
| Directive | Description | 
|---|---|
| [*name*] | The file begins with an engine name, mirror, in square brackets. As mentioned, this name must match theengineparameter value set on thefilter spoedirective in the HAProxy Enterprise configuration. | 
| log global | This line means that events, such as when HAProxy Enterprise sends data, will be logged to the same output defined by the logstatement in theglobalsection of the HAProxy Enterprise configuration. | 
| messages | This line is a space-delimited list of labels that match up with spoe-messagesections. | 
| use-backend | This line specifies which backend in the HAProxy Enterprise configuration holds the mirror agents. | 
| timeout hello | This setting limits how long HAProxy Enterprise will wait for an agent to acknowledge a connection. | 
| timeout idle | This setting limits how long HAProxy Enterprise will wait for an agent to close an idle connection. | 
| timeout processing | This setting limits how long an agent is allowed to process an event. | 
A spoe-message section defines which HAProxy Enterprise fetch methods will be used to capture data to send to the agents. The label here, mirror, is expected by this particular agent. For traffic mirroring, we capture the following:
- the HTTP method
- the URL path
- the version of HTTP
- all HTTP headers
- the request body (note that this requires option http-buffer-requestin the HAProxy Enterprise configuration)
Data is sent every time the on-frontend-http-request event fires, which is before the evaluation of http-request rules on the frontend side.
The options supported by hapee-spoa-mirror can be found using -h or --help:
nix
nix
outputtext
outputtext
Supported libev backends: select, poll, epoll, linuxaio, iouring.
Supported capabilities: fragmentation, pipelining, async.
Allowed logging file opening modes: a, w. The a mode allows opening or creating file for writing at end-of-file. The w mode allows truncating the file to zero length or creating a new file. If a capital letter is used for the mode, then line buffering is used when writing to the log file.
The time delay/interval is specified in milliseconds by default, but can be in any other unit if the number is suffixed by a unit (us, ms, s, m, h, d).
Traffic mirroring log reference Jump to heading
SPOE mirror agent activity is logged using HAProxy Enterprise’s logger. Mirrored requests are logged to the file /var/log/hapee-3.2/lb-access-<date>.log by default. A message is emitted for each mirrored request. Depending on the status code, the log level will be different. In the normal case, when no error occurred, the message is logged with the level LOG_NOTICE. If an error occurred, the message is logged with the level LOG_WARNING.
Consider the following example log message for a mirrored request:
An example log statement is shown below:
lb-access-20231205.logtext
lb-access-20231205.logtext
In this example, the mirror agent logged an event named on-frontend-http-request with a stream-id of 707. Its status code of 0 indicates it was successful. One event was processed and had zero errors.
Mirror agent log messages follow this format:
lb-access-20231205.logtext
lb-access-20231205.logtext
| Log message item | Description | 
|---|---|
| AGENT | The agent name. It is mirrorfor the mirror agent. | 
| TYPE | For mirrored requests this is EVENT. | 
| NAME | The event name. | 
| STREAM-ID | The unique integer id of the stream. | 
| STATUS_CODE | The request’s status code. A status code of 0indicates success. Other status codes include:1: I/O error;2: A timeout occurred;3: Frame is too big;4: Invalid frame received;5: Version value not found;6:max-frame-sizevalue not found;7: Capabilities value not found;8: Unsupported version;9:max-frame-sizetoo big or too small;10: Payload fragmentation is not supported;11: Invalid interlaced frames;12:frame-idnot found (it does not match any referenced frame);13: Resource allocation error;99: An unknown error occurred | 
| reqT/qT/wT/resT/pT | These represent the following time events: reqT: The encoding time. It includes ACLs processing time, if applicable. For fragmented frames, it is the sum of all fragments.qT: The delay before the request leaves the sending queue. For fragmented frames, it is the sum of all fragments.wT: The delay before the response is received. Fragmentation is not supported.resT: The delay in processing the response. Fragmentation is not supported.pT: The delay in processing the event; it is the latency added by the SPOE processing. It is more or less the sum of the other values. For all of these time events,-1means the process was interrupted. For example,-1for the queue time means the request never left the queue. Note that for fragmented frames it is harder to know when an interruption occurred. | 
| <idle> | The number of idle SPOE applets. | 
| <applets> | The number of SPOE applets. | 
| <nb_sending> | The number of streams waiting to send data. | 
| <nb_waiting> | The number of streams waiting for an ack. | 
| <nb_error> | The number of processing errors. | 
| <nb_processed> | The number of events processed. | 
Do you have any suggestions on how we can improve the content of this page?