Coverage Report

Created: 2025-09-04 07:51

/src/fluent-bit/lib/cmetrics/src/cmt_decode_opentelemetry.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  CMetrics
4
 *  ========
5
 *  Copyright 2021-2022 The CMetrics 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 <cmetrics/cmetrics.h>
21
#include <cmetrics/cmt_metric.h>
22
#include <cmetrics/cmt_map.h>
23
#include <cmetrics/cmt_gauge.h>
24
#include <cmetrics/cmt_counter.h>
25
#include <cmetrics/cmt_summary.h>
26
#include <cmetrics/cmt_histogram.h>
27
#include <cmetrics/cmt_untyped.h>
28
#include <cmetrics/cmt_compat.h>
29
#include <cmetrics/cmt_decode_opentelemetry.h>
30
31
static struct cfl_variant *clone_variant(Opentelemetry__Proto__Common__V1__AnyValue *source);
32
33
static int clone_array(struct cfl_array *target,
34
                       Opentelemetry__Proto__Common__V1__ArrayValue *source);
35
static int clone_array_entry(struct cfl_array *target,
36
                             Opentelemetry__Proto__Common__V1__AnyValue *source);
37
static int clone_kvlist(struct cfl_kvlist *target,
38
                                Opentelemetry__Proto__Common__V1__KeyValueList *source);
39
static int clone_kvlist_entry(struct cfl_kvlist *target,
40
                           Opentelemetry__Proto__Common__V1__KeyValue *source);
41
42
static struct cmt_map_label *create_label(char *caption, size_t length);
43
static int append_new_map_label_key(struct cmt_map *map, char *name);
44
static int append_new_metric_label_value(struct cmt_metric *metric, char *name, size_t length);
45
46
static struct cfl_variant *clone_variant(Opentelemetry__Proto__Common__V1__AnyValue *source)
47
1.54k
{
48
1.54k
    struct cfl_kvlist  *new_child_kvlist;
49
1.54k
    struct cfl_array   *new_child_array;
50
1.54k
    struct cfl_variant *result_instance = NULL;
51
1.54k
    int                 result;
52
53
1.54k
    if (source == NULL) {
54
2
        return NULL;
55
2
    }
56
1.54k
    if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) {
57
14
        result_instance = cfl_variant_create_from_string(source->string_value);
58
14
    }
59
1.53k
    else if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BOOL_VALUE) {
60
144
        result_instance = cfl_variant_create_from_bool(source->bool_value);
61
144
    }
62
1.38k
    else if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_INT_VALUE) {
63
384
        result_instance = cfl_variant_create_from_int64(source->int_value);
64
384
    }
65
1.00k
    else if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_DOUBLE_VALUE) {
66
72
        result_instance = cfl_variant_create_from_double(source->double_value);
67
72
    }
68
932
    else if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_KVLIST_VALUE) {
69
264
        new_child_kvlist = cfl_kvlist_create();
70
264
        if (new_child_kvlist == NULL) {
71
0
            return NULL;
72
0
        }
73
74
264
        result_instance = cfl_variant_create_from_kvlist(new_child_kvlist);
75
76
264
        if (result_instance == NULL) {
77
0
            cfl_kvlist_destroy(new_child_kvlist);
78
79
0
            return NULL;
80
0
        }
81
82
264
        result = clone_kvlist(new_child_kvlist, source->kvlist_value);
83
264
        if (result) {
84
0
            cfl_variant_destroy(result_instance);
85
86
0
            return NULL;
87
0
        }
88
264
    }
89
668
    else if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_ARRAY_VALUE) {
90
72
        new_child_array = cfl_array_create(source->array_value->n_values);
91
92
72
        if (new_child_array == NULL) {
93
0
            return NULL;
94
0
        }
95
96
72
        result_instance = cfl_variant_create_from_array(new_child_array);
97
72
        if (result_instance == NULL) {
98
0
            cfl_array_destroy(new_child_array);
99
100
0
            return NULL;
101
0
        }
102
103
72
        result = clone_array(new_child_array, source->array_value);
104
72
        if (result) {
105
0
            cfl_variant_destroy(result_instance);
106
107
0
            return NULL;
108
0
        }
109
72
    }
110
596
    else if (source->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE) {
111
596
        result_instance = cfl_variant_create_from_bytes((char *) source->bytes_value.data, source->bytes_value.len,
112
596
                                                        CFL_FALSE);
113
596
    }
114
115
1.54k
    return result_instance;
116
1.54k
}
117
118
static int clone_array(struct cfl_array *target,
119
                       Opentelemetry__Proto__Common__V1__ArrayValue *source)
120
72
{
121
72
    int    result;
122
72
    size_t index;
123
124
72
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
125
126
72
    for (index = 0 ;
127
144
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
128
144
         index < source->n_values ;
129
72
         index++) {
130
72
        result = clone_array_entry(target, source->values[index]);
131
72
    }
132
133
72
    return result;
134
72
}
135
136
static int clone_array_entry(struct cfl_array *target,
137
                             Opentelemetry__Proto__Common__V1__AnyValue *source)
138
72
{
139
72
    struct cfl_variant *new_child_instance;
140
72
    int                 result;
141
142
72
    new_child_instance = clone_variant(source);
143
72
    if (new_child_instance == NULL) {
144
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
145
0
    }
146
147
72
    result = cfl_array_append(target, new_child_instance);
148
72
    if (result) {
149
0
        cfl_variant_destroy(new_child_instance);
150
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
151
0
    }
152
153
72
    return CMT_DECODE_OPENTELEMETRY_SUCCESS;
154
72
}
155
156
static int clone_kvlist(struct cfl_kvlist *target,
157
                        Opentelemetry__Proto__Common__V1__KeyValueList *source)
