1 /***
2 * Copyright 2020 HAProxy Technologies
3 *
4 * This file is part of the HAProxy OpenTracing filter.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 #include "include.h"
21
22
23 static struct pool_head *pool_head_ot_span_context __read_mostly = NULL;
24
25 #ifdef USE_POOL_OT_SPAN_CONTEXT
26 REGISTER_POOL(&pool_head_ot_span_context, "ot_span_context", MAX(sizeof(struct otc_span), sizeof(struct otc_span_context)));
27 #endif
28
29
30 #ifdef DEBUG_OT
31
32 /***
33 * NAME
34 * ot_text_map_show -
35 *
36 * ARGUMENTS
37 * text_map -
38 *
39 * DESCRIPTION
40 * -
41 *
42 * RETURN VALUE
43 * This function does not return a value.
44 */
ot_text_map_show(const struct otc_text_map * text_map)45 void ot_text_map_show(const struct otc_text_map *text_map)
46 {
47 FLT_OT_FUNC("%p", text_map);
48
49 if (text_map == NULL)
50 FLT_OT_RETURN();
51
52 FLT_OT_DBG_TEXT_MAP(text_map);
53
54 if ((text_map->key != NULL) && (text_map->value != NULL) && (text_map->count > 0)) {
55 size_t i;
56
57 for (i = 0; i < text_map->count; i++)
58 FLT_OT_DBG(3, " \"%s\" -> \"%s\"", text_map->key[i], text_map->value[i]);
59 }
60
61 FLT_OT_RETURN();
62 }
63
64
65 /***
66 * NAME
67 * ot_debug -
68 *
69 * ARGUMENTS
70 * This function takes no arguments.
71 *
72 * DESCRIPTION
73 * -
74 *
75 * RETURN VALUE
76 * This function does not return a value.
77 */
ot_debug(void)78 void ot_debug(void)
79 {
80 char buffer[BUFSIZ];
81
82 FLT_OT_FUNC("");
83
84 otc_statistics(buffer, sizeof(buffer));
85 FLT_OT_DBG(0, "%s", buffer);
86
87 FLT_OT_RETURN();
88 }
89
90 #endif /* DEBUG_OT */
91
92
93 /***
94 * NAME
95 * ot_mem_malloc -
96 *
97 * ARGUMENTS
98 * func -
99 * line -
100 * size -
101 *
102 * DESCRIPTION
103 * -
104 *
105 * RETURN VALUE
106 * -
107 */
ot_mem_malloc(FLT_OT_DBG_ARGS (const char * func,int line,)size_t size)108 static void *ot_mem_malloc(FLT_OT_DBG_ARGS(const char *func, int line, ) size_t size)
109 {
110 return flt_ot_pool_alloc(pool_head_ot_span_context, size, 1, NULL);
111 }
112
113
114 /***
115 * NAME
116 * ot_mem_free -
117 *
118 * ARGUMENTS
119 * func -
120 * line -
121 * ptr -
122 *
123 * DESCRIPTION
124 * -
125 *
126 * RETURN VALUE
127 * This function does not return a value.
128 */
ot_mem_free(FLT_OT_DBG_ARGS (const char * func,int line,)void * ptr)129 static void ot_mem_free(FLT_OT_DBG_ARGS(const char *func, int line, ) void *ptr)
130 {
131 flt_ot_pool_free(pool_head_ot_span_context, &ptr);
132 }
133
134
135 /***
136 * NAME
137 * ot_init -
138 *
139 * ARGUMENTS
140 * tracer -
141 * plugin -
142 * err -
143 *
144 * DESCRIPTION
145 * -
146 *
147 * RETURN VALUE
148 * -
149 */
ot_init(struct otc_tracer ** tracer,const char * plugin,char ** err)150 int ot_init(struct otc_tracer **tracer, const char *plugin, char **err)
151 {
152 char cwd[PATH_MAX], path[PATH_MAX], errbuf[BUFSIZ] = "";
153 int rc, retval = -1;
154
155 FLT_OT_FUNC("%p:%p, \"%s\", %p:%p", FLT_OT_DPTR_ARGS(tracer), plugin, FLT_OT_DPTR_ARGS(err));
156
157 flt_ot_pools_info();
158 #ifdef USE_POOL_OT_SPAN_CONTEXT
159 FLT_OT_DBG(2, "sizeof_pool(ot_span_context) = %u", pool_head_ot_span_context->size);
160 #endif
161
162 if (getcwd(cwd, sizeof(cwd)) == NULL) {
163 FLT_OT_ERR("failed to get current working directory");
164
165 FLT_OT_RETURN(retval);
166 }
167 rc = snprintf(path, sizeof(path), "%s/%s", cwd, plugin);
168 if ((rc == -1) || (rc >= sizeof(path))) {
169 FLT_OT_ERR("failed to construct the OpenTracing plugin path");
170
171 FLT_OT_RETURN(retval);
172 }
173
174 *tracer = otc_tracer_load(path, errbuf, sizeof(errbuf));
175 if (*tracer == NULL) {
176 FLT_OT_ERR("%s", (*errbuf == '\0') ? "failed to initialize tracing library" : errbuf);
177 } else {
178 otc_ext_init(ot_mem_malloc, ot_mem_free);
179
180 retval = 0;
181 }
182
183 FLT_OT_RETURN(retval);
184 }
185
186
187 /***
188 * NAME
189 * ot_start -
190 *
191 * ARGUMENTS
192 * tracer -
193 * cfgbuf -
194 * err -
195 *
196 * DESCRIPTION
197 * -
198 *
199 * RETURN VALUE
200 * This function does not return a value.
201 */
ot_start(struct otc_tracer * tracer,const char * cfgbuf,char ** err)202 int ot_start(struct otc_tracer *tracer, const char *cfgbuf, char **err)
203 {
204 char errbuf[BUFSIZ] = "";
205 int retval = -1;
206
207 FLT_OT_FUNC("%p, %p, %p:%p", tracer, cfgbuf, FLT_OT_DPTR_ARGS(err));
208
209 if (cfgbuf == NULL)
210 FLT_OT_RETURN(retval);
211
212 retval = otc_tracer_start(NULL, cfgbuf, errbuf, sizeof(errbuf));
213 if (retval == -1)
214 FLT_OT_ERR("%s", (*errbuf == '\0') ? "failed to start tracer" : errbuf);
215
216 FLT_OT_RETURN(retval);
217 }
218
219
220 /***
221 * NAME
222 * ot_close -
223 *
224 * ARGUMENTS
225 * tracer -
226 *
227 * DESCRIPTION
228 * -
229 *
230 * RETURN VALUE
231 * This function does not return a value.
232 */
ot_close(struct otc_tracer ** tracer)233 void ot_close(struct otc_tracer **tracer)
234 {
235 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(tracer));
236
237 if ((tracer == NULL) || (*tracer == NULL))
238 FLT_OT_RETURN();
239
240 (*tracer)->close(*tracer);
241
242 *tracer = NULL;
243
244 FLT_OT_RETURN();
245 }
246
247
248 /***
249 * NAME
250 * ot_span_init -
251 *
252 * ARGUMENTS
253 * tracer -
254 * operation_name -
255 * ts_steady -
256 * ts_system -
257 * ref_type -
258 * ref_ctx_idx -
259 * ref_span -
260 * tags -
261 * num_tags -
262 * err -
263 *
264 * DESCRIPTION
265 * -
266 *
267 * RETURN VALUE
268 * -
269 */
ot_span_init(struct otc_tracer * tracer,const char * operation_name,const struct timespec * ts_steady,const struct timespec * ts_system,int ref_type,int ref_ctx_idx,const struct otc_span * ref_span,const struct otc_tag * tags,int num_tags,char ** err)270 struct otc_span *ot_span_init(struct otc_tracer *tracer, const char *operation_name, const struct timespec *ts_steady, const struct timespec *ts_system, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span, const struct otc_tag *tags, int num_tags, char **err)
271 {
272 struct otc_start_span_options options;
273 struct otc_span_context context = { .idx = ref_ctx_idx, .span = ref_span };
274 struct otc_span_reference references = { ref_type, &context };
275 struct otc_span *retptr = NULL;
276
277 FLT_OT_FUNC("%p, \"%s\", %p, %p, %d, %d, %p, %p, %d, %p:%p", tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, tags, num_tags, FLT_OT_DPTR_ARGS(err));
278
279 if (operation_name == NULL)
280 FLT_OT_RETURN(retptr);
281 else if (tracer == NULL)
282 FLT_OT_RETURN(retptr);
283
284 (void)memset(&options, 0, sizeof(options));
285
286 if (ts_steady != NULL)
287 (void)memcpy(&(options.start_time_steady.value), ts_steady, sizeof(options.start_time_steady.value));
288
289 if (ts_system != NULL)
290 (void)memcpy(&(options.start_time_system.value), ts_system, sizeof(options.start_time_system.value));
291
292 if (FLT_OT_IN_RANGE(ref_type, otc_span_reference_child_of, otc_span_reference_follows_from)) {
293 options.references = &references;
294 options.num_references = 1;
295 }
296
297 options.tags = tags;
298 options.num_tags = num_tags;
299
300 retptr = tracer->start_span_with_options(tracer, operation_name, &options);
301 if (retptr == NULL)
302 FLT_OT_ERR("failed to init new span");
303 else
304 FLT_OT_DBG(2, "span %p:%zd initialized", retptr, retptr->idx);
305
306 FLT_OT_RETURN(retptr);
307 }
308
309
310 /***
311 * NAME
312 * ot_span_init_va -
313 *
314 * ARGUMENTS
315 * tracer -
316 * operation_name -
317 * ts_steady -
318 * ts_system -
319 * ref_type -
320 * ref_ctx_idx -
321 * ref_span -
322 * err -
323 * tag_key -
324 * tag_value -
325 *
326 * DESCRIPTION
327 * -
328 *
329 * RETURN VALUE
330 * -
331 */
ot_span_init_va(struct otc_tracer * tracer,const char * operation_name,const struct timespec * ts_steady,const struct timespec * ts_system,int ref_type,int ref_ctx_idx,const struct otc_span * ref_span,char ** err,const char * tag_key,const char * tag_value,...)332 struct otc_span *ot_span_init_va(struct otc_tracer *tracer, const char *operation_name, const struct timespec *ts_steady, const struct timespec *ts_system, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span, char **err, const char *tag_key, const char *tag_value, ...)
333 {
334 struct otc_tag tags[FLT_OT_MAXTAGS];
335 int num_tags = 0;
336 struct otc_span *retptr;
337
338 FLT_OT_FUNC("%p, \"%s\", %p, %p, %d, %d, %p, %p:%p, \"%s\", \"%s\", ...", tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, FLT_OT_DPTR_ARGS(err), tag_key, tag_value);
339
340 if (tag_key != NULL) {
341 va_list ap;
342
343 va_start(ap, tag_value);
344 for (num_tags = 0; (num_tags < FLT_OT_TABLESIZE(tags)) && (tag_key != NULL) && (tag_value != NULL); num_tags++) {
345 tags[num_tags].key = (char *)tag_key;
346 FLT_OT_VSET(&(tags[num_tags].value), string, tag_value);
347
348 tag_key = va_arg(ap, typeof(tag_key));
349 if (tag_key != NULL)
350 tag_value = va_arg(ap, typeof(tag_value));
351 }
352 va_end(ap);
353 }
354
355 retptr = ot_span_init(tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, tags, num_tags, err);
356
357 FLT_OT_RETURN(retptr);
358 }
359
360
361 /***
362 * NAME
363 * ot_span_tag -
364 *
365 * ARGUMENTS
366 * span -
367 * tags -
368 * num_tags -
369 *
370 * DESCRIPTION
371 * -
372 *
373 * RETURN VALUE
374 * -
375 */
ot_span_tag(struct otc_span * span,const struct otc_tag * tags,int num_tags)376 int ot_span_tag(struct otc_span *span, const struct otc_tag *tags, int num_tags)
377 {
378 int retval = -1;
379
380 FLT_OT_FUNC("%p, %p, %d", span, tags, num_tags);
381
382 if ((span == NULL) || (tags == NULL))
383 FLT_OT_RETURN(retval);
384
385 for (retval = 0; retval < num_tags; retval++)
386 span->set_tag(span, tags[retval].key, &(tags[retval].value));
387
388 FLT_OT_RETURN(retval);
389 }
390
391
392 /***
393 * NAME
394 * ot_span_tag_va -
395 *
396 * ARGUMENTS
397 * span -
398 * key -
399 * type -
400 * value -
401 *
402 * DESCRIPTION
403 * -
404 *
405 * RETURN VALUE
406 * -
407 */
ot_span_tag_va(struct otc_span * span,const char * key,int type,...)408 int ot_span_tag_va(struct otc_span *span, const char *key, int type, ...)
409 {
410 va_list ap;
411 struct otc_value ot_value;
412 int retval = -1;
413
414 FLT_OT_FUNC("%p, \"%s\", %d, ...", span, key, type);
415
416 if ((span == NULL) || (key == NULL))
417 FLT_OT_RETURN(retval);
418
419 va_start(ap, type);
420 for (retval = 0; (key != NULL) && FLT_OT_IN_RANGE(type, otc_value_bool, otc_value_null); retval++) {
421 ot_value.type = type;
422 if (type == otc_value_bool)
423 ot_value.value.bool_value = va_arg(ap, typeof(ot_value.value.bool_value));
424 else if (type == otc_value_double)
425 ot_value.value.double_value = va_arg(ap, typeof(ot_value.value.double_value));
426 else if (type == otc_value_int64)
427 ot_value.value.int64_value = va_arg(ap, typeof(ot_value.value.int64_value));
428 else if (type == otc_value_uint64)
429 ot_value.value.uint64_value = va_arg(ap, typeof(ot_value.value.uint64_value));
430 else if (type == otc_value_string)
431 ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value));
432 else if (type == otc_value_null)
433 ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value));
434 span->set_tag(span, key, &ot_value);
435
436 key = va_arg(ap, typeof(key));
437 if (key != NULL)
438 type = va_arg(ap, typeof(type));
439 }
440 va_end(ap);
441
442 FLT_OT_RETURN(retval);
443 }
444
445
446 /***
447 * NAME
448 * ot_span_log -
449 *
450 * ARGUMENTS
451 * span -
452 * log_fields -
453 * num_fields -
454 *
455 * DESCRIPTION
456 * -
457 *
458 * RETURN VALUE
459 * -
460 */
ot_span_log(struct otc_span * span,const struct otc_log_field * log_fields,int num_fields)461 int ot_span_log(struct otc_span *span, const struct otc_log_field *log_fields, int num_fields)
462 {
463 int retval = -1;
464
465 FLT_OT_FUNC("%p, %p, %d", span, log_fields, num_fields);
466
467 if ((span == NULL) || (log_fields == NULL))
468 FLT_OT_RETURN(retval);
469
470 retval = MIN(OTC_MAXLOGFIELDS, num_fields);
471
472 span->log_fields(span, log_fields, retval);
473
474 FLT_OT_RETURN(retval);
475 }
476
477
478 /***
479 * NAME
480 * ot_span_log_va -
481 *
482 * ARGUMENTS
483 * span -
484 * key -
485 * value -
486 *
487 * DESCRIPTION
488 * -
489 *
490 * RETURN VALUE
491 * -
492 */
ot_span_log_va(struct otc_span * span,const char * key,const char * value,...)493 int ot_span_log_va(struct otc_span *span, const char *key, const char *value, ...)
494 {
495 va_list ap;
496 struct otc_log_field log_field[OTC_MAXLOGFIELDS];
497 int retval = -1;
498
499 FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value);
500
501 if ((span == NULL) || (key == NULL) || (value == NULL))
502 FLT_OT_RETURN(retval);
503
504 va_start(ap, value);
505 for (retval = 0; (retval < FLT_OT_TABLESIZE(log_field)) && (key != NULL); retval++) {
506 log_field[retval].key = key;
507 log_field[retval].value.type = otc_value_string;
508 log_field[retval].value.value.string_value = value;
509
510 key = va_arg(ap, typeof(key));
511 if (key != NULL)
512 value = va_arg(ap, typeof(value));
513 }
514 va_end(ap);
515
516 span->log_fields(span, log_field, retval);
517
518 FLT_OT_RETURN(retval);
519 }
520
521
522 /***
523 * NAME
524 * ot_span_log_fmt -
525 *
526 * ARGUMENTS
527 * span -
528 * key -
529 * format -
530 *
531 * DESCRIPTION
532 * -
533 *
534 * RETURN VALUE
535 * -
536 */
ot_span_log_fmt(struct otc_span * span,const char * key,const char * format,...)537 int ot_span_log_fmt(struct otc_span *span, const char *key, const char *format, ...)
538 {
539 va_list ap;
540 char value[BUFSIZ];
541 int n;
542
543 FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, format);
544
545 if ((span == NULL) || (key == NULL) || (format == NULL))
546 FLT_OT_RETURN(-1);
547
548 va_start(ap, format);
549 n = vsnprintf(value, sizeof(value), format, ap);
550 if (!FLT_OT_IN_RANGE(n, 0, sizeof(value) - 1)) {
551 FLT_OT_DBG(2, "WARNING: log buffer too small (%d > %zu)", n, sizeof(value));
552
553 FLT_OT_STR_ELLIPSIS(value, sizeof(value));
554 }
555 va_end(ap);
556
557 FLT_OT_RETURN(ot_span_log_va(span, key, value, NULL));
558 }
559
560
561 /***
562 * NAME
563 * ot_span_set_baggage -
564 *
565 * ARGUMENTS
566 * span -
567 * baggage -
568 *
569 * DESCRIPTION
570 * -
571 *
572 * RETURN VALUE
573 * -
574 */
ot_span_set_baggage(struct otc_span * span,const struct otc_text_map * baggage)575 int ot_span_set_baggage(struct otc_span *span, const struct otc_text_map *baggage)
576 {
577 size_t i;
578 int retval = -1;
579
580 FLT_OT_FUNC("%p, %p", span, baggage);
581
582 if ((span == NULL) || (baggage == NULL))
583 FLT_OT_RETURN(retval);
584
585 if ((baggage->key == NULL) || (baggage->value == NULL))
586 FLT_OT_RETURN(retval);
587
588 for (retval = i = 0; i < baggage->count; i++) {
589 FLT_OT_DBG(3, "set baggage: \"%s\" -> \"%s\"", baggage->key[i], baggage->value[i]);
590
591 if ((baggage->key[i] != NULL) && (baggage->value[i] != NULL)) {
592 span->set_baggage_item(span, baggage->key[i], baggage->value[i]);
593
594 retval++;
595 }
596 }
597
598 FLT_OT_RETURN(retval);
599 }
600
601
602 /***
603 * NAME
604 * ot_span_set_baggage_va -
605 *
606 * ARGUMENTS
607 * span -
608 * key -
609 * value -
610 *
611 * DESCRIPTION
612 * -
613 *
614 * RETURN VALUE
615 * -
616 */
ot_span_set_baggage_va(struct otc_span * span,const char * key,const char * value,...)617 int ot_span_set_baggage_va(struct otc_span *span, const char *key, const char *value, ...)
618 {
619 va_list ap;
620 int retval = -1;
621
622 FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value);
623
624 if ((span == NULL) || (key == NULL) || (value == NULL))
625 FLT_OT_RETURN(retval);
626
627 va_start(ap, value);
628 for (retval = 0; (key != NULL); retval++) {
629 FLT_OT_DBG(3, "set baggage: \"%s\" -> \"%s\"", key, value);
630
631 span->set_baggage_item(span, key, value);
632
633 key = va_arg(ap, typeof(key));
634 if (key != NULL)
635 value = va_arg(ap, typeof(value));
636 }
637 va_end(ap);
638
639 FLT_OT_RETURN(retval);
640 }
641
642
643 /***
644 * NAME
645 * ot_span_baggage_va -
646 *
647 * ARGUMENTS
648 * span -
649 * key -
650 *
651 * DESCRIPTION
652 * -
653 *
654 * RETURN VALUE
655 * -
656 */
ot_span_baggage_va(const struct otc_span * span,const char * key,...)657 struct otc_text_map *ot_span_baggage_va(const struct otc_span *span, const char *key, ...)
658 {
659 va_list ap;
660 struct otc_text_map *retptr = NULL;
661 int i, n;
662
663 FLT_OT_FUNC("%p, \"%s\", ...", span, key);
664
665 if ((span == NULL) || (key == NULL))
666 FLT_OT_RETURN(retptr);
667
668 va_start(ap, key);
669 for (n = 1; va_arg(ap, typeof(key)) != NULL; n++);
670 va_end(ap);
671
672 retptr = otc_text_map_new(NULL, n);
673 if (retptr == NULL)
674 FLT_OT_RETURN(retptr);
675
676 va_start(ap, key);
677 for (i = 0; (i < n) && (key != NULL); i++) {
678 char *value = (char *)span->baggage_item(span, key);
679
680 if (value != NULL) {
681 (void)otc_text_map_add(retptr, key, 0, value, 0, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE);
682
683 FLT_OT_DBG(3, "get baggage[%d]: \"%s\" -> \"%s\"", i, retptr->key[i], retptr->value[i]);
684 } else {
685 FLT_OT_DBG(3, "get baggage[%d]: \"%s\" -> invalid key", i, key);
686 }
687
688 key = va_arg(ap, typeof(key));
689 }
690 va_end(ap);
691
692 FLT_OT_RETURN(retptr);
693 }
694
695
696 /***
697 * NAME
698 * ot_inject_text_map -
699 *
700 * ARGUMENTS
701 * tracer -
702 * span -
703 * carrier -
704 *
705 * DESCRIPTION
706 * -
707 *
708 * RETURN VALUE
709 * -
710 */
ot_inject_text_map(struct otc_tracer * tracer,const struct otc_span * span,struct otc_text_map_writer * carrier)711 struct otc_span_context *ot_inject_text_map(struct otc_tracer *tracer, const struct otc_span *span, struct otc_text_map_writer *carrier)
712 {
713 struct otc_span_context *retptr = NULL;
714 int rc;
715
716 FLT_OT_FUNC("%p, %p, %p", tracer, span, carrier);
717
718 if ((span == NULL) || (carrier == NULL))
719 FLT_OT_RETURN(retptr);
720 else if (tracer == NULL)
721 FLT_OT_RETURN(retptr);
722
723 retptr = span->span_context((struct otc_span *)span);
724 if (retptr == NULL)
725 FLT_OT_RETURN(retptr);
726
727 (void)memset(carrier, 0, sizeof(*carrier));
728
729 rc = tracer->inject_text_map(tracer, carrier, retptr);
730 if (rc != otc_propagation_error_code_success) {
731 FLT_OT_FREE_CLEAR(retptr);
732 } else {
733 #ifdef DEBUG_OT
734 FLT_OT_DBG_TEXT_CARRIER(carrier, set);
735 ot_text_map_show(&(carrier->text_map));
736 FLT_OT_DBG_SPAN_CONTEXT(retptr);
737 #endif
738 }
739
740 FLT_OT_RETURN(retptr);
741 }
742
743
744 /***
745 * NAME
746 * ot_inject_http_headers -
747 *
748 * ARGUMENTS
749 * tracer -
750 * span -
751 * carrier -
752 * err -
753 *
754 * DESCRIPTION
755 * -
756 *
757 * RETURN VALUE
758 * -
759 */
ot_inject_http_headers(struct otc_tracer * tracer,const struct otc_span * span,struct otc_http_headers_writer * carrier,char ** err)760 struct otc_span_context *ot_inject_http_headers(struct otc_tracer *tracer, const struct otc_span *span, struct otc_http_headers_writer *carrier, char **err)
761 {
762 struct otc_span_context *retptr = NULL;
763 int rc;
764
765 FLT_OT_FUNC("%p, %p, %p, %p:%p", tracer, span, carrier, FLT_OT_DPTR_ARGS(err));
766
767 if ((span == NULL) || (carrier == NULL))
768 FLT_OT_RETURN(retptr);
769 else if (tracer == NULL)
770 FLT_OT_RETURN(retptr);
771
772 retptr = span->span_context((struct otc_span *)span);
773 if (retptr == NULL) {
774 FLT_OT_ERR("failed to create span context");
775
776 FLT_OT_RETURN(retptr);
777 }
778
779 (void)memset(carrier, 0, sizeof(*carrier));
780
781 rc = tracer->inject_http_headers(tracer, carrier, retptr);
782 if (rc != otc_propagation_error_code_success) {
783 FLT_OT_ERR("failed to inject HTTP headers data");
784
785 FLT_OT_FREE_CLEAR(retptr);
786 } else {
787 #ifdef DEBUG_OT
788 FLT_OT_DBG_TEXT_CARRIER(carrier, set);
789 ot_text_map_show(&(carrier->text_map));
790 FLT_OT_DBG_SPAN_CONTEXT(retptr);
791 #endif
792 }
793
794 FLT_OT_RETURN(retptr);
795 }
796
797
798 /***
799 * NAME
800 * ot_inject_binary -
801 *
802 * ARGUMENTS
803 * tracer -
804 * span -
805 * carrier -
806 *
807 * DESCRIPTION
808 * -
809 *
810 * RETURN VALUE
811 * -
812 */
ot_inject_binary(struct otc_tracer * tracer,const struct otc_span * span,struct otc_custom_carrier_writer * carrier)813 struct otc_span_context *ot_inject_binary(struct otc_tracer *tracer, const struct otc_span *span, struct otc_custom_carrier_writer *carrier)
814 {
815 struct otc_span_context *retptr = NULL;
816 int rc;
817
818 FLT_OT_FUNC("%p, %p, %p", tracer, span, carrier);
819
820 if ((span == NULL) || (carrier == NULL))
821 FLT_OT_RETURN(retptr);
822 else if (tracer == NULL)
823 FLT_OT_RETURN(retptr);
824
825 retptr = span->span_context((struct otc_span *)span);
826 if (retptr == NULL)
827 FLT_OT_RETURN(retptr);
828
829 (void)memset(carrier, 0, sizeof(*carrier));
830
831 rc = tracer->inject_binary(tracer, carrier, retptr);
832 if (rc != otc_propagation_error_code_success) {
833 FLT_OT_FREE_CLEAR(retptr);
834 } else {
835 #ifdef DEBUG_OT
836 struct otc_jaeger_trace_context *ctx = carrier->binary_data.data;
837
838 FLT_OT_DBG_CUSTOM_CARRIER(carrier, inject);
839 FLT_OT_DBG(3, "trace context: %016" PRIx64 "%016" PRIx64 ":%016" PRIx64 ":%016" PRIx64 ":%02hhx <%s> <%s>",
840 ctx->trace_id[0], ctx->trace_id[1], ctx->span_id, ctx->parent_span_id, ctx->flags,
841 flt_ot_str_hex(ctx->baggage, carrier->binary_data.size - sizeof(*ctx)),
842 flt_ot_str_ctrl(ctx->baggage, carrier->binary_data.size - sizeof(*ctx)));
843 FLT_OT_DBG_SPAN_CONTEXT(retptr);
844 #endif
845 }
846
847 FLT_OT_RETURN(retptr);
848 }
849
850
851 /***
852 * NAME
853 * ot_extract_text_map -
854 *
855 * ARGUMENTS
856 * tracer -
857 * carrier -
858 * text_map -
859 *
860 * DESCRIPTION
861 * -
862 *
863 * RETURN VALUE
864 * -
865 */
ot_extract_text_map(struct otc_tracer * tracer,struct otc_text_map_reader * carrier,const struct otc_text_map * text_map)866 struct otc_span_context *ot_extract_text_map(struct otc_tracer *tracer, struct otc_text_map_reader *carrier, const struct otc_text_map *text_map)
867 {
868 struct otc_span_context *retptr = NULL;
869 int rc;
870
871 FLT_OT_FUNC("%p, %p, %p", tracer, carrier, text_map);
872
873 if (carrier == NULL)
874 FLT_OT_RETURN(retptr);
875 else if (tracer == NULL)
876 FLT_OT_RETURN(retptr);
877
878 if (text_map != NULL) {
879 (void)memset(carrier, 0, sizeof(*carrier));
880 (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map));
881
882 FLT_OT_DBG_TEXT_CARRIER(carrier, foreach_key);
883 }
884
885 rc = tracer->extract_text_map(tracer, carrier, &retptr);
886 if (rc != otc_propagation_error_code_success)
887 FLT_OT_FREE_CLEAR(retptr);
888 else if (retptr != NULL)
889 FLT_OT_DBG_SPAN_CONTEXT(retptr);
890
891 FLT_OT_RETURN(retptr);
892 }
893
894
895 /***
896 * NAME
897 * ot_extract_http_headers -
898 *
899 * ARGUMENTS
900 * tracer -
901 * carrier -
902 * text_map -
903 * err -
904 *
905 * DESCRIPTION
906 * -
907 *
908 * RETURN VALUE
909 * -
910 */
ot_extract_http_headers(struct otc_tracer * tracer,struct otc_http_headers_reader * carrier,const struct otc_text_map * text_map,char ** err)911 struct otc_span_context *ot_extract_http_headers(struct otc_tracer *tracer, struct otc_http_headers_reader *carrier, const struct otc_text_map *text_map, char **err)
912 {
913 struct otc_span_context *retptr = NULL;
914 int rc;
915
916 FLT_OT_FUNC("%p, %p, %p, %p:%p", tracer, carrier, text_map, FLT_OT_DPTR_ARGS(err));
917
918 if (carrier == NULL)
919 FLT_OT_RETURN(retptr);
920 else if (tracer == NULL)
921 FLT_OT_RETURN(retptr);
922
923 if (text_map != NULL) {
924 (void)memset(carrier, 0, sizeof(*carrier));
925 (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map));
926
927 FLT_OT_DBG_TEXT_CARRIER(carrier, foreach_key);
928 }
929
930 rc = tracer->extract_http_headers(tracer, carrier, &retptr);
931 if (rc != otc_propagation_error_code_success) {
932 FLT_OT_ERR("failed to extract HTTP headers data");
933
934 FLT_OT_FREE_CLEAR(retptr);
935 }
936 else if (retptr != NULL)
937 FLT_OT_DBG_SPAN_CONTEXT(retptr);
938
939 FLT_OT_RETURN(retptr);
940 }
941
942
943 /***
944 * NAME
945 * ot_extract_binary -
946 *
947 * ARGUMENTS
948 * tracer -
949 * carrier -
950 * binary_data -
951 *
952 * DESCRIPTION
953 * -
954 *
955 * RETURN VALUE
956 * -
957 */
ot_extract_binary(struct otc_tracer * tracer,struct otc_custom_carrier_reader * carrier,const struct otc_binary_data * binary_data)958 struct otc_span_context *ot_extract_binary(struct otc_tracer *tracer, struct otc_custom_carrier_reader *carrier, const struct otc_binary_data *binary_data)
959 {
960 struct otc_span_context *retptr = NULL;
961 int rc;
962
963 FLT_OT_FUNC("%p, %p, %p", tracer, carrier, binary_data);
964
965 if (carrier == NULL)
966 FLT_OT_RETURN(retptr);
967 else if (tracer == NULL)
968 FLT_OT_RETURN(retptr);
969
970 if ((FLT_OT_DEREF(binary_data, data, NULL) != NULL) && (binary_data->size > 0)) {
971 (void)memset(carrier, 0, sizeof(*carrier));
972 (void)memcpy(&(carrier->binary_data), binary_data, sizeof(carrier->binary_data));
973
974 FLT_OT_DBG_CUSTOM_CARRIER(carrier, extract);
975 }
976
977 rc = tracer->extract_binary(tracer, carrier, &retptr);
978 if (rc != otc_propagation_error_code_success)
979 FLT_OT_FREE_CLEAR(retptr);
980 else if (retptr != NULL)
981 FLT_OT_DBG_SPAN_CONTEXT(retptr);
982
983 FLT_OT_RETURN(retptr);
984 }
985
986
987 /***
988 * NAME
989 * ot_span_finish -
990 *
991 * ARGUMENTS
992 * span -
993 * ts_finish -
994 * log_ts -
995 * log_key -
996 * log_value -
997 *
998 * DESCRIPTION
999 * -
1000 *
1001 * RETURN VALUE
1002 * This function does not return a value.
1003 */
ot_span_finish(struct otc_span ** span,const struct timespec * ts_finish,const struct timespec * log_ts,const char * log_key,const char * log_value,...)1004 void ot_span_finish(struct otc_span **span, const struct timespec *ts_finish, const struct timespec *log_ts, const char *log_key, const char *log_value, ...)
1005 {
1006 struct otc_finish_span_options options;
1007 struct otc_log_field log_field[OTC_MAXLOGFIELDS];
1008 struct otc_log_record log_records = { .fields = log_field, .num_fields = 0 };
1009 #ifdef DEBUG_OT
1010 typeof((*span)->idx) idx = FLT_OT_DDEREF(span, idx, 0);
1011 #endif
1012
1013 FLT_OT_FUNC("%p:%p, %p, %p, \"%s\", \"%s\", ...", FLT_OT_DPTR_ARGS(span), ts_finish, log_ts, log_key, log_value);
1014
1015 if ((span == NULL) || (*span == NULL))
1016 FLT_OT_RETURN();
1017
1018 (void)memset(&options, 0, sizeof(options));
1019
1020 if (ts_finish != NULL)
1021 (void)memcpy(&(options.finish_time.value), ts_finish, sizeof(options.finish_time.value));
1022
1023 if (log_key != NULL) {
1024 va_list ap;
1025 int i;
1026
1027 if (log_ts != NULL)
1028 (void)memcpy(&(log_records.timestamp.value), log_ts, sizeof(log_records.timestamp.value));
1029
1030 va_start(ap, log_value);
1031 for (i = 0; (i < FLT_OT_TABLESIZE(log_field)) && (log_key != NULL); i++) {
1032 log_field[i].key = log_key;
1033 log_field[i].value.type = otc_value_string;
1034 log_field[i].value.value.string_value = log_value;
1035
1036 log_key = va_arg(ap, typeof(log_key));
1037 if (log_key != NULL)
1038 log_value = va_arg(ap, typeof(log_value));
1039 }
1040 va_end(ap);
1041
1042 log_records.num_fields = i;
1043 options.log_records = &log_records;
1044 options.num_log_records = 1;
1045 }
1046
1047 /*
1048 * Caution: memory allocated for the span is released
1049 * in the function finish_with_options().
1050 */
1051 (*span)->finish_with_options(*span, &options);
1052
1053 FLT_OT_DBG(2, "span %p:%zu finished", *span, idx);
1054
1055 *span = NULL;
1056
1057 FLT_OT_RETURN();
1058 }
1059
1060 /*
1061 * Local variables:
1062 * c-indent-level: 8
1063 * c-basic-offset: 8
1064 * End:
1065 *
1066 * vi: noexpandtab shiftwidth=8 tabstop=8
1067 */
1068