Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/opentelemetry/flb_opentelemetry_logs.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,18 +293,18 @@ static int process_json_payload_log_records_entry(
result = flb_otel_utils_json_payload_append_converted_kvlist(encoder, FLB_LOG_EVENT_METADATA, metadata_object);
}

if (trace_id != NULL) {
flb_otel_utils_hex_to_id(trace_id->via.str.ptr, trace_id->via.str.size, tmp_id, 32);
if (trace_id != NULL && trace_id->type == MSGPACK_OBJECT_STR && trace_id->via.str.size == 32) {
flb_otel_utils_hex_to_id(trace_id->via.str.ptr, trace_id->via.str.size, tmp_id, 16);
flb_log_event_encoder_append_metadata_values(encoder,
FLB_LOG_EVENT_STRING_VALUE("trace_id", 8),
FLB_LOG_EVENT_BINARY_VALUE(tmp_id, 32));
FLB_LOG_EVENT_BINARY_VALUE(tmp_id, 16));
}

if (span_id != NULL) {
flb_otel_utils_hex_to_id(span_id->via.str.ptr, span_id->via.str.size, tmp_id, 16);
if (span_id != NULL && span_id->type == MSGPACK_OBJECT_STR && span_id->via.str.size == 16) {
flb_otel_utils_hex_to_id(span_id->via.str.ptr, span_id->via.str.size, tmp_id, 8);
flb_log_event_encoder_append_metadata_values(encoder,
FLB_LOG_EVENT_STRING_VALUE("span_id", 7),
FLB_LOG_EVENT_BINARY_VALUE(tmp_id, 16));
FLB_LOG_EVENT_BINARY_VALUE(tmp_id, 8));
}

result = flb_log_event_encoder_commit_map(encoder, FLB_LOG_EVENT_METADATA);
Expand Down
92 changes: 92 additions & 0 deletions tests/internal/opentelemetry.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <fluent-bit/flb_pack.h>
#include <fluent-bit/flb_sds.h>
#include <fluent-bit/flb_mem.h>
#include <fluent-bit/flb_record_accessor.h>
#include <fluent-bit/flb_ra_key.h>

// #include "../../plugins/in_opentelemetry/opentelemetry.h"
#include <fluent-bit/flb_opentelemetry.h>
Expand Down Expand Up @@ -735,13 +737,103 @@ void test_opentelemetry_cases()
flb_free(cases_json);
}

