blob: 2001c1fa049e48251b3908a2104ef7ed34ca576d [file] [log] [blame]
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001 -----------------------------------------------
2 Stream Processing Offload Engine (SPOE)
Christopher Faulet57583e42017-09-04 15:41:09 +02003 Version 1.2
Christopher Faulet3b788092020-05-13 08:25:12 +02004 ( Last update: 2020-06-13 )
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02005 -----------------------------------------------
6 Author : Christopher Faulet
7 Contact : cfaulet at haproxy dot com
8
9
10SUMMARY
11--------
12
13 0. Terms
14 1. Introduction
15 2. SPOE configuration
16 2.1. SPOE scope
17 2.2. "spoe-agent" section
18 2.3. "spoe-message" section
Christopher Faulet11610f32017-09-21 10:23:10 +020019 2.4. "spoe-group" section
20 2.5. Example
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020021 3. SPOP specification
22 3.1. Data types
23 3.2. Frames
24 3.2.1. Frame capabilities
25 3.2.2. Frame types overview
26 3.2.3. Workflow
27 3.2.4. Frame: HAPROXY-HELLO
28 3.2.5. Frame: AGENT-HELLO
29 3.2.6. Frame: NOTIFY
30 3.2.7. Frame: ACK
31 3.2.8. Frame: HAPROXY-DISCONNECT
32 3.2.9. Frame: AGENT-DISCONNECT
33 3.3. Events & messages
34 3.4. Actions
Christopher Fauletd1307ce2017-02-27 21:59:39 +010035 3.5. Errors & timeouts
Christopher Fauletb2dd1e02018-03-22 09:07:41 +010036 4. Logging
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020037
38
390. Terms
40---------
41
42* SPOE : Stream Processing Offload Engine.
43
Ilya Shipitsin11057a32020-06-21 21:18:27 +050044 A SPOE is a filter talking to servers managed by a SPOA to offload the
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020045 stream processing. An engine is attached to a proxy. A proxy can have
Christopher Fauletd1307ce2017-02-27 21:59:39 +010046 several engines. Each engine is linked to an agent and only one.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020047
48* SPOA : Stream Processing Offload Agent.
49
50 A SPOA is a service that will receive info from a SPOE to offload the
51 stream processing. An agent manages several servers. It uses a backend to
52 reference all of them. By extension, these servers can also be called
53 agents.
54
55* SPOP : Stream Processing Offload Protocol, used by SPOEs to talk to SPOA
56 servers.
57
58 This protocol is used by engines to talk to agents. It is an in-house
59 binary protocol described in this documentation.
60
61
621. Introduction
63----------------
64
65SPOE is a feature introduced in HAProxy 1.7. It makes possible the
66communication with external components to retrieve some info. The idea started
67with the problems caused by most ldap libs not working fine in event-driven
68systems (often at least the connect() is blocking). So, it is hard to properly
69implement Single Sign On solution (SSO) in HAProxy. The SPOE will ease this
70kind of processing, or we hope so.
71
72Now, the aim of SPOE is to allow any kind of offloading on the streams. First
Christopher Faulet3b788092020-05-13 08:25:12 +020073releases won't do lot of things. As we will see, there are few handled events
74and even less actions supported. Actually, for now, the SPOE can offload the
75processing before "tcp-request content", "tcp-response content", "http-request"
76and "http-response" rules. And it only supports variables definition. But, in
77spite of these limited features, we can easily imagine to implement SSO
78solution, ip reputation or ip geolocation services.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020079
Willy Tarreau86951992021-04-21 09:39:06 +020080Some example implementations in various languages are linked to from the
81HAProxy Wiki page dedicated to this mechanism:
82
83 https://github.com/haproxy/wiki/wiki/SPOE:-Stream-Processing-Offloading-Engine
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020084
852. SPOE configuration
86----------------------
87
88Because SPOE is implemented as a filter, To use it, you must declare a "filter
89spoe" line in a proxy section (frontend/backend/listen) :
90
91 frontend my-front
92 ...
93 filter spoe [engine <name>] config <file>
94 ...
95
96The "config" parameter is mandatory. It specififies the SPOE configuration
97file. The engine name is optional. It can be set to declare the scope to use in
98the SPOE configuration. So it is possible to use the same SPOE configuration
99for several engines. If no name is provided, the SPOE configuration must not
100contain any scope directive.
101
102We use a separate configuration file on purpose. By commenting SPOE filter
Michael Prokop4438c602019-05-24 10:25:45 +0200103line, you completely disable the feature, including the parsing of sections
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200104reserved to SPOE. This is also a way to keep the HAProxy configuration clean.
105
106A SPOE configuration file must contains, at least, the SPOA configuration
Christopher Faulet11610f32017-09-21 10:23:10 +0200107("spoe-agent" section) and SPOE messages/groups ("spoe-message" or "spoe-group"
108sections) attached to this agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200109
110IMPORTANT : The configuration of a SPOE filter must be located in a dedicated
111file. But the backend used by a SPOA must be declared in HAProxy configuration
112file.
113
1142.1. SPOE scope
115-------------------------
116
117If you specify an engine name on the SPOE filter line, then you need to define
118scope in the SPOE configuration with the same name. You can have several SPOE
119scope in the same file. In each scope, you must define one and only one
120"spoe-agent" section to configure the SPOA linked to your SPOE and several
Ilya Shipitsin2a950d02020-03-06 13:07:38 +0500121"spoe-message" and "spoe-group" sections to describe, respectively, messages and
Christopher Faulet11610f32017-09-21 10:23:10 +0200122group of messages sent to servers mananged by your SPOA.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200123
124A SPOE scope starts with this kind of line :
125
126 [<name>]
127
128where <name> is the same engine name specified on the SPOE filter line. The
129scope ends when the file ends or when another scope is found.
130
131 Example :
132 [my-first-engine]
133 spoe-agent my-agent
134 ...
135 spoe-message msg1
136 ...
137 spoe-message msg2
138 ...
Christopher Fauletb2dd1e02018-03-22 09:07:41 +0100139 spoe-group grp1
Christopher Faulet11610f32017-09-21 10:23:10 +0200140 ...
Christopher Fauletb2dd1e02018-03-22 09:07:41 +0100141 spoe-group grp2
142 ...
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200143
144 [my-second-engine]
145 ...
146
147If no engine name is provided on the SPOE filter line, no SPOE scope must be
148found in the SPOE configuration file. All the file is considered to be in the
149same anonymous and implicit scope.
150
Christopher Faulet7ee86672017-09-19 11:08:28 +0200151The engine name must be uniq for a proxy. If no engine name is provided on the
Joseph Herlant71b4b152018-11-13 16:55:16 -0800152SPOE filter line, the SPOE agent name is used by default.
Christopher Faulet7ee86672017-09-19 11:08:28 +0200153
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001542.2. "spoe-agent" section
155--------------------------
156
157For each engine, you must define one and only one "spoe-agent" section. In this
158section, you will declare SPOE messages and the backend you will use. You will
159also set timeouts and options to customize your agent's behaviour.
160
161
162spoe-agent <name>
163 Create a new SPOA with the name <name>. It must have one and only one
164 "spoe-agent" definition by SPOE scope.
165
166 Arguments :
167 <name> is the name of the agent section.
168
169 following keywords are supported :
Christopher Faulet11610f32017-09-21 10:23:10 +0200170 - groups
Christopher Faulet7250b8f2018-03-26 17:19:01 +0200171 - log
Christopher Faulet48026722016-11-16 15:01:12 +0100172 - maxconnrate
173 - maxerrrate
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100174 - max-frame-size
Christopher Faulete8ade382018-01-25 15:32:22 +0100175 - max-waiting-frames
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200176 - messages
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100177 - [no] option async
Christopher Faulet0e0f0852018-03-26 17:20:36 +0200178 - [no] option dontlog-normal
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100179 - [no] option pipelining
180 - [no] option send-frag-payload
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100181 - option continue-on-error
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100182 - option force-set-var
Christopher Faulet985532d2016-11-16 15:36:19 +0100183 - option set-on-error
Christopher Faulet36bda1c2018-03-22 09:08:20 +0100184 - option set-process-time
185 - option set-total-time
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200186 - option var-prefix
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100187 - register-var-names
Christopher Faulet03a34492016-11-19 16:47:56 +0100188 - timeout hello|idle|processing
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200189 - use-backend
190
191
Christopher Faulet11610f32017-09-21 10:23:10 +0200192groups <grp-name> ...
193 Declare the list of SPOE groups that an agent will handle.
194
195 Arguments :
196 <grp-name> is the name of a SPOE group.
197
Joseph Herlant71b4b152018-11-13 16:55:16 -0800198 Groups declared here must be found in the same engine scope, else an error is
Christopher Faulet11610f32017-09-21 10:23:10 +0200199 triggered during the configuration parsing. You can have many "groups" lines.
200
201 See also: "spoe-group" section.
202
203
Christopher Faulet7250b8f2018-03-26 17:19:01 +0200204log global
205log <address> [len <length>] [format <format>] <facility> [<level> [<minlevel>]]
206no log
207 Enable per-instance logging of events and traffic.
208
209 Prefix :
210 no should be used when the logger list must be flushed.
211
212 See the HAProxy Configuration Manual for details about this option.
213
Christopher Faulet48026722016-11-16 15:01:12 +0100214maxconnrate <number>
215 Set the maximum number of connections per second to <number>. The SPOE will
216 stop to open new connections if the maximum is reached and will wait to
217 acquire an existing one. So it is important to set "timeout hello" to a
218 relatively small value.
219
220
221maxerrrate <number>
222 Set the maximum number of errors per second to <number>. The SPOE will stop
223 its processing if the maximum is reached.
224
225
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100226max-frame-size <number>
227 Set the maximum allowed size for frames exchanged between HAProxy and SPOA.
228 It must be in the range [256, tune.bufsize-4] (4 bytes are reserved for the
229 frame length). By default, it is set to (tune.bufsize-4).
230
Christopher Faulete8ade382018-01-25 15:32:22 +0100231max-waiting-frames <number>
232 Set the maximum number of frames waiting for an acknowledgement on the same
Ilya Shipitsin07be66d2023-04-01 12:26:42 +0200233 connection. This value is only used when the pipelinied or asynchronous
Christopher Faulete8ade382018-01-25 15:32:22 +0100234 exchanges between HAProxy and SPOA are enabled. By default, it is set to 20.
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100235
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200236messages <msg-name> ...
237 Declare the list of SPOE messages that an agent will handle.
238
239 Arguments :
240 <msg-name> is the name of a SPOE message.
241
242 Messages declared here must be found in the same engine scope, else an error
243 is triggered during the configuration parsing. You can have many "messages"
244 lines.
245
246 See also: "spoe-message" section.
247
248
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100249option async
250no option async
Ilya Shipitsin07be66d2023-04-01 12:26:42 +0200251 Enable or disable the support of asynchronous exchanges between HAProxy and
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100252 SPOA. By default, this option is enabled.
253
254
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100255option continue-on-error
256 Do not stop the events processing when an error occurred on a stream.
257
258 By default, for a specific stream, when an abnormal/unexpected error occurs,
259 the SPOE is disabled for all the transaction. So if you have several events
Ilya Shipitsin11057a32020-06-21 21:18:27 +0500260 configured, such error on an event will disabled all following. For TCP
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100261 streams, this will disable the SPOE for the whole session. For HTTP streams,
262 this will disable it for the transaction (request and response).
263
264 When set, this option bypass this behaviour and only the current event will
265 be ignored.
266
Christopher Faulet0e0f0852018-03-26 17:20:36 +0200267
268option dontlog-normal
269no option dontlog-normal
270 Enable or disable logging of normal, successful processing.
271
272 Arguments : none
273
274 See also: "log" and section 4 about logging.
275
276
Etienne Carriereaec89892017-12-14 09:36:40 +0000277option force-set-var
278 By default, SPOE filter only register already known variables (mainly from
Willy Tarreau7978c5c2021-09-07 14:24:07 +0200279 parsing of the configuration), and process-wide variables (those of scope
280 "proc") cannot be created. If you want that haproxy trusts the agent and
Etienne Carriereaec89892017-12-14 09:36:40 +0000281 registers all variables (ex: can be useful for LUA workload), activate this
282 option.
283
284 Caution : this option opens to a variety of attacks such as a rogue SPOA that
285 asks to register too many variables.
286
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100287
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100288option pipelining
289no option pipelining
290 Enable or disable the support of pipelined exchanges between HAProxy and
291 SPOA. By default, this option is enabled.
292
293
294option send-frag-payload
295no option send-frag-payload
296 Enable or disable the sending of fragmented payload to SPOA. By default, this
297 option is enabled.
298
299
Christopher Faulet985532d2016-11-16 15:36:19 +0100300option set-on-error <var name>
301 Define the variable to set when an error occurred during an event processing.
302
303 Arguments :
304
305 <var name> is the variable name, without the scope. The name may only
306 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
307
308 This variable will only be set when an error occurred in the scope of the
309 transaction. As for all other variables define by the SPOE, it will be
310 prefixed. So, if your variable name is "error" and your prefix is
311 "my_spoe_pfx", the variable will be "txn.my_spoe_pfx.error".
312
Christopher Fauletb067b062017-01-04 16:39:11 +0100313 When set, the variable is an integer representing the error reason. For values
314 under 256, it represents an error coming from the engine. Below 256, it
315 reports a SPOP error. In this case, to retrieve the right SPOP status code,
316 you must remove 256 to this value. Here are possible values:
317
318 * 1 a timeout occurred during the event processing.
319
Michael Prokop4438c602019-05-24 10:25:45 +0200320 * 2 an error was triggered during the resources allocation.
Christopher Fauletb067b062017-01-04 16:39:11 +0100321
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100322 * 3 the frame payload exceeds the frame size and it cannot be
323 fragmented.
324
325 * 4 the fragmentation of a payload is aborted.
326
Christopher Faulet344c4ab2017-09-22 10:20:13 +0200327 * 5 The frame processing has been interrupted by HAProxy.
328
Christopher Fauletb067b062017-01-04 16:39:11 +0100329 * 255 an unknown error occurred during the event processing.
330
331 * 256+N a SPOP error occurred during the event processing (see section
332 "Errors & timeouts").
333
334 Note that if "option continue-on-error" is set, the variable is not
335 automatically removed between events processing.
Christopher Faulet985532d2016-11-16 15:36:19 +0100336
337 See also: "option continue-on-error", "option var-prefix".
338
Christopher Faulet36bda1c2018-03-22 09:08:20 +0100339
340option set-process-time <var name>
341 Define the variable to set to report the processing time of the last event or
342 group.
343
344 Arguments :
345
346 <var name> is the variable name, without the scope. The name may only
347 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
348
349 This variable will be set in the scope of the transaction. As for all other
350 variables define by the SPOE, it will be prefixed. So, if your variable name
351 is "process_time" and your prefix is "my_spoe_pfx", the variable will be
352 "txn.my_spoe_pfx.process_time".
353
354 When set, the variable is an integer representing the delay to process the
355 event or the group, in milliseconds. From the stream point of view, it is the
356 latency added by the SPOE processing for the last handled event or group.
357
358 If several events or groups are processed for the same stream, this value
359 will be overrideen.
360
361 See also: "option set-total-time".
362
363
364option set-total-time <var name>
365 Define the variable to set to report the total processing time SPOE for a
366 stream.
367
368 Arguments :
369
370 <var name> is the variable name, without the scope. The name may only
371 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
372
373 This variable will be set in the scope of the transaction. As for all other
374 variables define by the SPOE, it will be prefixed. So, if your variable name
375 is "total_time" and your prefix is "my_spoe_pfx", the variable will be
376 "txn.my_spoe_pfx.total_time".
377
378 When set, the variable is an integer representing the sum of processing times
379 for a stream, in milliseconds. From the stream point of view, it is the
380 latency added by the SPOE processing.
381
382 If several events or groups are processed for the same stream, this value
383 will be updated.
384
385 See also: "option set-process-time".
386
387
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200388option var-prefix <prefix>
389 Define the prefix used when variables are set by an agent.
390
391 Arguments :
392
393 <prefix> is the prefix used to limit the scope of variables set by an
394 agent.
395
396 To avoid conflict with other variables defined by HAProxy, all variables
397 names will be prefixed. By default, the "spoe-agent" name is used. This
398 option can be used to customize it.
399
400 The prefix will be added between the variable scope and its name, separated
401 by a '.'. It may only contain characters 'a-z', 'A-Z', '0-9', '.' and '_', as
402 for variables name. In HAProxy configuration, you need to use this prefix as
403 a part of the variables name. For example, if an agent define the variable
404 "myvar" in the "txn" scope, with the prefix "my_spoe_pfx", then you should
405 use "txn.my_spoe_pfx.myvar" name in your HAProxy configuration.
406
Etienne Carriereaec89892017-12-14 09:36:40 +0000407 By default, an agent will never set new variables at runtime: It can only set
408 new value for existing ones. If you want a different behaviour, see
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100409 force-set-var option and register-var-names directive.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200410
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100411register-var-names <var name> ...
412 Register some variable names. By default, an agent will not be allowed to set
413 new variables at runtime. This rule can be totally relaxed by setting the
414 option "force-set-var". If you know all the variables you will need, this
415 directive is a good way to register them without letting an agent doing what
416 it want. This is only required if these variables are not referenced anywhere
417 in the HAProxy configuration or the SPOE one.
418
419 Arguments:
420 <var name> is a variable name without the scope. The name may only
421 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
422
423 The prefix will be automatically added during the registration. You can have
424 many "register-var-names" lines.
425
426 See also: "option force-set-var", "option var-prefix".
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200427
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200428timeout hello <timeout>
429 Set the maximum time to wait for an agent to receive the AGENT-HELLO frame.
Christopher Fauletf7a30922016-11-10 15:04:51 +0100430 It is applied on the stream that handle the connection with the agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200431
432 Arguments :
433 <timeout> is the timeout value specified in milliseconds by default, but
434 can be in any other unit if the number is suffixed by the unit,
435 as explained at the top of this document.
436
437 This timeout is an applicative timeout. It differ from "timeout connect"
438 defined on backends.
439
440
441timeout idle <timeout>
Christopher Fauletf7a30922016-11-10 15:04:51 +0100442 Set the maximum time to wait for an agent to close an idle connection. It is
443 applied on the stream that handle the connection with the agent.
444
445 Arguments :
446 <timeout> is the timeout value specified in milliseconds by default, but
447 can be in any other unit if the number is suffixed by the unit,
448 as explained at the top of this document.
449
450
451timeout processing <timeout>
452 Set the maximum time to wait for a stream to process an event, i.e to acquire
453 a stream to talk with an agent, to encode all messages, to send the NOTIFY
Ilya Shipitsin01881082021-08-07 14:41:56 +0500454 frame, to receive the corresponding acknowledgement and to process all
Christopher Fauletf7a30922016-11-10 15:04:51 +0100455 actions. It is applied on the stream that handle the client and the server
456 sessions.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200457
458 Arguments :
459 <timeout> is the timeout value specified in milliseconds by default, but
460 can be in any other unit if the number is suffixed by the unit,
461 as explained at the top of this document.
462
463
464use-backend <backend>
465 Specify the backend to use. It must be defined.
466
467 Arguments :
468 <backend> is the name of a valid "backend" section.
469
470
4712.3. "spoe-message" section
472----------------------------
473
474To offload the stream processing, SPOE will send messages with specific
475information at a specific moment in the stream life and will wait for
476corresponding replies to know what to do.
477
478
479spoe-message <name>
480 Create a new SPOE message with the name <name>.
481
482 Arguments :
483 <name> is the name of the SPOE message.
484
485 Here you define a message that can be referenced in a "spoe-agent"
486 section. Following keywords are supported :
Christopher Faulet57583e42017-09-04 15:41:09 +0200487 - acl
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200488 - args
489 - event
490
491 See also: "spoe-agent" section.
492
493
Christopher Faulet57583e42017-09-04 15:41:09 +0200494acl <aclname> <criterion> [flags] [operator] <value> ...
Christopher Faulet57583e42017-09-04 15:41:09 +0200495 Declare or complete an access list.
496
497 See section 7 about ACL usage in the HAProxy Configuration Manual.
498
499
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200500args [name=]<sample> ...
501 Define arguments passed into the SPOE message.
502
503 Arguments :
504 <sample> is a sample expression.
505
506 When the message is processed, if a sample expression is not available, it is
507 set to NULL. Arguments are processed in their declaration order and added in
Joseph Herlant71b4b152018-11-13 16:55:16 -0800508 the message in that order. It is possible to declare named arguments.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200509
510 For example:
511 args frontend=fe_id src dst
512
513
Christopher Faulet57583e42017-09-04 15:41:09 +0200514event <name> [ { if | unless } <condition> ]
515 Set the event that triggers sending of the message. It may optionally be
516 followed by an ACL-based condition, in which case it will only be evaluated
Christopher Fauletd322e942021-12-03 10:18:09 +0100517 if the condition is true. A SPOE message can only be sent on one event. If
518 several events are defined, only the last one is considered.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200519
Christopher Faulet57583e42017-09-04 15:41:09 +0200520 ACL-based conditions are executed in the context of the stream that handle
521 the client and the server connections.
522
523 Arguments :
524 <name> is the event name.
525 <condition> is a standard ACL-based condition.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200526
527 Supported events are:
528 - on-client-session
Christopher Faulet1002aac2016-12-09 17:41:54 +0100529 - on-server-session
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200530 - on-frontend-tcp-request
531 - on-backend-tcp-request
532 - on-tcp-response
533 - on-frontend-http-request
534 - on-backend-http-request
535 - on-http-response
536
Christopher Faulet57583e42017-09-04 15:41:09 +0200537 See section "Events & Messages" for more details about supported events.
538 See section 7 about ACL usage in the HAProxy Configuration Manual.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200539
Christopher Faulet11610f32017-09-21 10:23:10 +02005402.4. "spoe-group" section
541--------------------------
542
543This section can be used to declare a group of SPOE messages. Unlike messages
544referenced in a "spoe-agent" section, messages inside a group are not sent on a
545specific event. The sending must be triggered by TCP or HTTP rules, from the
546HAProxy configuration.
547
548
549spoe-group <name>
550 Create a new SPOE group with the name <name>.
551
552 Arguments :
553 <name> is the name of the SPOE group.
554
555 Here you define a group of SPOE messages that can be referenced in a
556 "spoe-agent" section. Following keywords are supported :
557 - messages
558
559 See also: "spoe-agent" and "spoe-message" sections.
560
561
562messages <msg-name> ...
563 Declare the list of SPOE messages belonging to the group.
564
565 Arguments :
566 <msg-name> is the name of a SPOE message.
567
568 Messages declared here must be found in the same engine scope, else an error
569 is triggered during the configuration parsing. Furthermore, a message belongs
570 at most to a group. You can have many "messages" lines.
571
572 See also: "spoe-message" section.
573
574
5752.5. Example
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200576-------------
577
578Here is a simple but complete example that sends client-ip address to a ip
579reputation service. This service can set the variable "ip_score" which is an
580integer between 0 and 100, indicating its reputation (100 means totally safe
581and 0 a blacklisted IP with no doubt).
582
583 ###
584 ### HAProxy configuration
585 frontend www
586 mode http
587 bind *:80
588
589 filter spoe engine ip-reputation config spoe-ip-reputation.conf
590
591 # Reject connection if the IP reputation is under 20
592 tcp-request content reject if { var(sess.iprep.ip_score) -m int lt 20 }
593
594 default_backend http-servers
595
596 backend http-servers
597 mode http
598 server http A.B.C.D:80
599
600 backend iprep-servers
601 mode tcp
602 balance roundrobin
603
604 timeout connect 5s # greater than hello timeout
605 timeout server 3m # greater than idle timeout
606
607 server iprep1 A1.B1.C1.D1:12345
608 server iprep2 A2.B2.C2.D2:12345
609
610 ####
611 ### spoe-ip-reputation.conf
612 [ip-reputation]
613
614 spoe-agent iprep-agent
615 messages get-ip-reputation
616
617 option var-prefix iprep
618
Christopher Faulet03a34492016-11-19 16:47:56 +0100619 timeout hello 2s
620 timeout idle 2m
621 timeout processing 10ms
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200622
623 use-backend iprep-servers
624
625 spoe-message get-ip-reputation
626 args ip=src
Christopher Faulet57583e42017-09-04 15:41:09 +0200627 event on-client-session if ! { src -f /etc/haproxy/whitelist.lst }
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200628
629
6303. SPOP specification
631----------------------
632
6333.1. Data types
634----------------
635
636Here is the bytewise representation of typed data:
637
638 TYPED-DATA : <TYPE:4 bits><FLAGS:4 bits><DATA>
639
640Supported types and their representation are:
641
642 TYPE | ID | DESCRIPTION
643 -----------------------------+-----+----------------------------------
644 NULL | 0 | NULL : <0>
645 Boolean | 1 | BOOL : <1+FLAG>
646 32bits signed integer | 2 | INT32 : <2><VALUE:varint>
647 32bits unsigned integer | 3 | UINT32 : <3><VALUE:varint>
648 64bits signed integer | 4 | INT64 : <4><VALUE:varint>
649 32bits unsigned integer | 5 | UNIT64 : <5><VALUE:varint>
650 IPV4 | 6 | IPV4 : <6><STRUCT IN_ADDR:4 bytes>
651 IPV6 | 7 | IPV6 : <7><STRUCT IN_ADDR6:16 bytes>
652 String | 8 | STRING : <8><LENGTH:varint><BYTES>
653 Binary | 9 | BINARY : <9><LENGTH:varint><BYTES>
654 10 -> 15 unused/reserved | - | -
655 -----------------------------+-----+----------------------------------
656
657Variable-length integer (varint) are encoded using Peers encoding:
658
659
660 0 <= X < 240 : 1 byte (7.875 bits) [ XXXX XXXX ]
661 240 <= X < 2288 : 2 bytes (11 bits) [ 1111 XXXX ] [ 0XXX XXXX ]
662 2288 <= X < 264432 : 3 bytes (18 bits) [ 1111 XXXX ] [ 1XXX XXXX ] [ 0XXX XXXX ]
663 264432 <= X < 33818864 : 4 bytes (25 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
664 33818864 <= X < 4328786160 : 5 bytes (32 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
665 ...
666
667For booleans, the value (true or false) is the first bit in the FLAGS
668bitfield. if this bit is set to 0, then the boolean is evaluated as false,
669otherwise, the boolean is evaluated as true.
670
6713.2. Frames
672------------
673
674Exchange between HAProxy and agents are made using FRAME packets. All frames
675must be prefixed with their size encoded on 4 bytes in network byte order:
676
677 <FRAME-LENGTH:4 bytes> <FRAME>
678
679A frame always starts with its type, on one byte, followed by metadata
680containing flags, on 4 bytes and a two variable-length integer representing the
681stream identifier and the frame identifier inside the stream:
682
683 FRAME : <FRAME-TYPE:1 byte> <METADATA> <FRAME-PAYLOAD>
684 METADATA : <FLAGS:4 bytes> <STREAM-ID:varint> <FRAME-ID:varint>
685
686Then comes the frame payload. Depending on the frame type, the payload can be
687of three types: a simple key/value list, a list of messages or a list of
688actions.
689
690 FRAME-PAYLOAD : <LIST-OF-MESSAGES> | <LIST-OF-ACTIONS> | <KV-LIST>
691
692 LIST-OF-MESSAGES : [ <MESSAGE-NAME> <NB-ARGS:1 byte> <KV-LIST> ... ]
693 MESSAGE-NAME : <STRING>
694
695 LIST-OF-ACTIONS : [ <ACTION-TYPE:1 byte> <NB-ARGS:1 byte> <ACTION-ARGS> ... ]
696 ACTION-ARGS : [ <TYPED-DATA>... ]
697
698 KV-LIST : [ <KV-NAME> <KV-VALUE> ... ]
699 KV-NAME : <STRING>
700 KV-VALUE : <TYPED-DATA>
701
Thierry FOURNIERc4dcaff2018-05-18 12:25:39 +0200702 FLAGS :
703
704 Flags are a 32 bits field. They are encoded on 4 bytes in network byte
705 order, where the bit 0 is the LSB.
706
707 0 1 2-31
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100708 +---+---+----------+
709 | | A | |
710 | F | B | |
711 | I | O | RESERVED |
712 | N | R | |
713 | | T | |
714 +---+---+----------+
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200715
716 FIN: Indicates that this is the final payload fragment. The first fragment
717 may also be the final fragment.
718
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100719 ABORT: Indicates that the processing of the current frame must be
720 cancelled. This bit should be set on frames with a fragmented
721 payload. It can be ignore for frames with an unfragemnted
722 payload. When it is set, the FIN bit must also be set.
723
724
Joseph Herlant71b4b152018-11-13 16:55:16 -0800725Frames cannot exceed a maximum size negotiated between HAProxy and agents
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200726during the HELLO handshake. Most of time, payload will be small enough to send
727it in one frame. But when supported by the peer, it will be possible to
728fragment huge payload on many frames. This ability is announced during the
729HELLO handshake and it can be asynmetric (supported by agents but not by
730HAProxy or the opposite). The following rules apply to fragmentation:
731
732 * An unfragemnted payload consists of a single frame with the FIN bit set.
733
734 * A fragemented payload consists of several frames with the FIN bit clear and
735 terminated by a single frame with the FIN bit set. All these frames must
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100736 share the same STREAM-ID and FRAME-ID. The first frame must set the right
737 FRAME-TYPE (e.g, NOTIFY). The following frames must have an unset type (0).
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200738
739Beside the support of fragmented payload by a peer, some payload must not be
740fragmented. See below for details.
741
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100742IMPORTANT : The maximum size supported by peers for a frame must be greater
743than or equal to 256 bytes.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200744
7453.2.1. Frame capabilities
746--------------------------
747
748Here are the list of official capabilities that HAProxy and agents can support:
749
Christopher Fauleta1cda022016-12-21 08:58:06 +0100750 * fragmentation: This is the ability for a peer to support fragmented
751 payload in received frames. This is an asymmectical
752 capability, it only concerns the peer that announces
753 it. This is the responsibility to the other peer to use it
754 or not.
755
756 * pipelining: This is the ability for a peer to decouple NOTIFY and ACK
757 frames. This is a symmectical capability. To be used, it must
Willy Tarreau714f3452021-05-09 06:47:26 +0200758 be supported by HAProxy and agents. Unlike HTTP pipelining, the
Christopher Fauleta1cda022016-12-21 08:58:06 +0100759 ACK frames can be send in any order, but always on the same TCP
760 connection used for the corresponding NOTIFY frame.
761
762 * async: This ability is similar to the pipelining, but here any TCP
763 connection established between HAProxy and the agent can be used to
764 send ACK frames. if an agent accepts connections from multiple
765 HAProxy, it can use the "engine-id" value to group TCP
766 connections. See details about HAPROXY-HELLO frame.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200767
768Unsupported or unknown capabilities are silently ignored, when possible.
769
Christopher Faulet9536ad72021-03-02 10:05:03 +0100770NOTE: HAProxy does not support the fragmentation for now. This means it is not
771 able to handle fragmented frames. However, if an agent announces the
772 fragmentation support, HAProxy may choose to send fragemented frames.
773
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02007743.2.2. Frame types overview
775----------------------------
776
777Here are types of frame supported by SPOE. Frames sent by HAProxy come first,
778then frames sent by agents :
779
780 TYPE | ID | DESCRIPTION
781 -----------------------------+-----+-------------------------------------
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100782 UNSET | 0 | Used for all frames but the first when a
783 | | payload is fragmented.
784 -----------------------------+-----+-------------------------------------
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200785 HAPROXY-HELLO | 1 | Sent by HAProxy when it opens a
786 | | connection on an agent.
787 | |
788 HAPROXY-DISCONNECT | 2 | Sent by HAProxy when it want to close
789 | | the connection or in reply to an
790 | | AGENT-DISCONNECT frame
791 | |
792 NOTIFY | 3 | Sent by HAProxy to pass information
793 | | to an agent
794 -----------------------------+-----+-------------------------------------
795 AGENT-HELLO | 101 | Reply to a HAPROXY-HELLO frame, when
796 | | the connection is established
797 | |
798 AGENT-DISCONNECT | 102 | Sent by an agent just before closing
799 | | the connection
800 | |
801 ACK | 103 | Sent to acknowledge a NOTIFY frame
802 -----------------------------+-----+-------------------------------------
803
804Unknown frames may be silently skipped.
805
8063.2.3. Workflow
807----------------
808
809 * Successful HELLO handshake:
810
811 HAPROXY AGENT SRV
812 | HAPROXY-HELLO |
Christopher Fauletba7bc162016-11-07 21:07:38 +0100813 | (healthcheck: false) |
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200814 | --------------------------> |
815 | |
816 | AGENT-HELLO |
817 | <-------------------------- |
818 | |
819
Christopher Fauletba7bc162016-11-07 21:07:38 +0100820 * Successful HELLO healthcheck:
821
822 HAPROXY AGENT SRV
823 | HAPROXY-HELLO |
824 | (healthcheck: true) |
825 | --------------------------> |
826 | |
827 | AGENT-HELLO + close() |
828 | <-------------------------- |
829 | |
830
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200831
832 * Error encountered by agent during the HELLO handshake:
833
834 HAPROXY AGENT SRV
835 | HAPROXY-HELLO |
836 | --------------------------> |
837 | |
838 | DISCONNECT + close() |
839 | <-------------------------- |
840 | |
841
842 * Error encountered by HAProxy during the HELLO handshake:
843
844 HAPROXY AGENT SRV
845 | HAPROXY-HELLO |
846 | --------------------------> |
847 | |
848 | AGENT-HELLO |
849 | <-------------------------- |
850 | |
851 | DISCONNECT |
852 | --------------------------> |
853 | |
854 | DISCONNECT + close() |
855 | <-------------------------- |
856 | |
857
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100858 * Notify / Ack exchange (unfragmented payload):
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200859
860 HAPROXY AGENT SRV
861 | NOTIFY |
862 | --------------------------> |
863 | |
864 | ACK |
865 | <-------------------------- |
866 | |
867
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100868 * Notify / Ack exchange (fragmented payload):
869
870 HAPROXY AGENT SRV
871 | NOTIFY (frag 1) |
872 | --------------------------> |
873 | |
874 | UNSET (frag 2) |
875 | --------------------------> |
876 | ... |
877 | UNSET (frag N) |
878 | --------------------------> |
879 | |
880 | ACK |
881 | <-------------------------- |
882 | |
883
884 * Aborted fragmentation of a NOTIFY frame:
885
886 HAPROXY AGENT SRV
887 | ... |
888 | UNSET (frag X) |
889 | --------------------------> |
890 | |
891 | ACK/ABORT |
892 | <-------------------------- |
893 | |
894 | UNSET (frag X+1) |
895 | -----------X |
896 | |
897 | |
898
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200899 * Connection closed by haproxy:
900
901 HAPROXY AGENT SRV
902 | DISCONNECT |
903 | --------------------------> |
904 | |
905 | DISCONNECT + close() |
906 | <-------------------------- |
907 | |
908
909 * Connection closed by agent:
910
911 HAPROXY AGENT SRV
912 | DISCONNECT + close() |
913 | <-------------------------- |
914 | |
915
9163.2.4. Frame: HAPROXY-HELLO
917----------------------------
918
919This frame is the first one exchanged between HAProxy and an agent, when the
920connection is established. The payload of this frame is a KV-LIST. It cannot be
921fragmented. STREAM-ID and FRAME-ID are must be set 0.
922
923Following items are mandatory in the KV-LIST:
924
925 * "supported-versions" <STRING>
926
927 Last SPOP major versions supported by HAProxy. It is a comma-separated list
928 of versions, following the format "Major.Minor". Spaces must be ignored, if
929 any. When a major version is announced by HAProxy, it means it also support
930 all previous minor versions.
931
932 Example: "2.0, 1.5" means HAProxy supports SPOP 2.0 and 1.0 to 1.5
933
934 * "max-frame-size" <UINT32>
935
936 This is the maximum size allowed for a frame. The HAPROXY-HELLO frame must
937 be lower or equal to this value.
938
939 * "capabilities" <STRING>
940
941 This a comma-separated list of capabilities supported by HAProxy. Spaces
942 must be ignored, if any.
943
Christopher Fauletba7bc162016-11-07 21:07:38 +0100944Following optional items can be added in the KV-LIST:
945
946 * "healthcheck" <BOOLEAN>
947
948 If this item is set to TRUE, then the HAPROXY-HELLO frame is sent during a
949 SPOE health check. When set to FALSE, this item can be ignored.
950
Christopher Fauleta1cda022016-12-21 08:58:06 +0100951 * "engine-id" <STRING>
952
953 This is a uniq string that identify a SPOE engine.
954
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200955To finish the HELLO handshake, the agent must return an AGENT-HELLO frame with
956its supported SPOP version, the lower value between its maximum size allowed
957for a frame and the HAProxy one and capabilities it supports. If an error
958occurs or if an incompatibility is detected with the agent configuration, an
959AGENT-DISCONNECT frame must be returned.
960
9613.2.5. Frame: AGENT-HELLO
962--------------------------
963
964This frame is sent in reply to a HAPROXY-HELLO frame to finish a HELLO
965handshake. As for HAPROXY-HELLO frame, STREAM-ID and FRAME-ID are also set
9660. The payload of this frame is a KV-LIST and it cannot be fragmented.
967
968Following items are mandatory in the KV-LIST:
969
970 * "version" <STRING>
971
972 This is the SPOP version the agent supports. It must follow the format
973 "Major.Minor" and it must be lower or equal than one of major versions
974 announced by HAProxy.
975
976 * "max-frame-size" <UINT32>
977
978 This is the maximum size allowed for a frame. It must be lower or equal to
979 the value in the HAPROXY-HELLO frame. This value will be used for all
980 subsequent frames.
981
982 * "capabilities" <STRING>
983
984 This a comma-separated list of capabilities supported by agent. Spaces must
985 be ignored, if any.
986
987At this time, if everything is ok for HAProxy (supported version and valid
988max-frame-size value), the HELLO handshake is successfully completed. Else,
989HAProxy sends a HAPROXY-DISCONNECT frame with the corresponding error.
990
Christopher Fauletba7bc162016-11-07 21:07:38 +0100991If "healthcheck" item was set to TRUE in the HAPROXY-HELLO frame, the agent can
992safely close the connection without DISCONNECT frame. In all cases, HAProxy
Ilya Shipitsin11057a32020-06-21 21:18:27 +0500993will close the connection at the end of the health check.
Christopher Fauletba7bc162016-11-07 21:07:38 +0100994
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02009953.2.6. Frame: NOTIFY
996---------------------
997
998Information are sent to the agents inside NOTIFY frames. These frames are
999attached to a stream, so STREAM-ID and FRAME-ID must be set. The payload of
1000NOTIFY frames is a LIST-OF-MESSAGES and, if supported by agents, it can be
1001fragmented.
1002
1003NOTIFY frames must be acknowledge by agents sending an ACK frame, repeating
1004right STREAM-ID and FRAME-ID.
1005
10063.2.7. Frame: ACK
1007------------------
1008
1009ACK frames must be sent by agents to reply to NOTIFY frames. STREAM-ID and
1010FRAME-ID found in a NOTIFY frame must be reuse in the corresponding ACK
1011frame. The payload of ACK frames is a LIST-OF-ACTIONS and, if supported by
1012HAProxy, it can be fragmented.
1013
10143.2.8. Frame: HAPROXY-DISCONNECT
1015---------------------------------
1016
1017If an error occurs, at anytime, from the HAProxy side, a HAPROXY-DISCONNECT
1018frame is sent with information describing the error. HAProxy will wait an
1019AGENT-DISCONNECT frame in reply. All other frames will be ignored. The agent
1020must then close the socket.
1021
1022The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
1023FRAME-ID are must be set 0.
1024
1025Following items are mandatory in the KV-LIST:
1026
1027 * "status-code" <UINT32>
1028
1029 This is the code corresponding to the error.
1030
1031 * "message" <STRING>
1032
1033 This is a textual message describing the error.
1034
1035For more information about known errors, see section "Errors & timeouts"
1036
10373.2.9. Frame: AGENT-DISCONNECT
1038-------------------------------
1039
1040If an error occurs, at anytime, from the agent size, a AGENT-DISCONNECT frame
Michael Prokop4438c602019-05-24 10:25:45 +02001041is sent, with information describing the error. such frame is also sent in reply
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001042to a HAPROXY-DISCONNECT. The agent must close the socket just after sending
1043this frame.
1044
1045The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
1046FRAME-ID are must be set 0.
1047
1048Following items are mandatory in the KV-LIST:
1049
1050 * "status-code" <UINT32>
1051
1052 This is the code corresponding to the error.
1053
1054 * "message" <STRING>
1055
1056 This is a textual message describing the error.
1057
1058For more information about known errors, see section "Errors & timeouts"
1059
10603.3. Events & Messages
1061-----------------------
1062
1063Information about streams are sent in NOTIFY frames. You can specify which kind
1064of information to send by defining "spoe-message" sections in your SPOE
1065configuration file. for each "spoe-message" there will be a message in a NOTIFY
1066frame when the right event is triggered.
1067
1068A NOTIFY frame is sent for an specific event when there is at least one
1069"spoe-message" attached to this event. All messages for an event will be added
1070in the same NOTIFY frame.
1071
1072Here is the list of supported events:
1073
1074 * on-client-session is triggered when a new client session is created.
1075 This event is only available for SPOE filters
1076 declared in a frontend or a listen section.
1077
1078 * on-frontend-tcp-request is triggered just before the evaluation of
1079 "tcp-request content" rules on the frontend side.
1080 This event is only available for SPOE filters
1081 declared in a frontend or a listen section.
1082
1083 * on-backend-tcp-request is triggered just before the evaluation of
1084 "tcp-request content" rules on the backend side.
1085 This event is skipped for SPOE filters declared
1086 in a listen section.
1087
1088 * on-frontend-http-request is triggered just before the evaluation of
1089 "http-request" rules on the frontend side. This
1090 event is only available for SPOE filters declared
1091 in a frontend or a listen section.
1092
1093 * on-backend-http-request is triggered just before the evaluation of
1094 "http-request" rules on the backend side. This
1095 event is skipped for SPOE filters declared in a
1096 listen section.
1097
1098 * on-server-session is triggered when the session with the server is
1099 established.
1100
1101 * on-tcp-response is triggered just before the evaluation of
1102 "tcp-response content" rules.
1103
1104 * on-http-response is triggered just before the evaluation of
1105 "http-response" rules.
1106
1107
1108The stream processing will loop on these events, when triggered, waiting the
1109agent reply.
1110
11113.4. Actions
1112-------------
1113
1114An agent must acknowledge each NOTIFY frame by sending the corresponding ACK
1115frame. Actions can be added in these frames to dynamically take action on the
1116processing of a stream.
1117
1118Here is the list of supported actions:
1119
1120 * set-var set the value for an existing variable. 3 arguments must be
1121 attached to this action: the variable scope (proc, sess, txn,
Kevin Zhu730323e2018-06-01 05:38:00 +02001122 req or res), the variable name (a string) and its value.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001123
1124 ACTION-SET-VAR : <SET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME><VAR-VALUE>
1125
1126 SET-VAR : <1>
1127 NB-ARGS : <3>
1128 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
1129 VAR-NAME : <STRING>
1130 VAR-VALUE : <TYPED-DATA>
1131
1132 PROCESS : <0>
1133 SESSION : <1>
1134 TRANSACTION : <2>
1135 REQUEST : <3>
Christopher Fauleta1cda022016-12-21 08:58:06 +01001136 RESPONSE : <4>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001137
1138 * unset-var unset the value for an existing variable. 2 arguments must be
1139 attached to this action: the variable scope (proc, sess, txn,
Kevin Zhu730323e2018-06-01 05:38:00 +02001140 req or res) and the variable name (a string).
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001141
Christopher Faulet1002aac2016-12-09 17:41:54 +01001142 ACTION-UNSET-VAR : <UNSET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001143
Christopher Faulet1002aac2016-12-09 17:41:54 +01001144 UNSET-VAR : <2>
1145 NB-ARGS : <2>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001146 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
1147 VAR-NAME : <STRING>
1148
1149 PROCESS : <0>
1150 SESSION : <1>
1151 TRANSACTION : <2>
1152 REQUEST : <3>
Christopher Fauleta1cda022016-12-21 08:58:06 +01001153 RESPONSE : <4>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001154
1155
1156NOTE: Name of the variables will be automatically prefixed by HAProxy to avoid
1157 name clashes with other variables used in HAProxy. Moreover, unknown
1158 variable will be silently ignored.
1159
Christopher Fauletd1307ce2017-02-27 21:59:39 +010011603.5. Errors & timeouts
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001161----------------------
1162
1163Here is the list of all known errors:
1164
1165 STATUS CODE | DESCRIPTION
1166 ----------------+--------------------------------------------------------
1167 0 | normal (no error occurred)
1168 1 | I/O error
1169 2 | A timeout occurred
1170 3 | frame is too big
1171 4 | invalid frame received
1172 5 | version value not found
1173 6 | max-frame-size value not found
1174 7 | capabilities value not found
1175 8 | unsupported version
1176 9 | max-frame-size too big or too small
Christopher Fauletd1307ce2017-02-27 21:59:39 +01001177 10 | payload fragmentation is not supported
1178 11 | invalid interlaced frames
1179 12 | frame-id not found (it does not match any referenced frame)
1180 13 | resource allocation error
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001181 99 | an unknown error occurrde
1182 ----------------+--------------------------------------------------------
1183
1184An agent can define its own errors using a not yet assigned status code.
1185
Christopher Fauletea62c2a2016-11-14 10:54:21 +01001186IMPORTANT NOTE: By default, for a specific stream, when an abnormal/unexpected
1187 error occurs, the SPOE is disabled for all the transaction. So
1188 if you have several events configured, such error on an event
Ilya Shipitsin11057a32020-06-21 21:18:27 +05001189 will disabled all following. For TCP streams, this will
Christopher Fauletea62c2a2016-11-14 10:54:21 +01001190 disable the SPOE for the whole session. For HTTP streams, this
1191 will disable it for the transaction (request and response).
1192 See 'option continue-on-error' to bypass this limitation.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001193
Joseph Herlant71b4b152018-11-13 16:55:16 -08001194To avoid a stream to wait undefinetly, you must carefully choose the
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001195acknowledgement timeout. In most of cases, it will be quiet low. But it depends
1196on the responsivness of your service.
1197
1198You must also choose idle timeout carefully. Because connection with your
1199service depends on the backend configuration used by the SPOA, it is important
1200to use a lower value for idle timeout than the server timeout. Else the
1201connection will be closed by HAProxy. The same is true for hello timeout. You
1202should choose a lower value than the connect timeout.
1203
Christopher Fauletb2dd1e02018-03-22 09:07:41 +010012044. Logging
1205-----------
1206
1207Activity of an SPOE is logged using HAProxy's logger. The messages are logged
1208in the context of the streams that handle the client and the server
1209connections. A message is emitted for each event or group handled by an
1210SPOE. Depending on the status code, the log level will be different. In the
1211normal case, when no error occurred, the message is logged with the level
1212LOG_NOTICE. Otherwise, the message is logged with the level LOG_WARNING.
1213
Christopher Faulet3b8e3492018-03-26 17:20:58 +02001214The messages are logged using the agent's logger, if defined, and use the
1215following format:
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001216
Christopher Faulet6e0d5e72018-04-26 14:25:43 +02001217 SPOE: [AGENT] <TYPE:NAME> sid=STREAM-ID st=STATUS-CODE reqT/qT/wT/resT/pT \
Christopher Fauletcaf2fec2018-04-04 10:25:50 +02001218 <idles>/<applets> <nb_sending>/<nb_waiting> <nb_error>/<nb_processed>
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001219
1220 AGENT is the agent name
1221 TYPE is EVENT of GROUP
1222 NAME is the event or the group name
1223 STREAM-ID is an integer, the unique id of the stream
1224 STATUS_CODE is the processing's status code
1225 reqT/qT/wT/resT/pT are the following time events:
1226
1227 * reqT : the encoding time. It includes ACLs processing, if any. For
1228 fragmented frames, it is the sum of all fragments.
1229 * qT : the delay before the request gets out the sending queue. For
1230 fragmented frames, it is the sum of all fragments.
Joseph Herlant71b4b152018-11-13 16:55:16 -08001231 * wT : the delay before the response is received. No fragmentation
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001232 supported here.
1233 * resT : the delay to process the response. No fragmentation supported
Christopher Faulet36bda1c2018-03-22 09:08:20 +01001234 here.
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001235 * pT : the delay to process the event or the group. From the stream
Christopher Faulet36bda1c2018-03-22 09:08:20 +01001236 point of view, it is the latency added by the SPOE processing.
1237 It is more or less the sum of values above.
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001238
Christopher Fauletcaf2fec2018-04-04 10:25:50 +02001239 <idle> is the numbers of idle SPOE applets
1240 <applets> is the numbers of SPOE applets
1241 <nb_sending> is the numbers of streams waiting to send data
1242 <nb_waiting> is the numbers of streams waiting for a ack
1243 <nb_error> is the numbers of processing errors
1244 <nb_processed> is the numbers of events/groups processed
1245
1246
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001247For all these time events, -1 means the processing was interrupted before the
1248end. So -1 for the queue time means the request was never dequeued. For
1249fragmented frames it is harder to know when the interruption happened.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001250
1251/*
1252 * Local variables:
1253 * fill-column: 79
1254 * End:
1255 */