158
264
{
159
264
    int    result;
160
264
    size_t index;
161
162
264
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
163
164
264
    for (index = 0 ;
165
264
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
166
264
         index < source->n_values ;
167
264
         index++) {
168
0
        result = clone_kvlist_entry(target, source->values[index]);
169
0
    }
170
171
264
    return 0;
172
264
}
173
174
static int clone_kvlist_entry(struct cfl_kvlist *target,
175
                              Opentelemetry__Proto__Common__V1__KeyValue *source)
176
1.47k
{
177
1.47k
    struct cfl_variant *new_child_instance;
178
1.47k
    int                 result;
179
180
1.47k
    new_child_instance = clone_variant(source->value);
181
182
1.47k
    if (new_child_instance == NULL) {
183
2
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
184
2
    }
185
186
1.47k
    result = cfl_kvlist_insert(target, source->key, new_child_instance);
187
188
1.47k
    if (result) {
189
0
        cfl_variant_destroy(new_child_instance);
190
191
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
192
0
    }
193
194
1.47k
    return CMT_DECODE_OPENTELEMETRY_SUCCESS;
195
1.47k
}
196
197
struct cfl_kvlist *get_or_create_external_metadata_kvlist(
198
    struct cfl_kvlist *root, char *key)
199
34.5k
{
200
34.5k
    struct cfl_variant *entry_variant;
201
34.5k
    struct cfl_kvlist  *entry_kvlist;
202
34.5k
    int                 result;
203
204
34.5k
    entry_variant = cfl_kvlist_fetch(root, key);
205
206
34.5k
    if (entry_variant == NULL) {
207
34.5k
        entry_kvlist = cfl_kvlist_create();
208
209
34.5k
        if (entry_kvlist == NULL) {
210
0
            return NULL;
211
0
        }
212
213
34.5k
        result = cfl_kvlist_insert_kvlist(root,
214
34.5k
                                          key,
215
34.5k
                                          entry_kvlist);
216
217
34.5k
        if (result != 0) {
218
0
            cfl_kvlist_destroy(entry_kvlist);
219
220
0
            return NULL;
221
0
        }
222
34.5k
    }
223
0
    else {
224
0
        entry_kvlist = entry_variant->data.as_kvlist;
225
0
    }
226
227
34.5k
    return entry_kvlist;
228
34.5k
}
229
230
static struct cmt_map_label *create_label(char *caption, size_t length)
231
608
{
232
608
    struct cmt_map_label *instance;
233
234
608
    instance = calloc(1, sizeof(struct cmt_map_label));
235
236
608
    if (instance != NULL) {
237
608
        if (caption != NULL) {
238
503
            if (length == 0) {
239
503
                length = strlen(caption);
240
503
            }
241
242
503
            instance->name = cfl_sds_create_len(caption, length);
243
244
503
            if (instance->name == NULL) {
245
0
                cmt_errno();
246
247
0
                free(instance);
248
249
0
                instance = NULL;
250
0
            }
251
503
        }
252
608
    }
253
254
608
    return instance;
255
608
}
256
257
static int append_new_map_label_key(struct cmt_map *map, char *name)
258
479
{
259
479
    struct cmt_map_label *label;
260
261
479
    label = create_label(name, 0);
262
263
479
    if (label == NULL) {
264
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
265
0
    }
266
267
479
    cfl_list_add(&label->_head, &map->label_keys);
268
479
    map->label_count++;
269
270
479
    return CMT_DECODE_OPENTELEMETRY_SUCCESS;
271
479
}
272
273
static int append_new_metric_label_value(struct cmt_metric *metric, char *name, size_t length)
274
129
{
275
129
    struct cmt_map_label *label;
276
277
129
    label = create_label(name, length);
278
279
129
    if (label == NULL) {
280
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
281
0
    }
282
283
129
    cfl_list_add(&label->_head, &metric->labels);
284
285
129
    return CMT_DECODE_OPENTELEMETRY_SUCCESS;
286
129
}
287
288
static int decode_data_point_labels(struct cmt *cmt,
289
                                    struct cmt_map *map,
290
                                    struct cmt_metric *metric,
291
                                    size_t attribute_count,
292
                                    Opentelemetry__Proto__Common__V1__KeyValue **attribute_list)
293
1.73k
{
294
1.73k
    char                                        dummy_label_value[32];
295
1.73k
    void                                      **value_index_list;
296
1.73k
    size_t                                      attribute_index;
297
1.73k
    size_t                                      map_label_index;
298
1.73k
    size_t                                      map_label_count;
299
1.73k
    struct cfl_list                             *label_iterator;
300
1.73k
    struct cmt_map_label                       *current_label;
301
1.73k
    size_t                                      label_index;
302
1.73k
    int                                         label_found;
303
1.73k
    Opentelemetry__Proto__Common__V1__KeyValue *attribute;
304
1.73k
    int                                         result;
305
306
1.73k
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
307
308
1.73k
    if (attribute_count == 0) {
309
1.24k
        return result;
310
1.24k
    }
311
312
491
    if (attribute_count > 127) {
313
0
        return CMT_DECODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
314
0
    }
315
316
491
    value_index_list = calloc(128, sizeof(void *));
317
318
491
    if (value_index_list == NULL) {
319
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
320
0
    }
321
322
491
    for (attribute_index = 0 ;
323
1.18k
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
324
1.18k
         attribute_index < attribute_count ;
325
697
         attribute_index++) {
326
327
697
        attribute = attribute_list[attribute_index];
328
329
697
        label_found = CMT_FALSE;
330
697
        label_index = 0;
331
332
697
        cfl_list_foreach(label_iterator, &map->label_keys) {
333
383
            current_label = cfl_list_entry(label_iterator, struct cmt_map_label, _head);
334
335
383
            if (strcmp(current_label->name, attribute->key) == 0) {
336
218
                label_found = CMT_TRUE;
337
338
218
                break;
339
218
            }
340
341
165
            label_index++;
342
165
        }
343
344
697
        if (label_found == CMT_FALSE) {
345
479
            result = append_new_map_label_key(map, attribute->key);
346
479
        }
347
348
697
        if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
349
697
            value_index_list[label_index] = (void *) attribute;
350
697
        }
351
697
    }
