Coverage Report

Created: 2026-03-09 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/plugins/out_opentelemetry/opentelemetry_utils.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  Fluent Bit
4
 *  ==========
5
 *  Copyright (C) 2015-2026 The Fluent Bit Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#include <fluent-bit/flb_output_plugin.h>
21
#include <fluent-otel-proto/fluent-otel.h>
22
23
#include "opentelemetry_utils.h"
24
25
Opentelemetry__Proto__Common__V1__ArrayValue *otlp_array_value_initialize(size_t entry_count)
26
0
{
27
0
    Opentelemetry__Proto__Common__V1__ArrayValue *value;
28
29
0
    value = flb_calloc(1, sizeof(Opentelemetry__Proto__Common__V1__ArrayValue));
30
31
0
    if (value != NULL) {
32
0
        opentelemetry__proto__common__v1__array_value__init(value);
33
34
0
        if (entry_count > 0) {
35
0
            value->values = \
36
0
                flb_calloc(entry_count,
37
0
                       sizeof(Opentelemetry__Proto__Common__V1__AnyValue *));
38
39
0
            if (value->values == NULL) {
40
0
                flb_free(value);
41
42
0
                value = NULL;
43
0
            }
44
0
            else {
45
0
                value->n_values = entry_count;
46
0
            }
47
0
        }
48
0
    }
49
50
0
    return value;
51
0
}
52
53
Opentelemetry__Proto__Common__V1__KeyValue *otlp_kvpair_value_initialize()
54
0
{
55
0
    Opentelemetry__Proto__Common__V1__KeyValue *value;
56
57
0
    value = flb_calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue));
58
59
0
    if (value != NULL) {
60
0
        opentelemetry__proto__common__v1__key_value__init(value);
61
0
    }
62
63
0
    return value;
64
0
}
65
66
Opentelemetry__Proto__Common__V1__KeyValueList *otlp_kvlist_value_initialize(size_t entry_count)
67
0
{
68
0
    Opentelemetry__Proto__Common__V1__KeyValueList *value;
69
70
0
    value = flb_calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValueList));
71
72
0
    if (value != NULL) {
73
0
        opentelemetry__proto__common__v1__key_value_list__init(value);
74
75
0
        if (entry_count > 0) {
76
0
            value->values = \
77
0
                flb_calloc(entry_count,
78
0
                       sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
79
80
0
            if (value->values == NULL) {
81
0
                flb_free(value);
82
83
0
                value = NULL;
84
0
            }
85
0
            else {
86
0
                value->n_values = entry_count;
87
0
            }
88
0
        }
89
0
    }
90
91
0
    return value;
92
0
}
93
94
Opentelemetry__Proto__Common__V1__AnyValue *otlp_any_value_initialize(int data_type, size_t entry_count)
95
0
{
96
0
    Opentelemetry__Proto__Common__V1__AnyValue *value;
97
98
0
    value = flb_calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue));
99
100
0
    if (value == NULL) {
101
0
        return NULL;
102
0
    }
103
104
0
    opentelemetry__proto__common__v1__any_value__init(value);
105
106
0
    if (data_type == MSGPACK_OBJECT_STR) {
107
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE;
108
0
    }
109
0
    else if (data_type == MSGPACK_OBJECT_NIL) {
110
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE__NOT_SET;
111
0
    }
112
0
    else if (data_type == MSGPACK_OBJECT_BOOLEAN) {
113
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BOOL_VALUE;
114
0
    }
115
0
    else if (data_type == MSGPACK_OBJECT_POSITIVE_INTEGER || data_type == MSGPACK_OBJECT_NEGATIVE_INTEGER) {
116
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_INT_VALUE;
117
0
    }
118
0
    else if (data_type == MSGPACK_OBJECT_FLOAT32 || data_type == MSGPACK_OBJECT_FLOAT64) {
119
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_DOUBLE_VALUE;
120
0
    }
121
0
    else if (data_type == MSGPACK_OBJECT_ARRAY) {
122
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_ARRAY_VALUE;
123
0
        value->array_value = otlp_array_value_initialize(entry_count);
124
125
0
        if (value->array_value == NULL) {
126
0
            flb_free(value);
127
128
0
            value = NULL;
129
0
        }
130
0
    }
