summaryrefslogtreecommitdiffstats
path: root/addons/ot/src/opentracing.c
diff options
context:
space:
mode:
Diffstat (limited to 'addons/ot/src/opentracing.c')
-rw-r--r--addons/ot/src/opentracing.c1067
1 files changed, 1067 insertions, 0 deletions
diff --git a/addons/ot/src/opentracing.c b/addons/ot/src/opentracing.c
new file mode 100644
index 0000000..8ae5f02
--- /dev/null
+++ b/addons/ot/src/opentracing.c
@@ -0,0 +1,1067 @@
+/***
+ * Copyright 2020 HAProxy Technologies
+ *
+ * This file is part of the HAProxy OpenTracing filter.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "include.h"
+
+
+static struct pool_head *pool_head_ot_span_context __read_mostly = NULL;
+
+#ifdef USE_POOL_OT_SPAN_CONTEXT
+REGISTER_POOL(&pool_head_ot_span_context, "ot_span_context", MAX(sizeof(struct otc_span), sizeof(struct otc_span_context)));
+#endif
+
+
+#ifdef DEBUG_OT
+
+/***
+ * NAME
+ * ot_text_map_show -
+ *
+ * ARGUMENTS
+ * text_map -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * This function does not return a value.
+ */
+void ot_text_map_show(const struct otc_text_map *text_map)
+{
+ FLT_OT_FUNC("%p", text_map);
+
+ if (text_map == NULL)
+ FLT_OT_RETURN();
+
+ FLT_OT_DBG_TEXT_MAP(text_map);
+
+ if ((text_map->key != NULL) && (text_map->value != NULL) && (text_map->count > 0)) {
+ size_t i;
+
+ for (i = 0; i < text_map->count; i++)
+ FLT_OT_DBG(3, " \"%s\" -> \"%s\"", text_map->key[i], text_map->value[i]);
+ }
+
+ FLT_OT_RETURN();
+}
+
+
+/***
+ * NAME
+ * ot_debug -
+ *
+ * ARGUMENTS
+ * This function takes no arguments.
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * This function does not return a value.
+ */
+void ot_debug(void)
+{
+ char buffer[BUFSIZ];
+
+ FLT_OT_FUNC("");
+
+ otc_statistics(buffer, sizeof(buffer));
+ FLT_OT_DBG(0, "%s", buffer);
+
+ FLT_OT_RETURN();
+}
+
+#endif /* DEBUG_OT */
+
+
+/***
+ * NAME
+ * ot_mem_malloc -
+ *
+ * ARGUMENTS
+ * func -
+ * line -
+ * size -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+static void *ot_mem_malloc(FLT_OT_DBG_ARGS(const char *func, int line, ) size_t size)
+{
+ return flt_ot_pool_alloc(pool_head_ot_span_context, size, 1, NULL);
+}
+
+
+/***
+ * NAME
+ * ot_mem_free -
+ *
+ * ARGUMENTS
+ * func -
+ * line -
+ * ptr -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * This function does not return a value.
+ */
+static void ot_mem_free(FLT_OT_DBG_ARGS(const char *func, int line, ) void *ptr)
+{
+ flt_ot_pool_free(pool_head_ot_span_context, &ptr);
+}
+
+
+/***
+ * NAME
+ * ot_init -
+ *
+ * ARGUMENTS
+ * tracer -
+ * plugin -
+ * err -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_init(struct otc_tracer **tracer, const char *plugin, char **err)
+{
+ char cwd[PATH_MAX], path[PATH_MAX], errbuf[BUFSIZ] = "";
+ int rc, retval = -1;
+
+ FLT_OT_FUNC("%p:%p, \"%s\", %p:%p", FLT_OT_DPTR_ARGS(tracer), plugin, FLT_OT_DPTR_ARGS(err));
+
+ flt_ot_pools_info();
+#ifdef USE_POOL_OT_SPAN_CONTEXT
+ FLT_OT_DBG(2, "sizeof_pool(ot_span_context) = %u", pool_head_ot_span_context->size);
+#endif
+
+ if (getcwd(cwd, sizeof(cwd)) == NULL) {
+ FLT_OT_ERR("failed to get current working directory");
+
+ FLT_OT_RETURN_INT(retval);
+ }
+ rc = snprintf(path, sizeof(path), "%s/%s", cwd, plugin);
+ if ((rc == -1) || (rc >= sizeof(path))) {
+ FLT_OT_ERR("failed to construct the OpenTracing plugin path");
+
+ FLT_OT_RETURN_INT(retval);
+ }
+
+ *tracer = otc_tracer_load(path, errbuf, sizeof(errbuf));
+ if (*tracer == NULL) {
+ FLT_OT_ERR("%s", (*errbuf == '\0') ? "failed to initialize tracing library" : errbuf);
+ } else {
+ otc_ext_init(ot_mem_malloc, ot_mem_free);
+
+ retval = 0;
+ }
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_start -
+ *
+ * ARGUMENTS
+ * tracer -
+ * cfgbuf -
+ * err -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * This function does not return a value.
+ */
+int ot_start(struct otc_tracer *tracer, const char *cfgbuf, char **err)
+{
+ char errbuf[BUFSIZ] = "";
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, %p, %p:%p", tracer, cfgbuf, FLT_OT_DPTR_ARGS(err));
+
+ if (cfgbuf == NULL)
+ FLT_OT_RETURN_INT(retval);
+
+ retval = otc_tracer_start(NULL, cfgbuf, errbuf, sizeof(errbuf));
+ if (retval == -1)
+ FLT_OT_ERR("%s", (*errbuf == '\0') ? "failed to start tracer" : errbuf);
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_close -
+ *
+ * ARGUMENTS
+ * tracer -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * This function does not return a value.
+ */
+void ot_close(struct otc_tracer **tracer)
+{
+ FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(tracer));
+
+ if ((tracer == NULL) || (*tracer == NULL))
+ FLT_OT_RETURN();
+
+ (*tracer)->close(*tracer);
+
+ *tracer = NULL;
+
+ FLT_OT_RETURN();
+}
+
+
+/***
+ * NAME
+ * ot_span_init -
+ *
+ * ARGUMENTS
+ * tracer -
+ * operation_name -
+ * ts_steady -
+ * ts_system -
+ * ref_type -
+ * ref_ctx_idx -
+ * ref_span -
+ * tags -
+ * num_tags -
+ * err -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+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)
+{
+ struct otc_start_span_options options;
+ struct otc_span_context context = { .idx = ref_ctx_idx, .span = ref_span };
+ struct otc_span_reference references = { ref_type, &context };
+ struct otc_span *retptr = NULL;
+
+ 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));
+
+ if (operation_name == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ (void)memset(&options, 0, sizeof(options));
+
+ if (ts_steady != NULL)
+ (void)memcpy(&(options.start_time_steady.value), ts_steady, sizeof(options.start_time_steady.value));
+
+ if (ts_system != NULL)
+ (void)memcpy(&(options.start_time_system.value), ts_system, sizeof(options.start_time_system.value));
+
+ if (FLT_OT_IN_RANGE(ref_type, otc_span_reference_child_of, otc_span_reference_follows_from)) {
+ options.references = &references;
+ options.num_references = 1;
+ }
+
+ options.tags = tags;
+ options.num_tags = num_tags;
+
+ retptr = tracer->start_span_with_options(tracer, operation_name, &options);
+ if (retptr == NULL)
+ FLT_OT_ERR("failed to init new span");
+ else
+ FLT_OT_DBG(2, "span %p:%zd initialized", retptr, retptr->idx);
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_span_init_va -
+ *
+ * ARGUMENTS
+ * tracer -
+ * operation_name -
+ * ts_steady -
+ * ts_system -
+ * ref_type -
+ * ref_ctx_idx -
+ * ref_span -
+ * err -
+ * tag_key -
+ * tag_value -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+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, ...)
+{
+ struct otc_tag tags[FLT_OT_MAXTAGS];
+ int num_tags = 0;
+ struct otc_span *retptr;
+
+ 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);
+
+ if (tag_key != NULL) {
+ va_list ap;
+
+ va_start(ap, tag_value);
+ for (num_tags = 0; (num_tags < FLT_OT_TABLESIZE(tags)) && (tag_key != NULL) && (tag_value != NULL); num_tags++) {
+ tags[num_tags].key = (char *)tag_key;
+ FLT_OT_VSET(&(tags[num_tags].value), string, tag_value);
+
+ tag_key = va_arg(ap, typeof(tag_key));
+ if (tag_key != NULL)
+ tag_value = va_arg(ap, typeof(tag_value));
+ }
+ va_end(ap);
+ }
+
+ retptr = ot_span_init(tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, tags, num_tags, err);
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_span_tag -
+ *
+ * ARGUMENTS
+ * span -
+ * tags -
+ * num_tags -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_tag(struct otc_span *span, const struct otc_tag *tags, int num_tags)
+{
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, %p, %d", span, tags, num_tags);
+
+ if ((span == NULL) || (tags == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ for (retval = 0; retval < num_tags; retval++)
+ span->set_tag(span, tags[retval].key, &(tags[retval].value));
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_span_tag_va -
+ *
+ * ARGUMENTS
+ * span -
+ * key -
+ * type -
+ * value -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_tag_va(struct otc_span *span, const char *key, int type, ...)
+{
+ va_list ap;
+ struct otc_value ot_value;
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, \"%s\", %d, ...", span, key, type);
+
+ if ((span == NULL) || (key == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ va_start(ap, type);
+ for (retval = 0; (key != NULL) && FLT_OT_IN_RANGE(type, otc_value_bool, otc_value_null); retval++) {
+ ot_value.type = type;
+ if (type == otc_value_bool)
+ ot_value.value.bool_value = va_arg(ap, typeof(ot_value.value.bool_value));
+ else if (type == otc_value_double)
+ ot_value.value.double_value = va_arg(ap, typeof(ot_value.value.double_value));
+ else if (type == otc_value_int64)
+ ot_value.value.int64_value = va_arg(ap, typeof(ot_value.value.int64_value));
+ else if (type == otc_value_uint64)
+ ot_value.value.uint64_value = va_arg(ap, typeof(ot_value.value.uint64_value));
+ else if (type == otc_value_string)
+ ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value));
+ else if (type == otc_value_null)
+ ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value));
+ span->set_tag(span, key, &ot_value);
+
+ key = va_arg(ap, typeof(key));
+ if (key != NULL)
+ type = va_arg(ap, typeof(type));
+ }
+ va_end(ap);
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_span_log -
+ *
+ * ARGUMENTS
+ * span -
+ * log_fields -
+ * num_fields -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_log(struct otc_span *span, const struct otc_log_field *log_fields, int num_fields)
+{
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, %p, %d", span, log_fields, num_fields);
+
+ if ((span == NULL) || (log_fields == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ retval = MIN(OTC_MAXLOGFIELDS, num_fields);
+
+ span->log_fields(span, log_fields, retval);
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_span_log_va -
+ *
+ * ARGUMENTS
+ * span -
+ * key -
+ * value -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_log_va(struct otc_span *span, const char *key, const char *value, ...)
+{
+ va_list ap;
+ struct otc_log_field log_field[OTC_MAXLOGFIELDS];
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value);
+
+ if ((span == NULL) || (key == NULL) || (value == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ va_start(ap, value);
+ for (retval = 0; (retval < FLT_OT_TABLESIZE(log_field)) && (key != NULL); retval++) {
+ log_field[retval].key = key;
+ log_field[retval].value.type = otc_value_string;
+ log_field[retval].value.value.string_value = value;
+
+ key = va_arg(ap, typeof(key));
+ if (key != NULL)
+ value = va_arg(ap, typeof(value));
+ }
+ va_end(ap);
+
+ span->log_fields(span, log_field, retval);
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_span_log_fmt -
+ *
+ * ARGUMENTS
+ * span -
+ * key -
+ * format -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_log_fmt(struct otc_span *span, const char *key, const char *format, ...)
+{
+ va_list ap;
+ char value[BUFSIZ];
+ int n;
+
+ FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, format);
+
+ if ((span == NULL) || (key == NULL) || (format == NULL))
+ FLT_OT_RETURN_INT(-1);
+
+ va_start(ap, format);
+ n = vsnprintf(value, sizeof(value), format, ap);
+ if (!FLT_OT_IN_RANGE(n, 0, sizeof(value) - 1)) {
+ FLT_OT_DBG(2, "WARNING: log buffer too small (%d > %zu)", n, sizeof(value));
+
+ FLT_OT_STR_ELLIPSIS(value, sizeof(value));
+ }
+ va_end(ap);
+
+ FLT_OT_RETURN_INT(ot_span_log_va(span, key, value, NULL));
+}
+
+
+/***
+ * NAME
+ * ot_span_set_baggage -
+ *
+ * ARGUMENTS
+ * span -
+ * baggage -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_set_baggage(struct otc_span *span, const struct otc_text_map *baggage)
+{
+ size_t i;
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, %p", span, baggage);
+
+ if ((span == NULL) || (baggage == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ if ((baggage->key == NULL) || (baggage->value == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ for (retval = i = 0; i < baggage->count; i++) {
+ FLT_OT_DBG(3, "set baggage: \"%s\" -> \"%s\"", baggage->key[i], baggage->value[i]);
+
+ if ((baggage->key[i] != NULL) && (baggage->value[i] != NULL)) {
+ span->set_baggage_item(span, baggage->key[i], baggage->value[i]);
+
+ retval++;
+ }
+ }
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_span_set_baggage_va -
+ *
+ * ARGUMENTS
+ * span -
+ * key -
+ * value -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+int ot_span_set_baggage_va(struct otc_span *span, const char *key, const char *value, ...)
+{
+ va_list ap;
+ int retval = -1;
+
+ FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value);
+
+ if ((span == NULL) || (key == NULL) || (value == NULL))
+ FLT_OT_RETURN_INT(retval);
+
+ va_start(ap, value);
+ for (retval = 0; (key != NULL); retval++) {
+ FLT_OT_DBG(3, "set baggage: \"%s\" -> \"%s\"", key, value);
+
+ span->set_baggage_item(span, key, value);
+
+ key = va_arg(ap, typeof(key));
+ if (key != NULL)
+ value = va_arg(ap, typeof(value));
+ }
+ va_end(ap);
+
+ FLT_OT_RETURN_INT(retval);
+}
+
+
+/***
+ * NAME
+ * ot_span_baggage_va -
+ *
+ * ARGUMENTS
+ * span -
+ * key -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+struct otc_text_map *ot_span_baggage_va(const struct otc_span *span, const char *key, ...)
+{
+ va_list ap;
+ struct otc_text_map *retptr = NULL;
+ int i, n;
+
+ FLT_OT_FUNC("%p, \"%s\", ...", span, key);
+
+ if ((span == NULL) || (key == NULL))
+ FLT_OT_RETURN_PTR(retptr);
+
+ va_start(ap, key);
+ for (n = 1; va_arg(ap, typeof(key)) != NULL; n++);
+ va_end(ap);
+
+ retptr = otc_text_map_new(NULL, n);
+ if (retptr == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ va_start(ap, key);
+ for (i = 0; (i < n) && (key != NULL); i++) {
+ char *value = (char *)span->baggage_item(span, key);
+
+ if (value != NULL) {
+ (void)otc_text_map_add(retptr, key, 0, value, 0, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE);
+
+ FLT_OT_DBG(3, "get baggage[%d]: \"%s\" -> \"%s\"", i, retptr->key[i], retptr->value[i]);
+ } else {
+ FLT_OT_DBG(3, "get baggage[%d]: \"%s\" -> invalid key", i, key);
+ }
+
+ key = va_arg(ap, typeof(key));
+ }
+ va_end(ap);
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_inject_text_map -
+ *
+ * ARGUMENTS
+ * tracer -
+ * span -
+ * carrier -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+struct otc_span_context *ot_inject_text_map(struct otc_tracer *tracer, const struct otc_span *span, struct otc_text_map_writer *carrier)
+{
+ struct otc_span_context *retptr = NULL;
+ int rc;
+
+ FLT_OT_FUNC("%p, %p, %p", tracer, span, carrier);
+
+ if ((span == NULL) || (carrier == NULL))
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ retptr = span->span_context((struct otc_span *)span);
+ if (retptr == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ (void)memset(carrier, 0, sizeof(*carrier));
+
+ rc = tracer->inject_text_map(tracer, carrier, retptr);
+ if (rc != otc_propagation_error_code_success) {
+ FLT_OT_FREE_CLEAR(retptr);
+ } else {
+#ifdef DEBUG_OT
+ FLT_OT_DBG_TEXT_CARRIER(carrier, set);
+ ot_text_map_show(&(carrier->text_map));
+ FLT_OT_DBG_SPAN_CONTEXT(retptr);
+#endif
+ }
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_inject_http_headers -
+ *
+ * ARGUMENTS
+ * tracer -
+ * span -
+ * carrier -
+ * err -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+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)
+{
+ struct otc_span_context *retptr = NULL;
+ int rc;
+
+ FLT_OT_FUNC("%p, %p, %p, %p:%p", tracer, span, carrier, FLT_OT_DPTR_ARGS(err));
+
+ if ((span == NULL) || (carrier == NULL))
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ retptr = span->span_context((struct otc_span *)span);
+ if (retptr == NULL) {
+ FLT_OT_ERR("failed to create span context");
+
+ FLT_OT_RETURN_PTR(retptr);
+ }
+
+ (void)memset(carrier, 0, sizeof(*carrier));
+
+ rc = tracer->inject_http_headers(tracer, carrier, retptr);
+ if (rc != otc_propagation_error_code_success) {
+ FLT_OT_ERR("failed to inject HTTP headers data");
+
+ FLT_OT_FREE_CLEAR(retptr);
+ } else {
+#ifdef DEBUG_OT
+ FLT_OT_DBG_TEXT_CARRIER(carrier, set);
+ ot_text_map_show(&(carrier->text_map));
+ FLT_OT_DBG_SPAN_CONTEXT(retptr);
+#endif
+ }
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_inject_binary -
+ *
+ * ARGUMENTS
+ * tracer -
+ * span -
+ * carrier -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+struct otc_span_context *ot_inject_binary(struct otc_tracer *tracer, const struct otc_span *span, struct otc_custom_carrier_writer *carrier)
+{
+ struct otc_span_context *retptr = NULL;
+ int rc;
+
+ FLT_OT_FUNC("%p, %p, %p", tracer, span, carrier);
+
+ if ((span == NULL) || (carrier == NULL))
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ retptr = span->span_context((struct otc_span *)span);
+ if (retptr == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ (void)memset(carrier, 0, sizeof(*carrier));
+
+ rc = tracer->inject_binary(tracer, carrier, retptr);
+ if (rc != otc_propagation_error_code_success) {
+ FLT_OT_FREE_CLEAR(retptr);
+ } else {
+#ifdef DEBUG_OT
+ struct otc_jaeger_trace_context *ctx = carrier->binary_data.data;
+
+ FLT_OT_DBG_CUSTOM_CARRIER(carrier, inject);
+ FLT_OT_DBG(3, "trace context: %016" PRIx64 "%016" PRIx64 ":%016" PRIx64 ":%016" PRIx64 ":%02hhx <%s> <%s>",
+ ctx->trace_id[0], ctx->trace_id[1], ctx->span_id, ctx->parent_span_id, ctx->flags,
+ flt_ot_str_hex(ctx->baggage, carrier->binary_data.size - sizeof(*ctx)),
+ flt_ot_str_ctrl(ctx->baggage, carrier->binary_data.size - sizeof(*ctx)));
+ FLT_OT_DBG_SPAN_CONTEXT(retptr);
+#endif
+ }
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_extract_text_map -
+ *
+ * ARGUMENTS
+ * tracer -
+ * carrier -
+ * text_map -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+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)
+{
+ struct otc_span_context *retptr = NULL;
+ int rc;
+
+ FLT_OT_FUNC("%p, %p, %p", tracer, carrier, text_map);
+
+ if (carrier == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ if (text_map != NULL) {
+ (void)memset(carrier, 0, sizeof(*carrier));
+ (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map));
+
+ FLT_OT_DBG_TEXT_CARRIER(carrier, foreach_key);
+ }
+
+ rc = tracer->extract_text_map(tracer, carrier, &retptr);
+ if (rc != otc_propagation_error_code_success)
+ FLT_OT_FREE_CLEAR(retptr);
+ else if (retptr != NULL)
+ FLT_OT_DBG_SPAN_CONTEXT(retptr);
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_extract_http_headers -
+ *
+ * ARGUMENTS
+ * tracer -
+ * carrier -
+ * text_map -
+ * err -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+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)
+{
+ struct otc_span_context *retptr = NULL;
+ int rc;
+
+ FLT_OT_FUNC("%p, %p, %p, %p:%p", tracer, carrier, text_map, FLT_OT_DPTR_ARGS(err));
+
+ if (carrier == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ if (text_map != NULL) {
+ (void)memset(carrier, 0, sizeof(*carrier));
+ (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map));
+
+ FLT_OT_DBG_TEXT_CARRIER(carrier, foreach_key);
+ }
+
+ rc = tracer->extract_http_headers(tracer, carrier, &retptr);
+ if (rc != otc_propagation_error_code_success) {
+ FLT_OT_ERR("failed to extract HTTP headers data");
+
+ FLT_OT_FREE_CLEAR(retptr);
+ }
+ else if (retptr != NULL)
+ FLT_OT_DBG_SPAN_CONTEXT(retptr);
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_extract_binary -
+ *
+ * ARGUMENTS
+ * tracer -
+ * carrier -
+ * binary_data -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * -
+ */
+struct otc_span_context *ot_extract_binary(struct otc_tracer *tracer, struct otc_custom_carrier_reader *carrier, const struct otc_binary_data *binary_data)
+{
+ struct otc_span_context *retptr = NULL;
+ int rc;
+
+ FLT_OT_FUNC("%p, %p, %p", tracer, carrier, binary_data);
+
+ if (carrier == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+ else if (tracer == NULL)
+ FLT_OT_RETURN_PTR(retptr);
+
+ if ((FLT_OT_DEREF(binary_data, data, NULL) != NULL) && (binary_data->size > 0)) {
+ (void)memset(carrier, 0, sizeof(*carrier));
+ (void)memcpy(&(carrier->binary_data), binary_data, sizeof(carrier->binary_data));
+
+ FLT_OT_DBG_CUSTOM_CARRIER(carrier, extract);
+ }
+
+ rc = tracer->extract_binary(tracer, carrier, &retptr);
+ if (rc != otc_propagation_error_code_success)
+ FLT_OT_FREE_CLEAR(retptr);
+ else if (retptr != NULL)
+ FLT_OT_DBG_SPAN_CONTEXT(retptr);
+
+ FLT_OT_RETURN_PTR(retptr);
+}
+
+
+/***
+ * NAME
+ * ot_span_finish -
+ *
+ * ARGUMENTS
+ * span -
+ * ts_finish -
+ * log_ts -
+ * log_key -
+ * log_value -
+ *
+ * DESCRIPTION
+ * -
+ *
+ * RETURN VALUE
+ * This function does not return a value.
+ */
+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, ...)
+{
+ struct otc_finish_span_options options;
+ struct otc_log_field log_field[OTC_MAXLOGFIELDS];
+ struct otc_log_record log_records = { .fields = log_field, .num_fields = 0 };
+#ifdef DEBUG_OT
+ typeof((*span)->idx) idx = FLT_OT_DDEREF(span, idx, 0);
+#endif
+
+ FLT_OT_FUNC("%p:%p, %p, %p, \"%s\", \"%s\", ...", FLT_OT_DPTR_ARGS(span), ts_finish, log_ts, log_key, log_value);
+
+ if ((span == NULL) || (*span == NULL))
+ FLT_OT_RETURN();
+
+ (void)memset(&options, 0, sizeof(options));
+
+ if (ts_finish != NULL)
+ (void)memcpy(&(options.finish_time.value), ts_finish, sizeof(options.finish_time.value));
+
+ if (log_key != NULL) {
+ va_list ap;
+ int i;
+
+ if (log_ts != NULL)
+ (void)memcpy(&(log_records.timestamp.value), log_ts, sizeof(log_records.timestamp.value));
+
+ va_start(ap, log_value);
+ for (i = 0; (i < FLT_OT_TABLESIZE(log_field)) && (log_key != NULL); i++) {
+ log_field[i].key = log_key;
+ log_field[i].value.type = otc_value_string;
+ log_field[i].value.value.string_value = log_value;
+
+ log_key = va_arg(ap, typeof(log_key));
+ if (log_key != NULL)
+ log_value = va_arg(ap, typeof(log_value));
+ }
+ va_end(ap);
+
+ log_records.num_fields = i;
+ options.log_records = &log_records;
+ options.num_log_records = 1;
+ }
+
+ /*
+ * Caution: memory allocated for the span is released
+ * in the function finish_with_options().
+ */
+ (*span)->finish_with_options(*span, &options);
+
+ FLT_OT_DBG(2, "span %p:%zu finished", *span, idx);
+
+ *span = NULL;
+
+ FLT_OT_RETURN();
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * End:
+ *
+ * vi: noexpandtab shiftwidth=8 tabstop=8
+ */