void test_trace_span_binary_sizes()
{
int ret;
struct flb_log_event_encoder enc;
struct flb_log_event_decoder dec;
struct flb_log_event event;
int32_t record_type;
char *input_json;
int error_status = 0;
int found_trace_id = 0;
int found_span_id = 0;
size_t trace_id_size = 0;
size_t span_id_size = 0;
struct flb_record_accessor *ra_trace_id;
struct flb_record_accessor *ra_span_id;
struct flb_ra_value *val_trace_id;
struct flb_ra_value *val_span_id;
size_t len;

/* Test input with trace_id and span_id */
input_json = "{\"resourceLogs\":[{\"scopeLogs\":[{\"logRecords\":[{\"timeUnixNano\":\"1640995200000000000\",\"traceId\":\"5B8EFFF798038103D269B633813FC60C\",\"spanId\":\"EEE19B7EC3C1B174\",\"body\":{\"stringValue\":\"test\"}}]}]}]}";

ret = flb_log_event_encoder_init(&enc, FLB_LOG_EVENT_FORMAT_FLUENT_BIT_V2);
TEST_CHECK(ret == FLB_EVENT_ENCODER_SUCCESS);

ret = flb_opentelemetry_logs_json_to_msgpack(&enc, input_json, strlen(input_json), NULL, &error_status);
TEST_CHECK(ret == 0);

/* Create record accessors for trace_id and span_id */
ra_trace_id = flb_ra_create("$otlp['trace_id']", FLB_FALSE);
TEST_CHECK(ra_trace_id != NULL);

ra_span_id = flb_ra_create("$otlp['span_id']", FLB_FALSE);
TEST_CHECK(ra_span_id != NULL);

/* Decode the output to check binary sizes */
ret = flb_log_event_decoder_init(&dec, enc.output_buffer, enc.output_length);
TEST_CHECK(ret == FLB_EVENT_DECODER_SUCCESS);

flb_log_event_decoder_read_groups(&dec, FLB_TRUE);

while ((ret = flb_log_event_decoder_next(&dec, &event)) == FLB_EVENT_DECODER_SUCCESS) {
ret = flb_log_event_decoder_get_record_type(&event, &record_type);
TEST_CHECK(ret == 0);

if (record_type == FLB_LOG_EVENT_NORMAL) {
/* Use record accessor to get trace_id */
val_trace_id = flb_ra_get_value_object(ra_trace_id, *event.metadata);
if (val_trace_id != NULL) {
found_trace_id = 1;
if (val_trace_id->type == FLB_RA_BINARY) {
trace_id_size = flb_sds_len(val_trace_id->val.binary);
printf("Found trace_id with binary size: %zu\n", trace_id_size);
/* trace_id should be 16 bytes (32 hex chars = 16 bytes) */
TEST_CHECK_(trace_id_size == 16, "trace_id binary size should be 16, got %zu", trace_id_size);
}
else if (val_trace_id->type == FLB_RA_STRING) {
printf("Found trace_id as string: %s\n", val_trace_id->val.string);
}
flb_ra_key_value_destroy(val_trace_id);
}

/* Use record accessor to get span_id */
val_span_id = flb_ra_get_value_object(ra_span_id, *event.metadata);
if (val_span_id != NULL) {
found_span_id = 1;
if (val_span_id->type == FLB_RA_BINARY) {
span_id_size = flb_sds_len(val_span_id->val.binary);
printf("Found span_id with binary size: %zu\n", span_id_size);
/* span_id should be 8 bytes (16 hex chars = 8 bytes) */
TEST_CHECK_(span_id_size == 8, "span_id binary size should be 8, got %zu", span_id_size);
}
else if (val_span_id->type == FLB_RA_STRING) {
printf("Found span_id as string: %s\n", val_span_id->val.string);
}
flb_ra_key_value_destroy(val_span_id);
}
}
}

flb_log_event_decoder_destroy(&dec);
flb_log_event_encoder_destroy(&enc);
flb_ra_destroy(ra_trace_id);
flb_ra_destroy(ra_span_id);

TEST_CHECK(found_trace_id == 1);
TEST_CHECK(found_span_id == 1);
}
Comment on lines +740 to +827
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Strengthen the test: enforce binary type and verify the exact bytes, not only the lengths.

Today the test passes if IDs show up as strings. Given the PR fixes packaging to 16/8-byte binaries, assert type == FLB_RA_BINARY and bytes match the hex source. Also prefer const for the JSON literal.