352
353
491
    map_label_count = cfl_list_size(&map->label_keys);
354
355
491
    for (map_label_index = 0 ;
356
1.14k
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
357
1.14k
         map_label_index < map_label_count ;
358
656
         map_label_index++) {
359
360
656
        if (value_index_list[map_label_index] != NULL) {
361
491
            attribute = (Opentelemetry__Proto__Common__V1__KeyValue *)
362
491
                            value_index_list[map_label_index];
363
364
491
            if (attribute->value == NULL) {
365
362
                continue;
366
362
            }
367
368
129
            if (attribute->value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) {
369
0
                result = append_new_metric_label_value(metric, attribute->value->string_value, 0);
370
0
            }
371
129
            else if (attribute->value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE) {
372
0
                result = append_new_metric_label_value(metric,
373
0
                                                       (char *) attribute->value->bytes_value.data,
374
0
                                                       attribute->value->bytes_value.len);
375
0
            }
376
129
            else if (attribute->value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BOOL_VALUE) {
377
0
                snprintf(dummy_label_value, sizeof(dummy_label_value) - 1, "%d", attribute->value->bool_value);
378
379
0
                result = append_new_metric_label_value(metric, dummy_label_value, 0);
380
0
            }
381
129
            else if (attribute->value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_INT_VALUE) {
382
24
                snprintf(dummy_label_value, sizeof(dummy_label_value) - 1, "%" PRIi64, attribute->value->int_value);
383
384
24
                result = append_new_metric_label_value(metric, dummy_label_value, 0);
385
24
            }
386
105
            else if (attribute->value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_DOUBLE_VALUE) {
387
0
                snprintf(dummy_label_value, sizeof(dummy_label_value) - 1, "%.17g", attribute->value->double_value);
388
389
0
                result = append_new_metric_label_value(metric, dummy_label_value, 0);
390
0
            }
391
105
            else {
392
105
                result = append_new_metric_label_value(metric, NULL, 0);
393
105
            }
394
129
        }
395
656
    }
396
397
491
    free(value_index_list);
398
399
491
    return result;
400
491
}
401
402
static int decode_numerical_data_point(struct cmt *cmt,
403
                                       struct cmt_map *map,
404
                                       Opentelemetry__Proto__Metrics__V1__NumberDataPoint *data_point)
405
1.92k
{
406
1.92k
    int                static_metric_detected;
407
1.92k
    struct cmt_metric *sample;
408
1.92k
    int                result;
409
1.92k
    double             value;
410
411
1.92k
    static_metric_detected = CMT_FALSE;
412
413
1.92k
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
414
415
1.92k
    if (data_point->n_attributes == 0) {
416
1.61k
        if (map->metric_static_set == CMT_FALSE) {
417
557
            static_metric_detected = CMT_TRUE;
418
557
        }
419
1.61k
    }
420
421
1.92k
    if (static_metric_detected == CMT_FALSE) {
422
1.36k
        sample = calloc(1, sizeof(struct cmt_metric));
423
424
1.36k
        if (sample == NULL) {
425
0
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
426
0
        }
427
428
1.36k
        cfl_list_init(&sample->labels);
429
430
1.36k
        result = decode_data_point_labels(cmt,
431
1.36k
                                          map,
432
1.36k
                                          sample,
433
1.36k
                                          data_point->n_attributes,
434
1.36k
                                          data_point->attributes);
435
436
1.36k
        if (result) {
437
0
            destroy_label_list(&sample->labels);
438
439
0
            free(sample);
440
0
        }
441
1.36k
        else {
442
1.36k
            cfl_list_add(&sample->_head, &map->metrics);
443
1.36k
        }
444
1.36k
    }
445
557
    else {
446
557
        sample = &map->metric;
447
448
557
        map->metric_static_set = CMT_TRUE;
449
557
    }
450
451
1.92k
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
452
1.92k
        value = 0;
453
454
1.92k
        if (data_point->value_case == OPENTELEMETRY__PROTO__METRICS__V1__NUMBER_DATA_POINT__VALUE_AS_INT) {
455
0
            if (data_point->as_int < 0) {
456
0
                value = 0;
457
0
            }
458
0
            else {
459
0
                value = data_point->as_int;
460
0
            }
461
0
        }
462
1.92k
        else if (data_point->value_case == OPENTELEMETRY__PROTO__METRICS__V1__NUMBER_DATA_POINT__VALUE_AS_DOUBLE) {
463
0
            value = data_point->as_double;
464
0
        }
465
466
1.92k
        cmt_metric_set(sample, data_point->time_unix_nano, value);
467
1.92k
    }
468
469
1.92k
    return result;
470
1.92k
}
471
472
static int decode_numerical_data_point_list(struct cmt *cmt,
473
                                            struct cmt_map *map,
474
                                            size_t data_point_count,
475
                                            Opentelemetry__Proto__Metrics__V1__NumberDataPoint **data_point_list)
476
836
{
477
836
    size_t index;
478
836
    int    result;
479
480
836
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
481
482
836
    for (index = 0 ;
483
2.75k
         result == 0 &&
484
2.75k
         index < data_point_count ; index++) {
485
1.92k
        result = decode_numerical_data_point(cmt, map, data_point_list[index]);
486
1.92k
    }
487
488
836
    return result;
489
836
}
490
491
static int decode_summary_data_point(struct cmt *cmt,
492
                                     struct cmt_map *map,
493
                                     Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *data_point)
