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