131
0
    else if (data_type == MSGPACK_OBJECT_MAP) {
132
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_KVLIST_VALUE;
133
134
0
        value->kvlist_value = otlp_kvlist_value_initialize(entry_count);
135
136
0
        if (value->kvlist_value == NULL) {
137
0
            flb_free(value);
138
139
0
            value = NULL;
140
0
        }
141
0
    }
142
0
    else if (data_type == MSGPACK_OBJECT_BIN) {
143
0
        value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE;
144
0
    }
145
0
    else {
146
0
        flb_free(value);
147
148
0
        value = NULL;
149
0
    }
150
151
0
    return value;
152
0
}
153
154
void otlp_kvarray_destroy(Opentelemetry__Proto__Common__V1__KeyValue **kvarray, size_t entry_count)
155
0
{
156
0
    size_t index;
157
158
0
    if (kvarray != NULL) {
159
0
        for (index = 0 ; index < entry_count ; index++) {
160
0
            if (kvarray[index] != NULL) {
161
0
                otlp_kvpair_destroy(kvarray[index]);
162
0
                kvarray[index] = NULL;
163
0
            }
164
0
        }
165
166
0
        flb_free(kvarray);
167
0
    }
168
0
}
169
170
int otlp_kvarray_append(Opentelemetry__Proto__Common__V1__KeyValue ***base,
171
                        size_t *base_count,
172
                        Opentelemetry__Proto__Common__V1__KeyValue **extra,
173
                        size_t extra_count)
174
0
{
175
0
    size_t new_count;
176
0
    Opentelemetry__Proto__Common__V1__KeyValue **tmp;
177
178
0
    if (extra == NULL || extra_count == 0) {
179
0
        return 0;
180
0
    }
181
182
0
    new_count = *base_count + extra_count;
183
0
    tmp = flb_realloc(*base, new_count * sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
184
0
    if (!tmp) {
185
0
        return -1;
186
0
    }
187
188
0
    *base = tmp;
189
0
    memcpy(*base + *base_count, extra,
190
0
           extra_count * sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
191
0
    *base_count = new_count;
192
0
    flb_free(extra);
193
194
0
    return 0;
195
0
}
196
197
void otlp_kvpair_destroy(Opentelemetry__Proto__Common__V1__KeyValue *kvpair)
198
0
{
199
0
    if (kvpair == NULL) {
200
0
        return;
201
0
    }
202
203
0
    if (kvpair->key != NULL) {
204
0
        flb_free(kvpair->key);
205
0
    }
206
207
0
    if (kvpair->value != NULL) {
208
0
        otlp_any_value_destroy(kvpair->value);
209
0
    }
210
211
0
    flb_free(kvpair);
212
0
}
213
214
void otlp_kvlist_destroy(Opentelemetry__Proto__Common__V1__KeyValueList *kvlist)
215
0
{
216
0
    size_t index;
217
218
0
    if (kvlist != NULL) {
219
0
        if (kvlist->values != NULL) {
220
0
            for (index = 0 ; index < kvlist->n_values ; index++) {
221
0
                otlp_kvpair_destroy(kvlist->values[index]);
222
0
            }
223
224
0
            flb_free(kvlist->values);
225
0
        }
226
227
0
        flb_free(kvlist);
228
0
    }
229
0
}
230
231
void otlp_array_destroy(Opentelemetry__Proto__Common__V1__ArrayValue *array)
232
0
{
233
0
    size_t index;
234
235
0
    if (array != NULL) {
236
0
        if (array->values != NULL) {
237
0
            for (index = 0 ; index < array->n_values ; index++) {
238
0
                otlp_any_value_destroy(array->values[index]);
239
0
            }
240
241
0
            flb_free(array->values);
242
0
        }
243
244
0
        flb_free(array);
245
0
    }
246
0
}
247
248
void otlp_any_value_destroy(Opentelemetry__Proto__Common__V1__AnyValue *value)
249
0
{
250
0
    if (value != NULL) {
251
0
        if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) {
252
0
            if (value->string_value != NULL) {
253
0
                flb_free(value->string_value);
254
0
            }
255
0
        }
256
0
        else if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_ARRAY_VALUE) {
257
0
            if (value->array_value != NULL) {
258
0
                otlp_array_destroy(value->array_value);
259
0
            }
260
0
        }
261
0
        else if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_KVLIST_VALUE) {
262
0
            if (value->kvlist_value != NULL) {
263
0
                otlp_kvlist_destroy(value->kvlist_value);
264
0
            }
265
0
        }
266
0
        else if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE) {
267
0
            if (value->bytes_value.data != NULL) {
268
0
                flb_free(value->bytes_value.data);
269
0
            }
270
0
        }
