diff --git a/lib/ctraces/CMakeLists.txt b/lib/ctraces/CMakeLists.txt index 3cef9282fe2..e92834e0611 100644 --- a/lib/ctraces/CMakeLists.txt +++ b/lib/ctraces/CMakeLists.txt @@ -27,7 +27,7 @@ endif() # CTraces Version set(CTR_VERSION_MAJOR 0) set(CTR_VERSION_MINOR 5) -set(CTR_VERSION_PATCH 5) +set(CTR_VERSION_PATCH 6) set(CTR_VERSION_STR "${CTR_VERSION_MAJOR}.${CTR_VERSION_MINOR}.${CTR_VERSION_PATCH}") # Define __FILENAME__ consistently across Operating Systems diff --git a/lib/ctraces/src/ctr_encode_opentelemetry.c b/lib/ctraces/src/ctr_encode_opentelemetry.c index 8f0c81ed0bb..8a78f81a7fc 100644 --- a/lib/ctraces/src/ctr_encode_opentelemetry.c +++ b/lib/ctraces/src/ctr_encode_opentelemetry.c @@ -20,6 +20,9 @@ #include #include +static void destroy_scope_spans(Opentelemetry__Proto__Trace__V1__ScopeSpans **scope_spans, + size_t count); + static inline Opentelemetry__Proto__Common__V1__AnyValue *ctr_variant_to_otlp_any_value(struct cfl_variant *value); static inline Opentelemetry__Proto__Common__V1__KeyValue *ctr_variant_kvpair_to_otlp_kvpair(struct cfl_kvpair *input_pair); static inline Opentelemetry__Proto__Common__V1__AnyValue *ctr_variant_kvlist_to_otlp_any_value(struct cfl_variant *value); @@ -914,11 +917,21 @@ static Opentelemetry__Proto__Common__V1__InstrumentationScope *set_instrumentati return NULL; } - otel_scope->name = instrumentation_scope->name; - otel_scope->version = instrumentation_scope->version; + if (instrumentation_scope->name) { + otel_scope->name = instrumentation_scope->name; + } + else { + otel_scope->name = ""; + } + if (instrumentation_scope->version) { + otel_scope->version = instrumentation_scope->version; + } + else { + otel_scope->version = ""; + } otel_scope->n_attributes = get_attributes_count(instrumentation_scope->attr); otel_scope->dropped_attributes_count = instrumentation_scope->dropped_attr_count; - otel_scope->attributes = set_attributes_from_ctr(instrumentation_scope->attr);; + otel_scope->attributes = set_attributes_from_ctr(instrumentation_scope->attr); return otel_scope; } @@ -976,11 +989,19 @@ static Opentelemetry__Proto__Trace__V1__ScopeSpans **set_scope_spans(struct ctra otel_scope_span = initialize_scope_span(); if (!otel_scope_span) { + if (scope_span_index > 0) { + destroy_scope_spans(scope_spans, scope_span_index - 1); + } + + free(scope_spans); + return NULL; } otel_scope_span->schema_url = scope_span->schema_url; - otel_scope_span->scope = set_instrumentation_scope(scope_span->instrumentation_scope); + if (scope_span->instrumentation_scope != NULL) { + otel_scope_span->scope = set_instrumentation_scope(scope_span->instrumentation_scope); + } span_count = cfl_list_size(&scope_span->spans); otel_scope_span->n_spans = span_count; diff --git a/lib/ctraces/tests/decoding.c b/lib/ctraces/tests/decoding.c index e798f15389a..4e4a9a45453 100644 --- a/lib/ctraces/tests/decoding.c +++ b/lib/ctraces/tests/decoding.c @@ -429,6 +429,81 @@ static struct ctrace *generate_encoder_test_data() return context; } +static int generate_sample_resource_minimal_attributes(struct ctrace_resource *resource) +{ + struct ctrace_attributes *attributes; + int result; + + attributes = ctr_attributes_create(); + + if (attributes == NULL) { + return -1; + } + + result = ctr_attributes_set_string(attributes, "receiver.tool", "ctraces"); + + if (result != 0) { + ctr_attributes_destroy(attributes); + + return -2; + } + + result = ctr_resource_set_attributes(resource, attributes); + + if (result != 0) { + ctr_attributes_destroy(attributes); + + return -3; + } + + return 0; +} + +static struct ctrace *generate_encoder_test_data_with_empty_spans() +{ + struct ctrace_resource_span *resource_span; + struct ctrace_scope_span *scope_span; + struct ctrace *context; + int result; + + context = ctr_create(NULL); + + if (context == NULL) { + return NULL; + } + + resource_span = ctr_resource_span_create(context); + + if (resource_span == NULL) { + ctr_destroy(context); + + return NULL; + } + + ctr_resource_span_set_schema_url(resource_span, ""); + ctr_resource_set_dropped_attr_count(resource_span->resource, 0); + + result = generate_sample_resource_minimal_attributes(resource_span->resource); + + if (result != 0) { + ctr_destroy(context); + + return NULL; + } + + scope_span = ctr_scope_span_create(resource_span); + + if (scope_span == NULL) { + ctr_destroy(context); + + return NULL; + } + + ctr_scope_span_set_schema_url(scope_span, ""); + + return context; +} + /* * perform the following and then compare text buffers * @@ -483,6 +558,24 @@ void test_msgpack_to_cmt() ctr_destroy(context); } +void test_msgpack_to_ctr_with_empty_spans() +{ + struct ctrace *context; + char *referece_text_buffer; + + context = generate_encoder_test_data_with_empty_spans(); + TEST_ASSERT(context != NULL); + + referece_text_buffer = ctr_encode_text_create(context); + TEST_ASSERT(referece_text_buffer != NULL); + + printf("%s\n", referece_text_buffer); + msgpack_encode_decode_and_compare(context); + + ctr_encode_text_destroy(referece_text_buffer); + ctr_destroy(context); +} + void test_simple_to_msgpack_and_back() { struct ctrace *ctx; @@ -640,5 +733,6 @@ void test_simple_to_msgpack_and_back() TEST_LIST = { {"cmt_simple_to_msgpack_and_back", test_simple_to_msgpack_and_back}, {"cmt_msgpack", test_msgpack_to_cmt}, + {"empty_spans", test_msgpack_to_ctr_with_empty_spans}, { 0 } };