Core concepts
Converters
A converter is a built-in function that transforms the value returned by a fetch method.
Using converters Jump to heading
One of the available converters is the lower
converter which you can use to make a string lowercase.
In the example below, we get the HTTP request method (e.g. GET
or POST
) via the method
fetch and then use the lower
converter to make it lowercase. For example, GET
would become get
. The http-request capture
directive stores this data in the access logs:
haproxy
frontend wwwbind :80http-request capture method,lower len 10
haproxy
frontend wwwbind :80http-request capture method,lower len 10
You can also chain converters one after another. In the next example, the rand
fetch returns a random number between 0 and 100. We pass the result to the mul
converter to multiply it by 2; Then the sub
converter subtracts 5, the add
converter adds 3, and the div
converter divides it by 2:
haproxy
frontend wwwbind :80http-request add-header X-Random rand(1:100),mul(2),sub(5),add(3),div(2)
haproxy
frontend wwwbind :80http-request add-header X-Random rand(1:100),mul(2),sub(5),add(3),div(2)
when() converter Jump to heading
Available since
- HAProxy 3.1
- HAProxy Enterprise 3.1
- HAProxy ALOHA 17.0
The when()
converter enables you to pass data from an input sample preceding the converter, such as debugging information, only when a condition is met, such as an error condition. The when()
converter is flexible in terms of the conditions you are able to provide to it, and you can prefix a condition with !
to negate it. You can also specify an ACL to evaluate. The available conditions are:
Condition | Description |
---|---|
error |
Returns true when an error was encountered during stream processing. |
forwarded |
Returns true when the request was forwarded to a backend. |
normal |
Returns true when no error occurred. |
processed |
Returns true when the request was either forwarded to a backend server or processed by an applet. |
stopping |
Returns true if the process is currently stopping. |
acl |
Returns true when the ACL condition evaluates to true. Use this condition like so, specifying the ACL condition and ACL name separated by a comma: when(acl,<acl_name>) . |
Use when() to log data condtionally Jump to heading
You can provide the when()
converter with a condition that tells the load balancer to log debugging information only when there is an error. You can access this debugging information by using the sample fetch fs.debug_str
, which returns data from the lower layers of the frontend stream and connection, and by using the sample fetch bs.debug_str
for the backend data. Note that using these sample fetches on their own, that is, to log the information on every request, even those without error, may be too verbose. To prevent flooding the logs, it is best to use them with the when()
converter so that the debug information will only appear in the logs when there is an error.
Example #1: Conditionally log debug_str Jump to heading
To append extra debugging information to a log message upon error in a frontend, add a log format statement like this to your frontend, using the condition normal
and prefix it with !
to negate the condition:
haproxy
log-format "$HAPROXY_HTTP_LOG_FMT dbg={%[fs.debug_str,when(!normal)]}"
haproxy
log-format "$HAPROXY_HTTP_LOG_FMT dbg={%[fs.debug_str,when(!normal)]}"
This says: append the frontend debug to the log message only when the results of the expression are not normal. “Normal” in this case refers to the scenario where no error occurs in processing. When this condition is met, that is, an error occurred, the load balancer will append the contents of the debug string to the log message, for example:
outputtext
172.18.0.1:49698 [05/Dec/2024:18:45:41.631] myfrontend webservers/s1 0/0/1/39/40 200 206 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" dbg={ h1s=0x791735bcf080 h1s.flg=0x14010 .sd.flg=0x50404601 .req.state=MSG_DONE .res.state=MSG_DONE .meth=GET status=200 .sd.flg=0x50404601 .sc.flg=0x00034482 .sc.app=0x791735ae6400 .subs=0 h1c.flg=0x0 .sub=0 .ibuf=0@0+0/0 .obuf=0@0+0/0 .task=0x791735bbe400 .exp=<NEVER> conn.flg=0x80000300}
outputtext
172.18.0.1:49698 [05/Dec/2024:18:45:41.631] myfrontend webservers/s1 0/0/1/39/40 200 206 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" dbg={ h1s=0x791735bcf080 h1s.flg=0x14010 .sd.flg=0x50404601 .req.state=MSG_DONE .res.state=MSG_DONE .meth=GET status=200 .sd.flg=0x50404601 .sc.flg=0x00034482 .sc.app=0x791735ae6400 .subs=0 h1c.flg=0x0 .sub=0 .ibuf=0@0+0/0 .obuf=0@0+0/0 .task=0x791735bbe400 .exp=<NEVER> conn.flg=0x80000300}
If the condition for logging is not met, that is, no error occurred, the load balancer logs a dash (-
) in the log message instead.
Example #2: Conditionally log last_entity Jump to heading
You can also identify the entity, that is, the rule or filter, that was either the last evaluated during the stream analysis before an error occurred or that was stuck waiting to continue its processing when an error occured. For this, use the sample fetches last_entity
to retrieve the ID of the entity that completed its processing and waiting_entity
to retrieve the ID of the entity that was left waiting. Used with the when()
converter, this looks like:
haproxy
log-format "$HAPROXY_HTTP_LOG_FMT %{Q}[last_entity,when(error)]
haproxy
log-format "$HAPROXY_HTTP_LOG_FMT %{Q}[last_entity,when(error)]
In this example with the condition for when()
set to error, the load balancer will log the entity ID for the entity that was the last to complete its processing.
See also Jump to heading
Do you have any suggestions on how we can improve the content of this page?