Apply this diff:

 void test_trace_span_binary_sizes()
 {
     int ret;
     struct flb_log_event_encoder enc;
     struct flb_log_event_decoder dec;
     struct flb_log_event event;
     int32_t record_type;
-    char *input_json;
+    const char *input_json;
     int error_status = 0;
     int found_trace_id = 0;
     int found_span_id = 0;
     size_t trace_id_size = 0;
     size_t span_id_size = 0;
     struct flb_record_accessor *ra_trace_id;
     struct flb_record_accessor *ra_span_id;
     struct flb_ra_value *val_trace_id;
     struct flb_ra_value *val_span_id;
-    size_t len;
+    unsigned char expected_trace_id[16];
+    unsigned char expected_span_id[8];
+    const char *trace_hex = "5B8EFFF798038103D269B633813FC60C";
+    const char *span_hex  = "EEE19B7EC3C1B174";
 
     /* Test input with trace_id and span_id */
     input_json = "{\"resourceLogs\":[{\"scopeLogs\":[{\"logRecords\":[{\"timeUnixNano\":\"1640995200000000000\",\"traceId\":\"5B8EFFF798038103D269B633813FC60C\",\"spanId\":\"EEE19B7EC3C1B174\",\"body\":{\"stringValue\":\"test\"}}]}]}]}";
 
     ret = flb_log_event_encoder_init(&enc, FLB_LOG_EVENT_FORMAT_FLUENT_BIT_V2);
     TEST_CHECK(ret == FLB_EVENT_ENCODER_SUCCESS);
 
     ret = flb_opentelemetry_logs_json_to_msgpack(&enc, input_json, strlen(input_json), NULL, &error_status);
     TEST_CHECK(ret == 0);
+    TEST_CHECK(error_status == 0);
+
+    /* Prepare expected binary bytes from hex */
+    ret = flb_otel_utils_hex_to_id(trace_hex, 32, expected_trace_id, sizeof(expected_trace_id));
+    TEST_CHECK(ret == 0);
+    ret = flb_otel_utils_hex_to_id(span_hex, 16, expected_span_id, sizeof(expected_span_id));
+    TEST_CHECK(ret == 0);
 
     /* Create record accessors for trace_id and span_id */
     ra_trace_id = flb_ra_create("$otlp['trace_id']", FLB_FALSE);
     TEST_CHECK(ra_trace_id != NULL);
 
     ra_span_id = flb_ra_create("$otlp['span_id']", FLB_FALSE);
     TEST_CHECK(ra_span_id != NULL);
@@
             /* Use record accessor to get trace_id */
             val_trace_id = flb_ra_get_value_object(ra_trace_id, *event.metadata);
             if (val_trace_id != NULL) {
                 found_trace_id = 1;
-                if (val_trace_id->type == FLB_RA_BINARY) {
+                TEST_CHECK_(val_trace_id->type == FLB_RA_BINARY, "trace_id must be emitted as binary");
+                if (val_trace_id->type == FLB_RA_BINARY) {
                     trace_id_size = flb_sds_len(val_trace_id->val.binary);
                     printf("Found trace_id with binary size: %zu\n", trace_id_size);
                     /* trace_id should be 16 bytes (32 hex chars = 16 bytes) */
                     TEST_CHECK_(trace_id_size == 16, "trace_id binary size should be 16, got %zu", trace_id_size);
+                    TEST_CHECK_(memcmp(expected_trace_id, val_trace_id->val.binary, 16) == 0,
+                                "trace_id binary content mismatch");
                 }
-                else if (val_trace_id->type == FLB_RA_STRING) {
-                    printf("Found trace_id as string: %s\n", val_trace_id->val.string);
-                }
                 flb_ra_key_value_destroy(val_trace_id);
             }
 
             /* Use record accessor to get span_id */
             val_span_id = flb_ra_get_value_object(ra_span_id, *event.metadata);
             if (val_span_id != NULL) {
                 found_span_id = 1;
-                if (val_span_id->type == FLB_RA_BINARY) {
+                TEST_CHECK_(val_span_id->type == FLB_RA_BINARY, "span_id must be emitted as binary");
+                if (val_span_id->type == FLB_RA_BINARY) {
                     span_id_size = flb_sds_len(val_span_id->val.binary);
                     printf("Found span_id with binary size: %zu\n", span_id_size);
                     /* span_id should be 8 bytes (16 hex chars = 8 bytes) */
                     TEST_CHECK_(span_id_size == 8, "span_id binary size should be 8, got %zu", span_id_size);
+                    TEST_CHECK_(memcmp(expected_span_id, val_span_id->val.binary, 8) == 0,
+                                "span_id binary content mismatch");
                 }
-                else if (val_span_id->type == FLB_RA_STRING) {
-                    printf("Found span_id as string: %s\n", val_span_id->val.string);
-                }
                 flb_ra_key_value_destroy(val_span_id);
             }
         }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void test_trace_span_binary_sizes()
{
int ret;
struct flb_log_event_encoder enc;
struct flb_log_event_decoder dec;
struct flb_log_event event;
int32_t record_type;
char *input_json;
int error_status = 0;
int found_trace_id = 0;
int found_span_id = 0;
size_t trace_id_size = 0;
size_t span_id_size = 0;
struct flb_record_accessor *ra_trace_id;
struct flb_record_accessor *ra_span_id;
struct flb_ra_value *val_trace_id;
struct flb_ra_value *val_span_id;
size_t len;
/* Test input with trace_id and span_id */
input_json = "{\"resourceLogs\":[{\"scopeLogs\":[{\"logRecords\":[{\"timeUnixNano\":\"1640995200000000000\",\"traceId\":\"5B8EFFF798038103D269B633813FC60C\",\"spanId\":\"EEE19B7EC3C1B174\",\"body\":{\"stringValue\":\"test\"}}]}]}]}";
ret = flb_log_event_encoder_init(&enc, FLB_LOG_EVENT_FORMAT_FLUENT_BIT_V2);
TEST_CHECK(ret == FLB_EVENT_ENCODER_SUCCESS);
ret = flb_opentelemetry_logs_json_to_msgpack(&enc, input_json, strlen(input_json), NULL, &error_status);
TEST_CHECK(ret == 0);
/* Create record accessors for trace_id and span_id */
ra_trace_id = flb_ra_create("$otlp['trace_id']", FLB_FALSE);
TEST_CHECK(ra_trace_id != NULL);
ra_span_id = flb_ra_create("$otlp['span_id']", FLB_FALSE);
TEST_CHECK(ra_span_id != NULL);
/* Decode the output to check binary sizes */
ret = flb_log_event_decoder_init(&dec, enc.output_buffer, enc.output_length);
TEST_CHECK(ret == FLB_EVENT_DECODER_SUCCESS);
flb_log_event_decoder_read_groups(&dec, FLB_TRUE);
while ((ret = flb_log_event_decoder_next(&dec, &event)) == FLB_EVENT_DECODER_SUCCESS) {
ret = flb_log_event_decoder_get_record_type(&event, &record_type);
TEST_CHECK(ret == 0);
if (record_type == FLB_LOG_EVENT_NORMAL) {
/* Use record accessor to get trace_id */
val_trace_id = flb_ra_get_value_object(ra_trace_id, *event.metadata);
if (val_trace_id != NULL) {
found_trace_id = 1;
if (val_trace_id->type == FLB_RA_BINARY) {
trace_id_size = flb_sds_len(val_trace_id->val.binary);
printf("Found trace_id with binary size: %zu\n", trace_id_size);
/* trace_id should be 16 bytes (32 hex chars = 16 bytes) */
TEST_CHECK_(trace_id_size == 16, "trace_id binary size should be 16, got %zu", trace_id_size);
}
else if (val_trace_id->type == FLB_RA_STRING) {
printf("Found trace_id as string: %s\n", val_trace_id->val.string);
}
flb_ra_key_value_destroy(val_trace_id);
}
/* Use record accessor to get span_id */
val_span_id = flb_ra_get_value_object(ra_span_id, *event.metadata);
if (val_span_id != NULL) {
found_span_id = 1;
if (val_span_id->type == FLB_RA_BINARY) {
span_id_size = flb_sds_len(val_span_id->val.binary);
printf("Found span_id with binary size: %zu\n", span_id_size);
/* span_id should be 8 bytes (16 hex chars = 8 bytes) */
TEST_CHECK_(span_id_size == 8, "span_id binary size should be 8, got %zu", span_id_size);
}
else if (val_span_id->type == FLB_RA_STRING) {
printf("Found span_id as string: %s\n", val_span_id->val.string);
}
flb_ra_key_value_destroy(val_span_id);
}
}
}
flb_log_event_decoder_destroy(&dec);
flb_log_event_encoder_destroy(&enc);
flb_ra_destroy(ra_trace_id);
flb_ra_destroy(ra_span_id);
TEST_CHECK(found_trace_id == 1);
TEST_CHECK(found_span_id == 1);
}
void test_trace_span_binary_sizes()
{
int ret;
struct flb_log_event_encoder enc;
struct flb_log_event_decoder dec;
struct flb_log_event event;
int32_t record_type;
const char *input_json;
int error_status = 0;
int found_trace_id = 0;
int found_span_id = 0;
size_t trace_id_size = 0;
size_t span_id_size = 0;
struct flb_record_accessor *ra_trace_id;
struct flb_record_accessor *ra_span_id;
struct flb_ra_value *val_trace_id;
struct flb_ra_value *val_span_id;
unsigned char expected_trace_id[16];
unsigned char expected_span_id[8];
const char *trace_hex = "5B8EFFF798038103D269B633813FC60C";
const char *span_hex = "EEE19B7EC3C1B174";
/* Test input with trace_id and span_id */
input_json = "{\"resourceLogs\":[{\"scopeLogs\":[{\"logRecords\":[{\"timeUnixNano\":\"1640995200000000000\",\"traceId\":\"5B8EFFF798038103D269B633813FC60C\",\"spanId\":\"EEE19B7EC3C1B174\",\"body\":{\"stringValue\":\"test\"}}]}]}]}";
ret = flb_log_event_encoder_init(&enc, FLB_LOG_EVENT_FORMAT_FLUENT_BIT_V2);
TEST_CHECK(ret == FLB_EVENT_ENCODER_SUCCESS);
ret = flb_opentelemetry_logs_json_to_msgpack(&enc, input_json, strlen(input_json), NULL, &error_status);
TEST_CHECK(ret == 0);
TEST_CHECK(error_status == 0);
/* Prepare expected binary bytes from hex */
ret = flb_otel_utils_hex_to_id(trace_hex, 32, expected_trace_id, sizeof(expected_trace_id));
TEST_CHECK(ret == 0);
ret = flb_otel_utils_hex_to_id(span_hex, 16, expected_span_id, sizeof(expected_span_id));
TEST_CHECK(ret == 0);
/* Create record accessors for trace_id and span_id */
ra_trace_id = flb_ra_create("$otlp['trace_id']", FLB_FALSE);
TEST_CHECK(ra_trace_id != NULL);
ra_span_id = flb_ra_create("$otlp['span_id']", FLB_FALSE);
TEST_CHECK(ra_span_id != NULL);
/* Decode the output to check binary sizes */
ret = flb_log_event_decoder_init(&dec, enc.output_buffer, enc.output_length);
TEST_CHECK(ret == FLB_EVENT_DECODER_SUCCESS);
flb_log_event_decoder_read_groups(&dec, FLB_TRUE);
while ((ret = flb_log_event_decoder_next(&dec, &event)) == FLB_EVENT_DECODER_SUCCESS) {
ret = flb_log_event_decoder_get_record_type(&event, &record_type);
TEST_CHECK(ret == 0);
if (record_type == FLB_LOG_EVENT_NORMAL) {
/* Use record accessor to get trace_id */
val_trace_id = flb_ra_get_value_object(ra_trace_id, *event.metadata);
if (val_trace_id != NULL) {
found_trace_id = 1;
TEST_CHECK_(val_trace_id->type == FLB_RA_BINARY, "trace_id must be emitted as binary");
if (val_trace_id->type == FLB_RA_BINARY) {
trace_id_size = flb_sds_len(val_trace_id->val.binary);
printf("Found trace_id with binary size: %zu\n", trace_id_size);
/* trace_id should be 16 bytes (32 hex chars = 16 bytes) */
TEST_CHECK_(trace_id_size == 16, "trace_id binary size should be 16, got %zu", trace_id_size);
TEST_CHECK_(memcmp(expected_trace_id, val_trace_id->val.binary, 16) == 0,
"trace_id binary content mismatch");
}
flb_ra_key_value_destroy(val_trace_id);
}
/* Use record accessor to get span_id */
val_span_id = flb_ra_get_value_object(ra_span_id, *event.metadata);
if (val_span_id != NULL) {
found_span_id = 1;
TEST_CHECK_(val_span_id->type == FLB_RA_BINARY, "span_id must be emitted as binary");
if (val_span_id->type == FLB_RA_BINARY) {
span_id_size = flb_sds_len(val_span_id->val.binary);
printf("Found span_id with binary size: %zu\n", span_id_size);
/* span_id should be 8 bytes (16 hex chars = 8 bytes) */
TEST_CHECK_(span_id_size == 8, "span_id binary size should be 8, got %zu", span_id_size);
TEST_CHECK_(memcmp(expected_span_id, val_span_id->val.binary, 8) == 0,
"span_id binary content mismatch");
}
flb_ra_key_value_destroy(val_span_id);
}
}
}
flb_log_event_decoder_destroy(&dec);
flb_log_event_encoder_destroy(&enc);
flb_ra_destroy(ra_trace_id);
flb_ra_destroy(ra_span_id);
TEST_CHECK(found_trace_id == 1);
TEST_CHECK(found_span_id == 1);
}


/* Test list */
TEST_LIST = {
{ "hex_to_id", test_hex_to_id },
{ "convert_string_number_to_u64", test_convert_string_number_to_u64 },
{ "find_map_entry_by_key", test_find_map_entry_by_key },
{ "json_payload_get_wrapped_value", test_json_payload_get_wrapped_value },
{ "opentelemetry_cases", test_opentelemetry_cases },
{ "trace_span_binary_sizes", test_trace_span_binary_sizes },
{ 0 }
};

Loading