blob: a6cb21eea407db6c094e45f334d8e40edb1e2aba [file] [log] [blame]
Miroslav Zagorac70230c62020-12-09 16:54:31 +01001Here I will write down some specifics of certain parts of the source, these are
2just some of my thoughts and clues and they are probably not too important for
3a wider audience.
4
5src/parser.c
6------------------------------------------------------------------------------
7The first thing to run when starting the HAProxy is the flt_ot_parse() function
8which actually parses the filter configuration.
9
10In case of correct configuration, the function returns ERR_NONE (or 0), while
11in case of incorrect configuration it returns the combination of ERR_* flags
12(ERR_NONE here does not belong to that bit combination because its value is 0).
13
14One of the parameters of the function is <char **err> in which an error message
15can be returned, if it exists. In that case the return value of the function
16should have some of the ERR_* flags set.
17
18Let's look at an example of the following filter configuration what the function
19call sequence looks like.
20
21Filter configuration line:
22 filter opentracing [id <id>] config <file>
23
24Function call sequence:
25 flt_ot_parse(<err>) {
26 /* Initialization of the filter configuration data. */
27 flt_ot_conf_init() {
28 }
29
30 /* Setting the filter name. */
31 flt_ot_parse_keyword(<err>) {
32 flt_ot_parse_strdup(<err>) {
33 }
34 }
35
36 /* Setting the filter configuration file name. */
37 flt_ot_parse_keyword(<err>) {
38 flt_ot_parse_strdup(<err>) {
39 }
40 }
41
42 /* Checking the configuration of the filter. */
43 flt_ot_parse_cfg(<err>) {
44 flt_ot_parse_cfg_tracer() {
45 }
46 ...
47 flt_ot_post_parse_cfg_tracer() {
48 }
49 flt_ot_parse_cfg_group() {
50 }
51 ...
52 flt_ot_post_parse_cfg_group() {
53 }
54 flt_ot_parse_cfg_scope() {
55 }
56 ...
57 flt_ot_post_parse_cfg_scope() {
58 }
59 }
60 }
61
62Checking the filter configuration is actually much more complicated, only the
63name of the main function flt_ot_parse_cfg() that does it is listed here.
64
65All functions that use the <err> parameter should set the error status using
66that pointer. All other functions (actually these are all functions called
67by the flt_ot_parse_cfg() function) should set the error message using the
68ha_warning()/ha_alert() HAProxy functions. Of course, the return value (the
69mentioned combination of ERR_* bits) is set in all these functions and it
70indicates whether the filter configuration is correct or not.
71
72
73src/group.c
74------------------------------------------------------------------------------
75The OT filter allows the use of groups within which one or more 'ot-scope'
76declarations can be found. These groups can be used using several HAProxy
77rules, more precisely 'http-request', 'http-response', 'tcp-request',
78'tcp-response' and 'http-after-response' rules.
79
80Configuration example for the specified rules:
81 <rule> ot-group <filter-id> <group-name> [ { if | unless } <condition> ]
82
83Parsing each of these rules is performed by the flt_ot_group_parse() function.
84After parsing the configuration, its verification is performed via the
85flt_ot_group_check() function. One parsing function and one configuration
86check function are called for each defined rule.
87
88 flt_ot_group_parse(<err>) {
89 }
90 ...
91 flt_ot_group_check() {
92 }
93 ...
94
95
96When deinitializing the module, the function flt_ot_group_release() is called
97(which is actually an release_ptr callback function from one of the above
98rules). One callback function is called for each defined rule.
99
100 flt_ot_group_release() {
101 }
102 ...
103
104
105src/filter.c
106------------------------------------------------------------------------------
107After parsing and checking the configuration, the flt_ot_check() function is
108called which associates the 'ot-group' and 'ot-scope' definitions with their
109declarations. This procedure concludes the configuration of the OT filter and
110after that its initialization is possible.
111
112 flt_ops.check = flt_ot_check;
113 flt_ot_check() {
114 }
115
116
117The initialization of the OT filter is done via the flt_ot_init() callback
118function. In this function the OpenTracing API library is also initialized.
119It is also possible to initialize for each thread individually, but nothing
120is being done here for now.
121
122 flt_ops.init = flt_ot_init;
123 flt_ot_init() {
124 flt_ot_cli_init() {
125 }
126 /* Initialization of the OpenTracing API. */
127 ot_init(<err>) {
128 }
129 }
130
131 flt_ops.init_per_thread = flt_ot_init_per_thread;
132 flt_ot_init_per_thread() {
133 }
134 ...
135
136
137After the filter instance is created and attached to the stream, the
138flt_ot_attach() function is called. In this function a new OT runtime
139context is created, and flags are set that define which analyzers are used.
140
141 flt_ops.attach = flt_ot_attach;
142 flt_ot_attach() {
143 /* In case OT is disabled, nothing is done on this stream further. */
144 flt_ot_runtime_context_init(<err>) {
145 flt_ot_pool_alloc() {
146 }
Miroslav Zagorac560c7b82021-09-09 14:19:25 +0200147 /* Initializing and setting the variable 'txn.ot.uuid'. */
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100148 if (flt_ot_var_register(<err>) != -1) {
149 flt_ot_var_set(<err>) {
150 }
151 }
152 }
153 }
154
155
156When a stream is started, this function is called. At the moment, nothing
157is being done in it.
158
159 flt_ops.stream_start = flt_ot_stream_start;
160 flt_ot_stream_start() {
161 }
162
163
164Channel analyzers are called when executing individual filter events.
165For each of the four analyzer functions, the events associated with them
166are listed.
167
168 Events:
169 - 1 'on-client-session-start'
170 - 15 'on-server-session-start'
171------------------------------------------------------------------------
172 flt_ops.channel_start_analyze = flt_ot_channel_start_analyze;
173 flt_ot_channel_start_analyze() {
174 flt_ot_event_run() {
175 /* Run event. */
176 flt_ot_scope_run() {
177 /* Processing of all ot-scopes defined for the current event. */
178 }
179 }
180 }
181
182
183 Events:
184 - 2 'on-frontend-tcp-request'
185 - 4 'on-http-body-request'
186 - 5 'on-frontend-http-request'
187 - 6 'on-switching-rules-request'
188 - 7 'on-backend-tcp-request'
189 - 8 'on-backend-http-request'
190 - 9 'on-process-server-rules-request'
191 - 10 'on-http-process-request'
192 - 11 'on-tcp-rdp-cookie-request'
193 - 12 'on-process-sticking-rules-request
194 - 16 'on-tcp-response'
195 - 18 'on-process-store-rules-response'
196 - 19 'on-http-response'
197------------------------------------------------------------------------
198 flt_ops.channel_pre_analyze = flt_ot_channel_pre_analyze;
199 flt_ot_channel_pre_analyze() {
200 flt_ot_event_run() {
201 /* Run event. */
202 flt_ot_scope_run() {
203 /* Processing of all ot-scopes defined for the current event. */
204 }
205 }
206 }
207
208
209 Events:
210 - 3 'on-http-wait-request'
211 - 17 'on-http-wait-response'
212------------------------------------------------------------------------
213 flt_ops.channel_post_analyze = flt_ot_channel_post_analyze;
214 flt_ot_channel_post_analyze() {
215 flt_ot_event_run() {
216 /* Run event. */
217 flt_ot_scope_run() {
218 /* Processing of all ot-scopes defined for the current event. */
219 }
220 }
221 }
222
223
224 Events:
225 - 13 'on-client-session-end'
226 - 14 'on-server-unavailable'
227 - 20 'on-server-session-end'
228------------------------------------------------------------------------
229 flt_ops.channel_end_analyze = flt_ot_channel_end_analyze;
230 flt_ot_channel_end_analyze() {
231 flt_ot_event_run() {
232 /* Run event. */
233 flt_ot_scope_run() {
234 /* Processing of all ot-scopes defined for the current event. */
235 }
236 }
237
238 /* In case the backend server does not work, event 'on-server-unavailable'
239 is called here before event 'on-client-session-end'. */
240 if ('on-server-unavailable') {
241 flt_ot_event_run() {
242 /* Run event. */
243 flt_ot_scope_run() {
244 /* Processing of all ot-scopes defined for the current event. */
245 }
246 }
247 }
248 }
249
250
251After the stream has stopped, this function is called. At the moment, nothing
252is being done in it.
253
254 flt_ops.stream_stop = flt_ot_stream_stop;
255 flt_ot_stream_stop() {
256 }
257
258
259Then, before the instance filter is detached from the stream, the following
260function is called. It deallocates the runtime context of the OT filter.
261
262 flt_ops.detach = flt_ot_detach;
263 flt_ot_detach() {
264 flt_ot_runtime_context_free() {
265 flt_ot_pool_free() {
266 }
267 }
268 }
269
270
271Module deinitialization begins with deinitialization of individual threads
272(as many threads as configured for the HAProxy process). Because nothing
273special is connected to the process threads, nothing is done in this function.
274
275 flt_ops.deinit_per_thread = flt_ot_deinit_per_thread;
276 flt_ot_deinit_per_thread() {
277 }
278 ...
279
280
281For this function see the above description related to the src/group.c file.
282
283 flt_ot_group_release() {
284 }
285 ...
286
287
288Module deinitialization ends with the flt_ot_deinit() function, in which all
289memory occupied by module operation (and OpenTracing API operation, of course)
290is freed.
291
292 flt_ops.deinit = flt_ot_deinit;
293 flt_ot_deinit() {
294 ot_close() {
295 }
296 flt_ot_conf_free() {
297 }
298 }