mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-12 14:31:00 +01:00
This patch solves the problem reported in github issue #1204, where the OpenTracing filter cannot communicate with the selected tracer if HAProxy is run in daemon mode. This commit also solves github issue #1274, where the problem manifests itself when using the 'chroot' keyword in the HAProxy configuration. This is solved so that the initialization of the OpenTracing plugin is split into two operations, first the plugin (dynamic library) is loaded before switching the HAProxy to daemon mode (or chroot) and then the tracer thread is started. This means that nothing is retrieved from the file system in runtime. After applying this commit, opentracing C wrapper version 1.1.0 should be used because the earlier version does not have separated initialization functions. This resolves GitHub issues #1204 and #1274.
1068 lines
23 KiB
C
1068 lines
23 KiB
C
/***
|
|
* 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(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(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(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(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(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(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(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(retval);
|
|
|
|
for (retval = 0; retval < num_tags; retval++)
|
|
span->set_tag(span, tags[retval].key, &(tags[retval].value));
|
|
|
|
FLT_OT_RETURN(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(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(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(retval);
|
|
|
|
retval = MIN(OTC_MAXLOGFIELDS, num_fields);
|
|
|
|
span->log_fields(span, log_fields, retval);
|
|
|
|
FLT_OT_RETURN(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(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(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(-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(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(retval);
|
|
|
|
if ((baggage->key == NULL) || (baggage->value == NULL))
|
|
FLT_OT_RETURN(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(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(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(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(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(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(retptr);
|
|
|
|
retptr = span->span_context((struct otc_span *)span);
|
|
if (retptr == NULL)
|
|
FLT_OT_RETURN(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(retptr);
|
|
|
|
retptr = span->span_context((struct otc_span *)span);
|
|
if (retptr == NULL) {
|
|
FLT_OT_ERR("failed to create span context");
|
|
|
|
FLT_OT_RETURN(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(retptr);
|
|
|
|
retptr = span->span_context((struct otc_span *)span);
|
|
if (retptr == NULL)
|
|
FLT_OT_RETURN(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(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(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(retptr);
|
|
else if (tracer == NULL)
|
|
FLT_OT_RETURN(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(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
|
|
*/
|