494
593
{
495
593
    int                 static_metric_detected;
496
593
    struct cmt_summary *summary;
497
593
    struct cmt_metric  *sample;
498
593
    int                 result;
499
593
    size_t              index;
500
501
593
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
502
503
593
    summary = (struct cmt_summary *) map->parent;
504
505
593
    if (summary->quantiles == NULL) {
506
291
        summary->quantiles = calloc(data_point->n_quantile_values,
507
291
                                    sizeof(double));
508
509
291
        if (summary->quantiles == NULL) {
510
0
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
511
0
        }
512
513
291
        summary->quantiles_count = data_point->n_quantile_values;
514
515
291
        for (index = 0 ;
516
291
             index < data_point->n_quantile_values ;
517
291
             index++) {
518
0
            summary->quantiles[index] = data_point->quantile_values[index]->quantile;
519
0
        }
520
291
    }
521
522
593
    static_metric_detected = CMT_FALSE;
523
524
593
    if (data_point->n_attributes == 0) {
525
404
        if (map->metric_static_set == CMT_FALSE) {
526
224
            static_metric_detected = CMT_TRUE;
527
224
        }
528
404
    }
529
530
593
    if (static_metric_detected == CMT_FALSE) {
531
369
        sample = calloc(1, sizeof(struct cmt_metric));
532
533
369
        if (sample == NULL) {
534
0
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
535
0
        }
536
537
369
        cfl_list_init(&sample->labels);
538
539
369
        result = decode_data_point_labels(cmt,
540
369
                                          map,
541
369
                                          sample,
542
369
                                          data_point->n_attributes,
543
369
                                          data_point->attributes);
544
545
369
        if (result) {
546
0
            destroy_label_list(&sample->labels);
547
548
0
            free(sample);
549
550
0
            return result;
551
0
        }
552
369
        else {
553
369
            cfl_list_add(&sample->_head, &map->metrics);
554
369
        }
555
369
    }
556
224
    else {
557
224
        sample = &map->metric;
558
559
224
        map->metric_static_set = CMT_TRUE;
560
224
    }
561
562
593
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
563
593
        if (sample->sum_quantiles_set == CMT_FALSE) {
564
593
            sample->sum_quantiles = calloc(data_point->n_quantile_values,
565
593
                                           sizeof(uint64_t));
566
567
593
            if (sample->sum_quantiles == NULL) {
568
0
                return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
569
0
            }
570
571
593
            sample->sum_quantiles_set = CMT_TRUE;
572
593
            sample->sum_quantiles_count = data_point->n_quantile_values;
573
593
        }
574
575
593
        for (index = 0 ;
576
593
             index < data_point->n_quantile_values ;
577
593
             index++) {
578
0
            cmt_summary_quantile_set(sample, data_point->time_unix_nano,
579
0
                                     index, data_point->quantile_values[index]->value);
580
0
        }
581
582
593
        sample->sum_sum = cmt_math_d64_to_uint64(data_point->sum);
583
593
        sample->sum_count = data_point->count;
584
593
    }
585
586
593
    return result;
587
593
}
588
589
static int decode_summary_data_point_list(struct cmt *cmt,
590
                                          struct cmt_map *map,
591
                                          size_t data_point_count,
592
                                          Opentelemetry__Proto__Metrics__V1__SummaryDataPoint **data_point_list)
593
423
{
594
423
    size_t index;
595
423
    int    result;
596
597
423
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
598
599
423
    for (index = 0 ;
600
1.01k
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
601
1.01k
         index < data_point_count ; index++) {
602
593
        result = decode_summary_data_point(cmt, map, data_point_list[index]);
603
593
    }
604
605
423
    return result;
606
423
}
607
608
static int decode_histogram_data_point(struct cmt *cmt,
609
                                       struct cmt_map *map,
610
                                       Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *data_point)
611
0
{
612
0
    int                   static_metric_detected;
613
0
    struct cmt_histogram *histogram;
614
0
    struct cmt_metric    *sample;
615
0
    int                   result;
616
0
    size_t                index;
617
618
0
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
619
620
0
    histogram = (struct cmt_histogram *) map->parent;
621
622
0
    if (data_point->n_bucket_counts > data_point->n_explicit_bounds + 1) {
623
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
624
0
    }
625
626
0
    if (histogram->buckets == NULL) {
627
0
        histogram->buckets = cmt_histogram_buckets_create_size(data_point->explicit_bounds,
628
0
                                                               data_point->n_explicit_bounds);
629
630
0
        if (histogram->buckets == NULL) {
631
0
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
632
0
        }
633
0
    }
634
635
0
    static_metric_detected = CMT_FALSE;
636
637
0
    if (data_point->n_attributes == 0) {
638
0
        if (map->metric_static_set == CMT_FALSE) {
639
0
            static_metric_detected = CMT_TRUE;
640
0
        }
641
0
    }
642
643
0
    if (static_metric_detected == CMT_FALSE) {
644
0
        sample = calloc(1, sizeof(struct cmt_metric));
645
646
0
        if (sample == NULL) {
647
0
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
648
0
        }
649
650
0
        cfl_list_init(&sample->labels);
651
652
0
        result = decode_data_point_labels(cmt,
653
0
                                          map,
654
0
                                          sample,
655
0
                                          data_point->n_attributes,
656
0
                                          data_point->attributes);
657
658
0
        if (result != 0) {
659
0
            destroy_label_list(&sample->labels);
660
661
0
            free(sample);
662
663
0
            return result;
664
0
        }
665
0
        else {
666
0
            cfl_list_add(&sample->_head, &map->metrics);
667
0
        }
668
0
    }
669
0
    else {
670
0
        sample = &map->metric;
671
672
0
        map->metric_static_set = CMT_TRUE;
673
0
    }
674
675
0
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
676
0
        if (sample->hist_buckets == NULL) {
677
0
            sample->hist_buckets = calloc(data_point->n_bucket_counts + 1,
678
0
                                          sizeof(uint64_t));
679
680
0
            if (sample->hist_buckets == NULL) {
681
0
                return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
682
0
            }
683
0
        }
684
685
0
        for (index = 0 ;
686
0
             index < data_point->n_bucket_counts;
687
0
             index++) {
688
0
            cmt_metric_hist_set(sample, data_point->time_unix_nano,
689
0
                                index, data_point->bucket_counts[index]);
690
0
        }
691
692
0
        sample->hist_sum = cmt_math_d64_to_uint64(data_point->sum);
693
0
        sample->hist_count = data_point->count;
694
0
    }
