blob: a08f47138160d590e6d53d48f3518c2e447d05c5 [file] [log] [blame]
Miroslav Zagorac70230c62020-12-09 16:54:31 +01001 -----------------------------------------
2 The HAProxy OpenTracing filter (OT)
3 Version 1.0
4 ( Last update: 2020-12-10 )
5 -----------------------------------------
6 Author : Miroslav Zagorac
7 Contact : mzagorac at haproxy dot com
8
9
10SUMMARY
11--------
12
13 0. Terms
14 1. Introduction
15 2. Build instructions
16 3. Basic concepts in OpenTracing
17 4. OT configuration
18 4.1. OT scope
19 4.2. "ot-tracer" section
20 4.3. "ot-scope" section
21 4.4. "ot-group" section
22 5. Examples
23 5.1 Benchmarking results
24 6. OT CLI
25 7. Known bugs and limitations
26
27
280. Terms
29---------
30
31* OT: The HAProxy OpenTracing filter
32
33 OT is the HAProxy filter that allows you to send data to distributed
34 tracing systems via the OpenTracing API.
35
36
371. Introduction
38----------------
39
40Nowadays there is a growing need to divide a process into microservices and
41there is a problem of monitoring the work of the same process. One way to
42solve this problem is to use distributed tracing service in a central location,
43the so-called tracer.
44
45OT is a feature introduced in HAProxy 2.4. This filter enables communication
46via the OpenTracing API with OpenTracing compatible servers (tracers).
47Currently, tracers that support this API include Datadog, Jaeger, LightStep
48and Zipkin.
49
50The OT filter was primarily tested with the Jaeger tracer, while configurations
51for both Datadog and Zipkin tracers were also set in the test directory.
52
53The OT filter is a standard HAProxy filter, so what applies to others also
54applies to this one (of course, by that I mean what is described in the
55documentation, more precisely in the doc/internals/filters.txt file).
56
57The OT filter activation is done explicitly by specifying it in the HAProxy
58configuration. If this is not done, the OT filter in no way participates
59in the work of HAProxy.
60
61As for the impact on HAProxy speed, this is documented with several tests
62located in the test directory, and the result is found in the README-speed-*
63files. In short, the speed of operation depends on the way it is used and
64the complexity of the configuration, from an almost immeasurable impact to
65a significant deceleration (5x and more). I think that in some normal use
66the speed of HAProxy with the filter on will be quite satisfactory with a
67slowdown of less than 4% (provided that no more than 10% of requests are
68sent to the tracer, which is determined by the keyword 'rate-limit').
69
70The OT filter allows intensive use of ACLs, which can be defined anywhere in
71the configuration. Thus, it is possible to use the filter only for those
72connections that are of interest to us.
73
74
752. Build instructions
76----------------------
77
78OT is the HAProxy filter and as such is compiled together with HAProxy.
79
80To communicate with some OpenTracing compatible tracer, the OT filter uses the
81OpenTracing C Wrapper library (which again uses the OpenTracing CPP library).
82This means that we must have both libraries installed on the system on which
83we want to compile or use HAProxy.
84
85Instructions for compiling and installing both required libraries can be
86found at https://github.com/haproxytech/opentracing-c-wrapper .
87
88Also, to use the OT filter when running HAProxy we need to have an OpenTracing
89plugin for the tracer we want to use. We will return to this later, in
90section 5.
91
92The OT filter can be more easily compiled using the pkg-config tool, if we
93have the OpenTracing C Wrapper library installed so that it contains pkg-config
94files (which have the .pc extension). If the pkg-config tool cannot be used,
95then the path to the directory where the include files and libraries are
96located can be explicitly specified.
97
98Below are examples of the two ways to compile HAProxy with the OT filter, the
99first using the pkg-congfig tool and the second explicitly specifying the path
100to the OpenTracing C Wrapper include and library.
101
102Note: prompt '%' indicates that the command is executed under a unprivileged
103 user, while prompt '#' indicates that the command is executed under the
104 root user.
105
106Example of compiling HAProxy using the pkg-congfig tool (assuming the
107OpenTracing C Wrapper library is installed in the /opt directory):
108
109 % PKG_CONFIG_PATH=/opt/lib/pkgconfig make USE_OT=1 TARGET=linux-glibc
110
111The OT filter can also be compiled in debug mode as follows:
112
113 % PKG_CONFIG_PATH=/opt/lib/pkgconfig make USE_OT=1 OT_DEBUG=1 TARGET=linux-glibc
114
115HAProxy compilation example explicitly specifying path to the OpenTracing C
116Wrapper include and library:
117
118 % make USE_OT=1 OT_INC=/opt/include OT_LIB=/opt/lib TARGET=linux-glibc
119
120In case we want to use debug mode, then it looks like this:
121
122 % make USE_OT=1 OT_DEBUG=1 OT_INC=/opt/include OT_LIB=/opt/lib TARGET=linux-glibc
123
124If the library we want to use is not installed on a unix system, then a locally
125installed library can be used (say, which is compiled and installed in the user
126home directory). In this case instead of /opt/include and /opt/lib the
127equivalent paths to the local installation should be specified. Of course,
128in that case the pkg-config tool can also be used if we have a complete
129installation (with .pc files).
130
131last but not least, if the pkg-config tool is not used when compiling, then
132HAProxy executable may not be able to find the OpenTracing C Wrapper library
133at startup. This can be solved in several ways, for example using the
134LD_LIBRARY_PATH environment variable which should be set to the path where the
135library is located before starting the HAProxy.
136
137 % LD_LIBRARY_PATH=/opt/lib /path-to/haproxy ...
138
139Another way is to add RUNPATH to HAProxy executable that contains the path to
140the library in question.
141
142 % make USE_OT=1 OT_RUNPATH=1 OT_INC=/opt/include OT_LIB=/opt/lib TARGET=linux-glibc
143
144After HAProxy is compiled, we can check if the OT filter is enabled:
145
146 % ./haproxy -vv | grep opentracing
147 --- command output ----------
148 [ OT] opentracing
149 --- command output ----------
150
151
1523. Basic concepts in OpenTracing
153---------------------------------
154
155Basic concepts of OpenTracing can be read on the OpenTracing documentation
156website https://opentracing.io/docs/overview/.
157
158Here we will list only the most important elements of distributed tracing and
159these are 'trace', 'span' and 'span context'. Trace is a description of the
160complete transaction we want to record in the tracing system. A span is an
161operation that represents a unit of work that is recorded in a tracing system.
162Span context is a group of information related to a particular span that is
163passed on to the system (from service to service). Using this context, we can
164add new spans to already open trace (or supplement data in already open spans).
165
166An individual span may contain one or more tags, logs and baggage items.
167The tag is a key-value element that is valid for the entire span. Log is a
168key-value element that allows you to write some data at a certain time, it
169can be used for debugging. A baggage item is a key-value data pair that can
170be used for the duration of an entire trace, from the moment it is added to
171the span.
172
173
1744. OT configuration
175--------------------
176
177In order for the OT filter to be used, it must be included in the HAProxy
178configuration, in the proxy section (frontend / listen / backend):
179
180 frontend ot-test
181 ...
182 filter opentracing [id <id>] config <file>
183 ...
184
185If no filter id is specified, 'ot-filter' is used as default. The 'config'
186parameter must be specified and it contains the path of the file used to
187configure the OT filter.
188
189
1904.1 OT scope
191-------------
192
193If the filter id is defined for the OT filter, then the OT scope with
194the same name should be defined in the configuration file. In the same
195configuration file we can have several defined OT scopes.
196
197Each OT scope must have a defined (only one) "ot-tracer" section that is
198used to configure the operation of the OT filter and define the used groups
199and scopes.
200
201OT scope starts with the id of the filter specified in square brackets and
202ends with the end of the file or when a new OT scope is defined.
203
204For example, this defines two OT scopes in the same configuration file:
205 [my-first-ot-filter]
206 ot-tracer tracer1
207 ...
208 ot-group group1
209 ...
210 ot-scope scope1
211 ...
212
213 [my-second-ot-filter]
214 ...
215
216
2174.2. "ot-tracer" section
218-------------------------
219
220Only one "ot-tracer" section must be defined for each OT scope.
221
222There are several keywords that must be defined for the OT filter to work.
223These are 'config' which defines the configuration file for the OpenTracing
224API, and 'plugin' which defines the OpenTracing plugin used.
225
226Through optional keywords can be defined ACLs, logging, rate limit, and groups
227and scopes that define the tracing model.
228
229
230ot-tracer <name>
231 A new OT with the name <name> is created.
232
233 Arguments :
234 name - the name of the tracer section
235
236
237 The following keywords are supported in this section:
238 - mandatory keywords:
239 - config
240 - plugin
241
242 - optional keywords:
243 - acl
244 - debug-level
245 - groups
246 - [no] log
247 - [no] option disabled
248 - [no] option dontlog-normal
249 - [no] option hard-errors
250 - rate-limit
251 - scopes
252
253
254acl <aclname> <criterion> [flags] [operator] <value> ...
255 Declare or complete an access list.
256
257 To configure and use the ACL, see section 7 of the HAProxy Configuration
258 Manual.
259
260
261config <file>
262 'config' is one of the two mandatory keywords associated with the OT tracer
263 configuration. This keyword sets the path of the configuration file for the
264 OpenTracing tracer plugin. To set the contents of this configuration file,
265 it is best to look at the documentation related to the OpenTracing tracer we
266 want to use.
267
268 Arguments :
269 file - the path of the configuration file
270
271
272debug-level <value>
273 This keyword sets the value of the debug level related to the display of
274 debug messages in the OT filter. The 'debug-level' value is binary, ie
275 a single value bit enables or disables the display of the corresponding
276 debug message that uses that bit. The default value is set via the
277 FLT_OT_DEBUG_LEVEL macro in the include/config.h file. Debug level value
278 is used only if the OT filter is compiled with the debug mode enabled,
279 otherwise it is ignored.
280
281 Arguments :
282 value - binary value ranging from 0 to 255 (8 bits)
283
284
285groups <name> ...
286 A list of "ot-group" groups used for the currently defined tracer is declared.
287 Several groups can be specified in one line.
288
289 Arguments :
290 name - the name of the OT group
291
292
293log global
294log <addr> [len <len>] [format <fmt>] <facility> [<level> [<minlevel>]]
295no log
296 Enable per-instance logging of events and traffic.
297
298 To configure and use the logging system, see section 4.2 of the HAProxy
299 Configuration Manual.
300
301
302option disabled
303no option disabled
304 Keyword which turns the operation of the OT filter on or off. By default
305 the filter is on.
306
307
308option dontlog-normal
309no option dontlog-normal
310 Enable or disable logging of normal, successful processing. By default,
311 this option is disabled. For this option to be considered, logging must
312 be turned on.
313
314 See also: 'log' keyword description.
315
316
317option hard-errors
318no option hard-errors
319 During the operation of the filter, some errors may occur, caused by
320 incorrect configuration of the tracer or some error related to the operation
321 of HAProxy. By default, such an error will not interrupt the filter
322 operation for the stream in which the error occurred. If the 'hard-error'
323 option is enabled, the operation error prohibits all further processing of
324 events and groups in the stream in which the error occurred.
325
326
327plugin <file>
328 'plugin' is one of the two mandatory keywords associated with the OT tracer
329 configuration. This keyword sets the path of the OpenTracing tracer plugin.
330
331 Arguments :
332 file - the name of the plugin used
333
334
335rate-limit <value>
336 This option allows limiting the use of the OT filter, ie it can be influenced
337 whether the OT filter is activated for a stream or not. Determining whether
338 or not a filter is activated depends on the value of this option that is
339 compared to a randomly selected value when attaching the filter to the stream.
340 By default, the value of this option is set to 100.0, ie the OT filter is
341 activated for each stream.
342
343 Arguments :
344 value - floating point value ranging from 0.0 to 100.0
345
346
347scopes <name> ...
348 This keyword declares a list of "ot-scope" definitions used for the currently
349 defined tracer. Multiple scopes can be specified in the same line.
350
351 Arguments :
352 name - the name of the OT scope
353
354
3554.3. "ot-scope" section
356------------------------
357
358Stream processing begins with filter attachment, then continues with the
359processing of a number of defined events and groups, and ends with filter
360detachment. The "ot-scope" section is used to define actions related to
361individual events. However, this section may be part of a group, so the
362event does not have to be part of the definition.
363
364
365ot-scope <name>
366 Creates a new OT scope definition named <name>.
367
368 Arguments :
369 name - the name of the OT scope
370
371
372 The following keywords are supported in this section:
373 - acl
374 - baggage
375 - event
376 - extract
377 - finish
378 - inject
379 - log
380 - span
381 - tag
382
383
384acl <aclname> <criterion> [flags] [operator] <value> ...
385 Declare or complete an access list.
386
387 To configure and use the ACL, see section 7 of the HAProxy Configuration
388 Manual.
389
390
391baggage <name> <sample> ...
392 Baggage items allow the propagation of data between spans, ie allow the
393 assignment of metadata that is propagated to future children spans.
394 This data is formatted in the style of key-value pairs and is part of
395 the context that can be transferred between processes that are part of
396 a server architecture.
397
398 This kewyord allows setting the baggage for the currently active span. The
399 data type is always a string, ie any sample type is converted to a string.
400 The exception is a binary value that is not supported by the OT filter.
401
402 See the 'tag' keyword description for the data type conversion table.
403
404 Arguments :
405 name - key part of a data pair
406 sample - sample expression (value part of a data pair), at least one
407 sample must be present
408
409
410event <name> [{ if | unless } <condition>]
411 Set the event that triggers the 'ot-scope' to which it is assigned.
412 Optionally, it can be followed by an ACL-based condition, in which case it
413 will only be evaluated if the condition is true.
414
415 ACL-based conditions are executed in the context of a stream that processes
416 the client and server connections. To configure and use the ACL, see
417 section 7 of the HAProxy Configuration Manual.
418
419 Arguments :
420 name - the event name
421 condition - a standard ACL-based condition
422
423 Supported events are (the table gives the names of the events in the OT
424 filter and the corresponding equivalent in the SPOE filter):
425
426 -------------------------------------|------------------------------
427 the OT filter | the SPOE filter
428 -------------------------------------|------------------------------
429 on-client-session-start | on-client-session
430 on-frontend-tcp-request | on-frontend-tcp-request
431 on-http-wait-request | -
432 on-http-body-request | -
433 on-frontend-http-request | on-frontend-http-request
434 on-switching-rules-request | -
435 on-backend-tcp-request | on-backend-tcp-request
436 on-backend-http-request | on-backend-http-request
437 on-process-server-rules-request | -
438 on-http-process-request | -
439 on-tcp-rdp-cookie-request | -
440 on-process-sticking-rules-request | -
441 on-client-session-end | -
442 on-server-unavailable | -
443 -------------------------------------|------------------------------
444 on-server-session-start | on-server-session
445 on-tcp-response | on-tcp-response
446 on-http-wait-response | -
447 on-process-store-rules-response | -
448 on-http-response | on-http-response
449 on-server-session-end | -
450 -------------------------------------|------------------------------
451
452
453extract <name-prefix> [use-vars | use-headers]
454 For a more detailed description of the propagation process of the span
455 context, see the description of the keyword 'inject'. Only the process
456 of extracting data from the carrier is described here.
457
458 Arguments :
459 name-prefix - data name prefix (ie key element prefix)
460 use-vars - data is extracted from HAProxy variables
461 use-headers - data is extracted from the HTTP header
462
463
464 Below is an example of using HAProxy variables to transfer span context data:
465
466 --- test/ctx/ot.cfg --------------------------------------------------------
467 ...
468 ot-scope client_session_start_2
469 extract "ot_ctx_1" use-vars
470 span "Client session" child-of "ot_ctx_1"
471 ...
472 ----------------------------------------------------------------------------
473
474
475finish <name> ...
476 Closing a particular span or span context. Instead of the name of the span,
477 there are several specially predefined names with which we can finish certain
478 groups of spans. So it can be used as the name '*req*' for all open spans
479 related to the request channel, '*res*' for all open spans related to the
480 response channel and '*' for all open spans regardless of which channel they
481 are related to. Several spans and/or span contexts can be specified in one
482 line.
483
484 Arguments :
485 name - the name of the span or context context
486
487
488inject <name-prefix> [use-vars] [use-headers]
489 In OpenTracing, the transfer of data related to the tracing process between
490 microservices that are part of a larger service is done through the
491 propagation of the span context. The basic operations that allow us to
492 access and transfer this data are 'inject' and 'extract'.
493
494 'inject' allows us to extract span context so that the obtained data can
495 be forwarded to another process (microservice) via the selected carrier.
496 'inject' in the name actually means inject data into carrier. Carrier is
497 an interface here (ie a data structure) that allows us to transfer tracing
498 state from one process to another.
499
500 Data transfer can take place via one of two selected storage methods, the
501 first is by adding data to the HTTP header and the second is by using HAProxy
502 variables. Only data transfer via HTTP header can be used to transfer data
503 to another process (ie microservice). All data is organized in the form of
504 key-value data pairs.
505
506 No matter which data transfer method you use, we need to specify a prefix
507 for the key element. All alphanumerics (lowercase only) and underline
508 character can be used to construct the data name prefix. Uppercase letters
509 can actually be used, but they will be converted to lowercase when creating
510 the prefix.
511
512 Arguments :
513 name-prefix - data name prefix (ie key element prefix)
514 use-vars - HAProxy variables are used to store and transfer data
515 use-headers - HTTP headers are used to store and transfer data
516
517
518 Below is an example of using HTTP headers and variables, and how this is
519 reflected in the internal data of the HAProxy process.
520
521 --- test/ctx/ot.cfg --------------------------------------------------------
522 ...
523 ot-scope client_session_start_1
524 span "HAProxy session" root
525 inject "ot_ctx_1" use-headers use-vars
526 ...
527 ----------------------------------------------------------------------------
528
529 - generated HAProxy variable (key -> value):
530 txn.ot_ctx_1.uberDtraceDid -> 8f1a05a3518d2283:8f1a05a3518d2283:0:1
531
532 - generated HTTP header (key: value):
533 ot_ctx_1-uber-trace-id: 8f1a05a3518d2283:8f1a05a3518d2283:0:1
534
535 Because HAProxy does not allow the '-' character in the variable name (which
536 is automatically generated by the OpenTracing API and on which we have no
537 influence), it is converted to the letter 'D'. We can see that there is no
538 such conversion in the name of the HTTP header because the '-' sign is allowed
539 there. Due to this conversion, initially all uppercase letters are converted
540 to lowercase because otherwise we would not be able to distinguish whether
541 the disputed sign '-' is used or not.
542
543 Thus created HTTP headers and variables are deleted when executing the
544 'finish' keyword or when detaching the stream from the filter.
545
546
547log <name> <sample> ...
548 This kewyord allows setting the log for the currently active span. The
549 data type is always a string, ie any sample type is converted to a string.
550 The exception is a binary value that is not supported by the OT filter.
551
552 See the 'tag' keyword description for the data type conversion table.
553
554 Arguments :
555 name - key part of a data pair
556 sample - sample expression (value part of a data pair), at least one
557 sample must be present
558
559
560span <name> [<reference>]
561 Creating a new span (or referencing an already opened one). If a new span
562 is created, it can be a child of the referenced span, follow from the
563 referenced span, or be root 'span'. In case we did not specify a reference
564 to the previously created span, the new span will become the root span.
565 We need to pay attention to the fact that in one trace there can be only
566 one root span. In case we have specified a non-existent span as a reference,
567 a new span will not be created.
568
569 Arguments :
570 name - the name of the span being created or referenced (operation
571 name)
572 reference - span or span context to which the created span is referenced
573
574
575tag <name> <sample> ...
576 This kewyord allows setting a tag for the currently active span. The first
577 argument is the name of the tag (tag ID) and the second its value. A value
578 can consist of one or more data. If the value is only one data, then the
579 type of that data depends on the type of the HAProxy sample. If the value
580 contains more data, then the data type is string. The data conversion table
581 is below:
582
583 HAProxy sample data type | the OpenTracing data type
584 --------------------------+---------------------------
585 NULL | NULL
586 BOOL | BOOL
587 INT32 | INT64
588 UINT32 | UINT64
589 INT64 | INT64
590 UINT64 | UINT64
591 IPV4 | STRING
592 IPV6 | STRING
593 STRING | STRING
594 BINARY | UNSUPPORTED
595 --------------------------+---------------------------
596
597 Arguments :
598 name - key part of a data pair
599 sample - sample expression (value part of a data pair), at least one
600 sample must be present
601
602
6034.4. "ot-group" section
604------------------------
605
606This section allows us to define a group of OT scopes, that is not activated
607via an event but is triggered from TCP or HTTP rules. More precisely, these
608are the following rules: 'tcp-request', 'tcp-response', 'http-request',
609'http-response' and 'http-after-response'. These rules can be defined in the
610HAProxy configuration file.
611
612
613ot-group <name>
614 Creates a new OT group definition named <name>.
615
616 Arguments :
617 name - the name of the OT group
618
619
620 The following keywords are supported in this section:
621 - scopes
622
623
624scopes <name> ...
625 'ot-scope' sections that are part of the specified group are defined. If
626 the mentioned 'ot-scope' sections are used only in some OT group, they do
627 not have to have defined events. Several 'ot-scope' sections can be
628 specified in one line.
629
630 Arguments :
631 name - the name of the 'ot-scope' section
632
633
6345. Examples
635------------
636
637Several examples of the OT filter configuration can be found in the test
638directory. A brief description of the prepared configurations follows:
639
640cmp - the configuration very similar to that of the spoa-opentracing project.
641 It was made to compare the speed of the OT filter with the
642 implementation of distributed tracing via spoa-opentracing application.
643
644sa - the configuration in which all possible events are used.
645
646ctx - the configuration is very similar to the previous one, with the only
647 difference that the spans are opened using the span context as a span
648 reference.
649
650fe be - a slightly more complicated example of the OT filter configuration
651 that uses two cascaded HAProxy services. The span context between
652 HAProxy processes is transmitted via the HTTP header.
653
654empty - the empty configuration in which the OT filter is initialized but
655 no event is triggered. It is not very usable, except to check the
656 behavior of the OT filter in the case of a similar configuration.
657
658
659In order to be able to collect data (and view results via the web interface)
660we need to install some of the supported tracers. We will use the Jaeger
661tracer as an example. Installation instructions can be found on the website
662https://www.jaegertracing.io/download/. For the impatient, here we will list
663how the image to test the operation of the tracer system can be installed
664without much reading of the documentation.
665
666 # docker pull jaegertracing/all-in-one:latest
667 # docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
668 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 \
669 -p 16686:16686 -p 14268:14268 -p 9411:9411 jaegertracing/all-in-one:latest
670
671The last command will also initialize and run the Jaeger container. If we
672want to use that container later, it can be started and stopped in the classic
673way, using the 'docker container start/stop' commands.
674
675
676In order to be able to use any of the configurations from the test directory,
677we must also have a tracer plugin in that directory (all examples use the
678Jaeger tracer plugin). The simplest way is to download the tracer plugin
679using the already prepared shell script get-opentracing-plugins.sh.
680The script accepts one argument, the directory in which the download is made.
681If run without an argument, the script downloads all plugins to the current
682directory.
683
684 % ./get-opentracing-plugins.sh
685
686After that, we can run one of the pre-configured configurations using the
687provided script run-xxx.sh (where xxx is the name of the configuration being
688tested). For example:
689
690 % ./run-sa.sh
691
692The script will create a new log file each time it is run (because part of the
693log file name is the start time of the script).
694
695Eh, someone will surely notice that all test configurations use the Jaeger
696tracing plugin that cannot be downloaded using the get-opentracing-plugins.sh
697script. Unfortunately, the latest precompiled version that can be downloaded
698is 0.4.2, for newer ones only the source code can be found. Version 0.4.2 has
699a bug that can cause the operation of the OT filter to get stuck, so it is
700better not to use this version. Here is the procedure by which we can compile
701a newer version of the plugin (in our example it is 0.5.0).
702
703Important note: the GCC version must be at least 4.9 or later.
704
705 % wget https://github.com/jaegertracing/jaeger-client-cpp/archive/v0.5.0.tar.gz
706 % tar xf v0.5.0.tar.gz
707 % cd jaeger-client-cpp-0.5.0
708 % mkdir build
709 % cd build
710 % cmake -DCMAKE_INSTALL_PREFIX=/opt -DJAEGERTRACING_PLUGIN=ON -DHUNTER_CONFIGURATION_TYPES=Release -DHUNTER_BUILD_SHARED_LIBS=OFF ..
711 % make
712
713After the plugin is compiled, it will be in the current directory. The name
714of the plugin is libjaegertracing_plugin.so.
715
716
7175.1. Benchmarking results
718--------------------------
719
720To check the operation of the OT filter, several different test configurations
721have been made which are located in the test directory. The test results of
722the same configurations (with the names README-speed-xxx, where xxx is the name
723of the configuration being tested) are also in the directory of the same name.
724
725All tests were performed on the same debian 9.13 system, CPU i7-4770, 32 GB RAM.
726For the purpose of testing, the thttpd web server on port 8000 was used.
727Testing was done with the wrk utility running via run-xxx.sh scripts; that is,
728via the test-speed.sh script that is run as follows:
729
730 % ./test-speed.sh all
731
732The above mentioned thttpd web server is run from that script and it should be
733noted that we need to have the same installed on the system (or change the path
734to the thttpd server in that script if it is installed elsewhere).
735
736Each test is performed several times over a period of 5 minutes per individual
737test. The only difference when running the tests for the same configuration
738was in changing the 'rate-limit' parameter (and the 'option disabled' option),
739which is set to the following values: 100.0, 50.0, 10.0, 2.5 and 0.0 percent.
740Then a test is performed with the OT filter active but disabled for request
741processing ('option disabled' is included in the ot.cfg configuration). In
742the last test, the OT filter is not used at all, ie it is not active and does
743not affect the operation of HAProxy in any way.
744
745
7466. OT CLI
747----------
748
749Via the HAProxy CLI interface we can find out the current status of the OT
750filter and change several of its settings.
751
752All supported CLI commands can be found in the following way, using the
753socat utility with the assumption that the HAProxy CLI socket path is set
754to /tmp/haproxy.sock (of course, instead of socat, nc or other utility can
755be used with a change in arguments when running the same):
756
757 % echo "help" | socat - UNIX-CONNECT:/tmp/haproxy.sock | grep flt-ot
758 --- command output ----------
759 flt-ot debug [level] : set the OT filter debug level (default: get current debug level)
760 flt-ot disable : disable the OT filter
761 flt-ot enable : enable the OT filter
762 flt-ot soft-errors : turning off hard-errors mode
763 flt-ot hard-errors : enabling hard-errors mode
764 flt-ot logging [state] : set logging state (default: get current logging state)
765 flt-ot rate [value] : set the rate limit (default: get current rate value)
766 flt-ot status : show the OT filter status
767 --- command output ----------
768
769'flt-ot debug' can only be used in case the OT filter is compiled with the
770debug mode enabled.
771
772
7737. Known bugs and limitations
774------------------------------
775
776The name of the span context definition can contain only letters, numbers and
777characters '_' and '-'. Also, all uppercase letters in the name are converted
778to lowercase. The character '-' is converted internally to the 'D' character,
779and since a HAProxy variable is generated from that name, this should be taken
780into account if we want to use it somewhere in the HAProxy configuration.
781The above mentioned span context is used in the 'inject' and 'extract' keywords.
782
783Let's look a little at the example test/fe-be (configurations are in the
784test/fe and test/be directories, 'fe' is here the abbreviation for frontend
785and 'be' for backend). In case we have the 'rate-limit' set to a value less
786than 100.0, then distributed tracing will not be started with each new HTTP
787request. It also means that the span context will not be delivered (via the
788HTTP header) to the backend HAProxy process. The 'rate-limit' on the backend
789HAProxy must be set to 100.0, but because the frontend HAProxy does not send
790a span context every time, all such cases will cause an error to be reported
791on the backend server. Therefore, the 'hard-errors' option must be set on the
792backend server, so that processing on that stream is stopped as soon as the
793first error occurs. Such cases will slow down the backend server's response
794a bit (in the example in question it is about 3%).