271
272
0
        value->string_value = NULL;
273
274
0
        flb_free(value);
275
0
    }
276
0
}
277
278
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_boolean_to_otlp_any_value(struct msgpack_object *o)
279
0
{
280
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
281
282
0
    result = otlp_any_value_initialize(MSGPACK_OBJECT_BOOLEAN, 0);
283
284
0
    if (result != NULL) {
285
0
        result->bool_value = o->via.boolean;
286
0
    }
287
288
0
    return result;
289
0
}
290
291
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_integer_to_otlp_any_value(struct msgpack_object *o)
292
0
{
293
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
294
295
0
    result = otlp_any_value_initialize(o->type, 0);
296
297
0
    if (result != NULL) {
298
0
        if (o->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
299
0
            result->int_value = (int64_t) o->via.u64;
300
0
        }
301
0
        else {
302
0
            result->int_value = o->via.i64;
303
0
        }
304
0
    }
305
306
0
    return result;
307
0
}
308
309
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_float_to_otlp_any_value(struct msgpack_object *o)
310
0
{
311
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
312
313
0
    result = otlp_any_value_initialize(o->type, 0);
314
315
0
    if (result != NULL) {
316
0
        result->double_value = o->via.f64;
317
0
    }
318
319
0
    return result;
320
0
}
321
322
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_string_to_otlp_any_value(struct msgpack_object *o)
323
0
{
324
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
325
326
0
    result = otlp_any_value_initialize(MSGPACK_OBJECT_STR, 0);
327
328
0
    if (result != NULL) {
329
0
        result->string_value = flb_strndup(o->via.str.ptr, o->via.str.size);
330
331
0
        if (result->string_value == NULL) {
332
0
            otlp_any_value_destroy(result);
333
334
0
            result = NULL;
335
0
        }
336
0
    }
337
338
0
    return result;
339
0
}
340
341
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_nil_to_otlp_any_value(struct msgpack_object *o)
342
0
{
343
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
344
345
0
    result = otlp_any_value_initialize(MSGPACK_OBJECT_NIL, 0);
346
347
0
    if (result != NULL) {
348
0
        result->string_value = NULL;
349
0
    }
350
351
0
    return result;
352
0
}
353
354
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_bin_to_otlp_any_value(struct msgpack_object *o)
355
0
{
356
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
357
358
0
    result = otlp_any_value_initialize(MSGPACK_OBJECT_BIN, 0);
359
360
0
    if (result != NULL) {
361
0
        result->bytes_value.len = o->via.bin.size;
362
0
        result->bytes_value.data = flb_malloc(o->via.bin.size);
363
364
0
        if (result->bytes_value.data != NULL) {
365
0
            memcpy(result->bytes_value.data, o->via.bin.ptr, o->via.bin.size);
366
0
        }
367
0
        else {
368
0
            otlp_any_value_destroy(result);
369
370
0
            result = NULL;
371
0
        }
372
373
0
    }
374
375
0
    return result;
376
0
}
377
378
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_array_to_otlp_any_value(struct msgpack_object *o)
379
0
{
380
0
    size_t                                      entry_count;
381
0
    Opentelemetry__Proto__Common__V1__AnyValue *entry_value;
382
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
383
0
    size_t                                      index;
384
0
    msgpack_object                             *p;
385
386
0
    entry_count = o->via.array.size;
387
0
    result = otlp_any_value_initialize(MSGPACK_OBJECT_ARRAY, entry_count);
388
389
0
    p = o->via.array.ptr;
390
391
0
    if (result != NULL) {
392
0
        index = 0;
393
394
0
        for (index = 0 ; index < entry_count ; index++) {
395
0
            entry_value = msgpack_object_to_otlp_any_value(&p[index]);
396
397
0
            if (entry_value == NULL) {
398
0
                otlp_any_value_destroy(result);
399
400
0
                result = NULL;
401
402
0
                break;
403
0
            }
404
405
0
            result->array_value->values[index] = entry_value;
406
0
        }
407
0
    }
408
409
0
    return result;
410
0
}
411
412
Opentelemetry__Proto__Common__V1__KeyValue *msgpack_kv_to_otlp_any_value(struct msgpack_object_kv *input_pair)
413
0
{
414
0
    Opentelemetry__Proto__Common__V1__KeyValue *kv;
415
416
0
    kv = otlp_kvpair_value_initialize();
417
0
    if (kv == NULL) {
418
0
        flb_errno();
419
420
0
        return NULL;
421
0
    }
422
423
0
    kv->key = flb_strndup(input_pair->key.via.str.ptr, input_pair->key.via.str.size);
424
0
    if (kv->key == NULL) {
425
0
        flb_errno();
426
0
        flb_free(kv);
427
428
0
        return NULL;
429
0
    }
430
431
0
    kv->value = msgpack_object_to_otlp_any_value(&input_pair->val);
432
0
    if (kv->value == NULL) {
433
0
        flb_free(kv->key);
434
0
        flb_free(kv);
435
436
0
        return NULL;
437
0
    }
438
439
0
    return kv;
440
0
}
441
442
Opentelemetry__Proto__Common__V1__KeyValue **msgpack_map_to_otlp_kvarray(struct msgpack_object *o, size_t *entry_count)
443
0
{
444
0
    Opentelemetry__Proto__Common__V1__KeyValue **result;
445
0
    size_t                                       index;
446
0
    msgpack_object_kv                           *kv;
447
448
0
    *entry_count = o->via.map.size;
449
0
    result = flb_calloc(*entry_count, sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
450
0
    if (result != NULL) {
451
0
        for (index = 0; index < *entry_count; index++) {
452
0
            kv = &o->via.map.ptr[index];
453
0
            result[index] = msgpack_kv_to_otlp_any_value(kv);
454
0
        }
455
0
    }
456
0
    else {
457
0
        *entry_count = 0;
458
0
    }
459
460
0
    return result;
461
0
}
462
463
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_map_to_otlp_any_value(struct msgpack_object *o)
464
0
{
465
0
    size_t                                      entry_count;
466
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
467
0
    Opentelemetry__Proto__Common__V1__KeyValue *keyvalue;
468
0
    size_t                                      index;
469
0
    msgpack_object_kv                          *kv;
470
471
0
    entry_count = o->via.map.size;
472
0
    result = otlp_any_value_initialize(MSGPACK_OBJECT_MAP, entry_count);
473
474
0
    if (result != NULL) {
475
476
0
        for (index = 0; index < entry_count; index++) {
477
0
            kv = &o->via.map.ptr[index];
478
0
            keyvalue = msgpack_kv_to_otlp_any_value(kv);
479
0
            result->kvlist_value->values[index] = keyvalue;
480
0
        }
481
0
    }
482
483
0
    return result;
484
0
}
485
486
Opentelemetry__Proto__Common__V1__AnyValue *msgpack_object_to_otlp_any_value(struct msgpack_object *o)
487
0
{
488
0
    Opentelemetry__Proto__Common__V1__AnyValue *result;
489
490
0
    result = NULL;
491
492
0
    switch (o->type) {
493
0
        case MSGPACK_OBJECT_NIL:
494
0
            result = msgpack_nil_to_otlp_any_value(o);
495
0
            break;
496
497
0
        case MSGPACK_OBJECT_BOOLEAN:
498
0
            result = msgpack_boolean_to_otlp_any_value(o);
499
0
            break;
500
501
0
        case MSGPACK_OBJECT_POSITIVE_INTEGER:
502
0
        case MSGPACK_OBJECT_NEGATIVE_INTEGER:
503
0
            result = msgpack_integer_to_otlp_any_value(o);
504
0
            break;
505
506
0
        case MSGPACK_OBJECT_FLOAT32:
507
0
        case MSGPACK_OBJECT_FLOAT64:
508
0
            result = msgpack_float_to_otlp_any_value(o);
509
0
            break;
510
511
0
        case MSGPACK_OBJECT_STR:
512
0
            result = msgpack_string_to_otlp_any_value(o);
513
0
            break;
514
515
0
        case MSGPACK_OBJECT_MAP:
516
0
            result = msgpack_map_to_otlp_any_value(o);
517
0
            break;
518
519
0
        case MSGPACK_OBJECT_BIN:
520
0
            result = msgpack_bin_to_otlp_any_value(o);
521
0
            break;
522
523
0
        case MSGPACK_OBJECT_ARRAY:
524
0
            result = msgpack_array_to_otlp_any_value(o);
525
0
            break;
526
527
0
        default:
528
0
            break;
529
0
    }
530
531
    /* This function will fail if it receives an object with
532
     * type MSGPACK_OBJECT_EXT
533
     */
534
535
0
    return result;
536
0
}