695
696
0
    return result;
697
0
}
698
699
static int decode_histogram_data_point_list(struct cmt *cmt,
700
                                            struct cmt_map *map,
701
                                            size_t data_point_count,
702
                                            Opentelemetry__Proto__Metrics__V1__HistogramDataPoint **data_point_list)
703
1.00k
{
704
1.00k
    size_t index;
705
1.00k
    int    result;
706
707
1.00k
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
708
709
1.00k
    for (index = 0 ;
710
1.00k
         result == 0 &&
711
1.00k
         index < data_point_count ; index++) {
712
0
        result = decode_histogram_data_point(cmt, map, data_point_list[index]);
713
0
    }
714
715
1.00k
    return result;
716
1.00k
}
717
718
static int decode_counter_entry(struct cmt *cmt,
719
    void *instance,
720
    Opentelemetry__Proto__Metrics__V1__Sum *metric)
721
682
{
722
682
    struct cmt_counter *counter;
723
682
    int                 result;
724
725
682
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
726
727
682
    counter = (struct cmt_counter *) instance;
728
729
682
    counter->map->metric_static_set = 0;
730
731
682
    result = decode_numerical_data_point_list(cmt,
732
682
                                              counter->map,
733
682
                                              metric->n_data_points,
734
682
                                              metric->data_points);
735
736
682
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
737
682
        if (metric->aggregation_temporality == OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_DELTA) {
738
0
            counter->aggregation_type = CMT_AGGREGATION_TYPE_DELTA;
739
0
        }
740
682
        else  if (metric->aggregation_temporality == OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_CUMULATIVE) {
741
363
            counter->aggregation_type = CMT_AGGREGATION_TYPE_CUMULATIVE;
742
363
        }
743
319
        else {
744
319
            counter->aggregation_type = CMT_AGGREGATION_TYPE_UNSPECIFIED;
745
319
        }
746
747
682
        counter->allow_reset = !metric->is_monotonic;
748
682
    }
749
750
682
    return result;
751
682
}
752
753
static int decode_gauge_entry(struct cmt *cmt,
754
    void *instance,
755
    Opentelemetry__Proto__Metrics__V1__Gauge *metric)
756
154
{
757
154
    struct cmt_gauge *gauge;
758
154
    int               result;
759
760
154
    gauge = (struct cmt_gauge *) instance;
761
762
154
    gauge->map->metric_static_set = 0;
763
764
154
    result = decode_numerical_data_point_list(cmt,
765
154
                                              gauge->map,
766
154
                                              metric->n_data_points,
767
154
                                              metric->data_points);
768
769
154
    return result;
770
154
}
771
772
static int decode_summary_entry(struct cmt *cmt,
773
    void *instance,
774
    Opentelemetry__Proto__Metrics__V1__Summary *metric)
775
423
{
776
423
    struct cmt_summary *summary;
777
423
    int                 result;
778
779
423
    summary = (struct cmt_summary *) instance;
780
781
423
    if (summary->quantiles != NULL) {
782
423
        free(summary->quantiles);
783
423
    }
784
785
423
    summary->quantiles = NULL;
786
423
    summary->quantiles_count = 0;
787
423
    summary->map->metric_static_set = 0;
788
789
423
    result = decode_summary_data_point_list(cmt,
790
423
                                            summary->map,
791
423
                                            metric->n_data_points,
792
423
                                            metric->data_points);
793
794
423
    return result;
795
423
}
796
797
static int decode_histogram_entry(struct cmt *cmt,
798
    void *instance,
799
    Opentelemetry__Proto__Metrics__V1__Histogram *metric)
800
1.00k
{
801
1.00k
    struct cmt_histogram *histogram;
802
1.00k
    int                   result;
803
804
1.00k
    histogram = (struct cmt_histogram *) instance;
805
806
1.00k
    histogram->buckets = NULL;
807
1.00k
    histogram->map->metric_static_set = 0;
808
809
1.00k
    result = decode_histogram_data_point_list(cmt,
810
1.00k
                                              histogram->map,
811
1.00k
                                              metric->n_data_points,
812
1.00k
                                              metric->data_points);
813
814
1.00k
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
815
1.00k
        if (metric->aggregation_temporality == OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_DELTA) {
816
521
            histogram->aggregation_type = CMT_AGGREGATION_TYPE_DELTA;
817
521
        }
818
488
        else  if (metric->aggregation_temporality == OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_CUMULATIVE) {
819
354
            histogram->aggregation_type = CMT_AGGREGATION_TYPE_CUMULATIVE;
820
354
        }
821
134
        else {
822
134
            histogram->aggregation_type = CMT_AGGREGATION_TYPE_UNSPECIFIED;
823
134
        }
824
1.00k
    }
825
826
1.00k
    return result;
827
1.00k
}
828
829
static int decode_metrics_entry(struct cmt *cmt,
830
    Opentelemetry__Proto__Metrics__V1__Metric *metric)
831
3.20k
{
832
3.20k
    char *metric_description;
833
3.20k
    char *metric_namespace;
834
3.20k
    char *metric_subsystem;
835
3.20k
    char *metric_name;
836
3.20k
    void *instance;
837
3.20k
    int   result;
838
839
3.20k
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
840
841
3.20k
    metric_name = metric->name;
842
3.20k
    metric_namespace = "";
843
3.20k
    metric_subsystem = "";
844
3.20k
    metric_description = metric->description;
845
846
3.20k
    if (metric_description == NULL) {
847
0
        metric_description = "-";
848
0
    }
849
3.20k
    else if (strlen(metric_description) == 0) {
850
3.20k
        metric_description = "-";
851
3.20k
    }
852
853
3.20k
    if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUM) {
854
686
        instance = cmt_counter_create(cmt,
855
686
                                      metric_namespace,
856
686
                                      metric_subsystem,
857
686
                                      metric_name,
858
686
                                      metric_description,
859
686
                                      0, NULL);
860
861
686
        if (instance == NULL) {
862
4
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
863
4
        }
864
865
682
        result = decode_counter_entry(cmt, instance, metric->sum);
866
867
682
        if (result) {
868
0
            cmt_counter_destroy(instance);
869
0
        }
870
682
    }
871
2.51k
    else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_GAUGE) {
872
157
        instance = cmt_gauge_create(cmt,
873
157
                                    metric_namespace,
874
157
                                    metric_subsystem,
875
157
                                    metric_name,
876
157
                                    metric_description,
877
157
                                    0, NULL);
878
879
157
        if (instance == NULL) {
880
3
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
881
3
        }
882
883
154
        result = decode_gauge_entry(cmt, instance, metric->gauge);
884
885
154
        if (result) {
886
0
            cmt_gauge_destroy(instance);
887
0
        }
888
154
    }
889
2.35k
    else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUMMARY) {
890
423
        instance = cmt_summary_create(cmt,
891
423
                                      metric_namespace,
892
423
                                      metric_subsystem,
893
423
                                      metric_name,
894
423
                                      metric_description,
895
423
                                      1, (double []) { 0.0 },
896
423
                                      0, NULL);
897
898
423
        if (instance == NULL) {
899
0
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
900
0
        }
901
902
        /* We are forced to create at least one quantile by the constructor but we
903
         * don't know the details about it at the moment so we just leave it "open"
904
         */
905
906
423
        result = decode_summary_entry(cmt, instance, metric->summary);
907
908
423
        if (result) {
909
0
            cmt_summary_destroy(instance);
910
0
        }
911
423
    }
912
1.93k
    else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_HISTOGRAM) {
913
1.01k
        instance = cmt_histogram_create(cmt,
914
1.01k
                                        metric_namespace,
915
1.01k
                                        metric_subsystem,
916
1.01k
                                        metric_name,
917
1.01k
                                        metric_description,
918
1.01k
                                        (struct cmt_histogram_buckets *) cmt,
919
1.01k
                                        0, NULL);
920
921
1.01k
        if (instance == NULL) {
922
2
            return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
923
2
        }
924
925
1.00k
        result = decode_histogram_entry(cmt, instance, metric->histogram);
926
927
1.00k
        if (result) {
928
0
            cmt_histogram_destroy(instance);
929
0
        }
930
1.00k
    }
931
932
3.19k
    return result;
933
3.20k
}
934
935
static int decode_scope_metadata_and_attributes(struct cfl_kvlist *external_metadata,
936
    Opentelemetry__Proto__Common__V1__InstrumentationScope *scope)
937
4.51k
{
938
4.51k
    struct cfl_kvlist *attributes;
939
4.51k
    struct cfl_kvlist *metadata;
940
4.51k
    int                result;
941
4.51k
    size_t             index;
942
4.51k
    struct cfl_kvlist *root;
943
944
4.51k
    root = get_or_create_external_metadata_kvlist(external_metadata, "scope");
945
946
4.51k
    if (root == NULL) {
947
0
        return -1;
948
0
    }
949
950
4.51k
    metadata = get_or_create_external_metadata_kvlist(root, "metadata");
951
952
4.51k
    if (metadata == NULL) {
953
0
        return -2;
954
0
    }
955
956
4.51k
    attributes = get_or_create_external_metadata_kvlist(root, "attributes");
957
958
4.51k
    if (attributes == NULL) {
959
0
        return -3;
960
0
    }
961
962
4.51k
    if (scope == NULL) {
963
4.36k
        return 0;
964
4.36k
    }
965
966
151
    if (scope->name != NULL) {
967
151
        result = cfl_kvlist_insert_string(metadata, "name", scope->name);
968
969
151
        if (result != 0) {
970
0
            return -4;
971
0
        }
972
151
    }
973
974
151
    if (scope->version != NULL) {
975
151
        result = cfl_kvlist_insert_string(metadata, "version", scope->version);
976
977
151
        if (result != 0) {
978
0
            return -5;
979
0
        }
980
151
    }
981
982
151
    result = cfl_kvlist_insert_int64(metadata, "dropped_attributes_count", scope->dropped_attributes_count);
983
984
151
    if (result != 0) {
985
0
        return -6;
986
0
    }
987
988
151
    for (index = 0 ;
989
151
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
990
151
         index < scope->n_attributes ;
991
151
         index++) {
992
0
         result = clone_kvlist_entry(attributes,
993
0
                                     scope->attributes[index]);
994
0
    }
995
996
151
    if (result != 0) {
997
0
        return -7;
998
0
    }
999
1000
151
    return 0;
1001
151
}
1002
1003
static int decode_scope_metrics_metadata(struct cfl_kvlist *external_metadata,
1004
    Opentelemetry__Proto__Metrics__V1__ScopeMetrics *scope_metrics)
1005
4.51k
{
1006
4.51k
    struct cfl_kvlist *scope_metrics_metadata;
1007
4.51k
    struct cfl_kvlist *scope_metrics_root;
1008
4.51k
    int                result;
1009
1010
4.51k
    scope_metrics_root = get_or_create_external_metadata_kvlist(external_metadata, "scope_metrics");
1011
1012
4.51k
    if (scope_metrics_root == NULL) {
1013
0
        return -1;
1014
0
    }
1015
1016
4.51k
    scope_metrics_metadata = get_or_create_external_metadata_kvlist(scope_metrics_root, "metadata");
1017
1018
4.51k
    if (scope_metrics_metadata == NULL) {
1019
0
        return -2;
1020
0
    }
1021
1022
4.51k
    if (scope_metrics == NULL) {
1023
0
        return 0;
1024
0
    }
1025
1026
4.51k
    if (scope_metrics->schema_url != NULL) {
1027
4.51k
        result = cfl_kvlist_insert_string(scope_metrics_metadata, "schema_url", scope_metrics->schema_url);
1028
1029
4.51k
        if (result != 0) {
1030
0
            return -3;
1031
0
        }
1032
4.51k
    }
1033
1034
4.51k
    return 0;
1035
4.51k
}
1036
1037
static int decode_scope_metrics_entry(struct cfl_list *context_list,
1038
    Opentelemetry__Proto__Metrics__V1__ScopeMetrics *metrics)
1039
4.51k
{
1040
4.51k
    struct cmt *context;
1041
4.51k
    int         result;
1042
4.51k
    size_t      index;
1043
1044
4.51k
    context = cmt_create();
1045
1046
4.51k
    if (context == NULL) {
1047
0
        return CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
1048
0
    }
1049
1050
4.51k
    cfl_list_add(&context->_head, context_list);
1051
1052
4.51k
    result = cfl_kvlist_insert_string(context->internal_metadata,
1053
4.51k
                                      "producer",
1054
4.51k
                                      "opentelemetry");
1055
1056
4.51k
    if (result != 0) {
1057
0
        result = CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
1058
0
    }
1059
1060
4.51k
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1061
4.51k
        result = decode_scope_metadata_and_attributes(context->external_metadata,
1062
4.51k
                                                      metrics->scope);
1063
1064
4.51k
        if (result != 0) {
1065
0
            result = CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
1066
0
        }
1067
4.51k
    }
1068
1069
4.51k
    if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1070
4.51k
        result = decode_scope_metrics_metadata(context->external_metadata,
1071
4.51k
                                               metrics);
1072
1073
4.51k
        if (result != 0) {
1074
0
            result = CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
1075
0
        }
1076
4.51k
    }
1077
1078
4.51k
    if (result != CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1079
0
        return result;
1080
0
    }
1081
1082
4.51k
    for (index = 0 ;
1083
7.71k
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
1084
7.71k
         index < metrics->n_metrics ;
1085
4.51k
         index++) {
1086
3.20k
        result = decode_metrics_entry(context,
1087
3.20k
                                      metrics->metrics[index]);
1088
3.20k
    }
1089
1090
4.51k
    return result;
1091
4.51k
}
1092
1093
1094
static int decode_resource_metadata_and_attributes(struct cfl_kvlist *external_metadata,
1095
    Opentelemetry__Proto__Resource__V1__Resource *resource)
1096
1.00k
{
1097
1.00k
    struct cfl_kvlist *attributes;
1098
1.00k
    struct cfl_kvlist *metadata;
1099
1.00k
    int                result;
1100
1.00k
    size_t             index;
1101
1.00k
    struct cfl_kvlist *root;
1102
1103
1.00k
    root = get_or_create_external_metadata_kvlist(external_metadata, "resource");
1104
1105
1.00k
    if (root == NULL) {
1106
0
        return -1;
1107
0
    }
1108
1109
1.00k
    metadata = get_or_create_external_metadata_kvlist(root, "metadata");
1110
1111
1.00k
    if (metadata == NULL) {
1112
0
        return -2;
1113
0
    }
1114
1115
1.00k
    attributes = get_or_create_external_metadata_kvlist(root, "attributes");
1116
1117
1.00k
    if (attributes == NULL) {
1118
0
        return -3;
1119
0
    }
1120
1121
1.00k
    if (resource == NULL) {
1122
0
        return 0;
1123
0
    }
1124
1125
1.00k
    result = cfl_kvlist_insert_int64(metadata, "dropped_attributes_count", (int64_t) resource->dropped_attributes_count);
1126
1127
1.00k
    if (result != 0) {
1128
0
        return -4;
1129
0
    }
1130
1131
1.00k
    for (index = 0 ;
1132
2.48k
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
1133
2.48k
         index < resource->n_attributes ;
1134
1.47k
         index++) {
1135
1.47k
         result = clone_kvlist_entry(attributes,
1136
1.47k
                                     resource->attributes[index]);
1137
1.47k
    }
1138
1139
1.00k
    if (result != CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1140
2
        return -5;
1141
2
    }
1142
1143
1.00k
    return 0;
1144
1.00k
}
1145
1146
static int decode_resource_metrics_metadata(struct cfl_kvlist *external_metadata,
1147
    Opentelemetry__Proto__Metrics__V1__ResourceMetrics *resource_metrics)
1148
4.50k
{
1149
4.50k
    struct cfl_kvlist *resource_metrics_metadata;
1150
4.50k
    struct cfl_kvlist *resource_metrics_root;
1151
4.50k
    int                result;
1152
1153
4.50k
    resource_metrics_root = get_or_create_external_metadata_kvlist(external_metadata, "resource_metrics");
1154
1155
4.50k
    if (resource_metrics_root == NULL) {
1156
0
        return -1;
1157
0
    }
1158
1159
4.50k
    resource_metrics_metadata = get_or_create_external_metadata_kvlist(resource_metrics_root, "metadata");
1160
1161
4.50k
    if (resource_metrics_metadata == NULL) {
1162
0
        return -2;
1163
0
    }
1164
1165
4.50k
    if (resource_metrics == NULL) {
1166
0
        return 0;
1167
0
    }
1168
1169
4.50k
    if (resource_metrics->schema_url != NULL) {
1170
4.50k
        result = cfl_kvlist_insert_string(resource_metrics_metadata, "schema_url", resource_metrics->schema_url);
1171
1172
4.50k
        if (result != 0) {
1173
0
            return -3;
1174
0
        }
1175
4.50k
    }
1176
1177
4.50k
    return 0;
1178
4.50k
}
1179
1180
static int decode_resource_metrics_entry(
1181
    struct cfl_list *context_list,
1182
    Opentelemetry__Proto__Metrics__V1__ResourceMetrics *resource_metrics)
1183
457k
{
1184
457k
    struct cmt *context;
1185
457k
    int         result;
1186
457k
    size_t      index;
1187
1188
457k
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
1189
1190
457k
    for (index = 0 ;
1191
461k
         result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
1192
461k
         index < resource_metrics->n_scope_metrics ;
1193
457k
         index++) {
1194
4.51k
        result = decode_scope_metrics_entry(context_list,
1195
4.51k
                    resource_metrics->scope_metrics[index]);
1196
1197
4.51k
        if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1198
4.50k
            context = cfl_list_entry_last(context_list, struct cmt, _head);
1199
1200
4.50k
            if (context != NULL) {
1201
4.50k
                if (resource_metrics->resource != NULL) {
1202
1.00k
                    result = decode_resource_metadata_and_attributes(context->external_metadata,
1203
1.00k
                                                                     resource_metrics->resource);
1204
1205
1.00k
                    if (result != 0) {
1206
2
                        result = CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
1207
2
                    }
1208
1.00k
                }
1209
1210
4.50k
                if (result == CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1211
4.50k
                    result = decode_resource_metrics_metadata(context->external_metadata,
1212
4.50k
                                                              resource_metrics);
1213
1214
4.50k
                    if (result != 0) {
1215
0
                        result = CMT_DECODE_OPENTELEMETRY_ALLOCATION_ERROR;
1216
0
                    }
1217
4.50k
                }
1218
4.50k
            }
1219
4.50k
        }
1220
4.51k
    }
1221
1222
457k
    return result;
1223
457k
}
1224
1225
static void destroy_context_list(struct cfl_list *context_list)
1226
165
{
1227
165
    struct cfl_list *iterator;
1228
165
    struct cmt      *context;
1229
165
    struct cfl_list *tmp;
1230
1231
4.51k
    cfl_list_foreach_safe(iterator, tmp, context_list) {
1232
4.51k
        context = cfl_list_entry(iterator, struct cmt, _head);
1233
1234
4.51k
        cfl_list_del(&context->_head);
1235
1236
4.51k
        cmt_destroy(context);
1237
4.51k
    }
1238
165
}
1239
1240
static int decode_service_request(struct cfl_list *context_list,
1241
    Opentelemetry__Proto__Collector__Metrics__V1__ExportMetricsServiceRequest *service_request)
1242
84
{
1243
84
    int    result;
1244
84
    size_t index;
1245
1246
84
    result = CMT_DECODE_OPENTELEMETRY_SUCCESS;
1247
1248
84
    if (service_request->n_resource_metrics > 0) {
1249
64
        for (index = 0 ;
1250
457k
             result == CMT_DECODE_OPENTELEMETRY_SUCCESS &&
1251
457k
             index < service_request->n_resource_metrics ;
1252
457k
             index++) {
1253
1254
457k
            result = decode_resource_metrics_entry(context_list,
1255
457k
                                                   service_request->resource_metrics[index]);
1256
457k
        }
1257
64
    }
1258
1259
84
    return result;
1260
84
}
1261
1262
int cmt_decode_opentelemetry_create(struct cfl_list *result_context_list,
1263
                                    char *in_buf, size_t in_size,
1264
                                    size_t *offset)
1265
165
{
1266
165
    Opentelemetry__Proto__Collector__Metrics__V1__ExportMetricsServiceRequest *service_request;
1267
165
    int                                                                        result;
1268
1269
165
    result = CMT_DECODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
1270
1271
165
    cfl_list_init(result_context_list);
1272
1273
165
    service_request = opentelemetry__proto__collector__metrics__v1__export_metrics_service_request__unpack(NULL, in_size - *offset,
1274
165
                                                                                                           (unsigned char *) &in_buf[*offset]);
1275
1276
165
    if (service_request != NULL) {
1277
84
        result = decode_service_request(result_context_list, service_request);
1278
1279
84
        opentelemetry__proto__collector__metrics__v1__export_metrics_service_request__free_unpacked(service_request, NULL);
1280
84
    }
1281
1282
165
    if (result != CMT_DECODE_OPENTELEMETRY_SUCCESS) {
1283
92
        destroy_context_list(result_context_list);
1284
92
    }
1285
1286
165
    return result;
1287
165
}
1288
1289
void cmt_decode_opentelemetry_destroy(struct cfl_list *context_list)
1290
73
{
1291
73
    if (context_list != NULL) {
1292
73
        destroy_context_list(context_list);
1293
73
    }
1294
73
}