summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/cmetrics/src/cmt_encode_opentelemetry.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/cmetrics/src/cmt_encode_opentelemetry.c')
-rw-r--r--fluent-bit/lib/cmetrics/src/cmt_encode_opentelemetry.c2592
1 files changed, 2592 insertions, 0 deletions
diff --git a/fluent-bit/lib/cmetrics/src/cmt_encode_opentelemetry.c b/fluent-bit/lib/cmetrics/src/cmt_encode_opentelemetry.c
new file mode 100644
index 00000000..8c934186
--- /dev/null
+++ b/fluent-bit/lib/cmetrics/src/cmt_encode_opentelemetry.c
@@ -0,0 +1,2592 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* CMetrics
+ * ========
+ * Copyright 2021-2022 The CMetrics Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <cmetrics/cmetrics.h>
+#include <cmetrics/cmt_metric.h>
+#include <cmetrics/cmt_map.h>
+#include <cmetrics/cmt_gauge.h>
+#include <cmetrics/cmt_counter.h>
+#include <cmetrics/cmt_untyped.h>
+#include <cmetrics/cmt_summary.h>
+#include <cmetrics/cmt_histogram.h>
+#include <cmetrics/cmt_encode_opentelemetry.h>
+
+static Opentelemetry__Proto__Metrics__V1__ScopeMetrics **
+ initialize_scope_metrics_list(
+ size_t element_count);
+
+static void destroy_scope_metric_list(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics **metric_list);
+
+struct cfl_kvlist *fetch_metadata_kvlist_key(
+ struct cfl_kvlist *kvlist, char *key)
+{
+ struct cfl_variant *entry_variant;
+ struct cfl_kvlist *entry_kvlist;
+
+ if (kvlist == NULL) {
+ return NULL;
+ }
+
+ entry_variant = cfl_kvlist_fetch(kvlist, key);
+
+ if (entry_variant != NULL) {
+ entry_kvlist = entry_variant->data.as_kvlist;
+ }
+ else {
+ entry_kvlist = NULL;
+ }
+
+ return entry_kvlist;
+}
+
+
+static int is_string_releaseable(char *address);
+
+static int is_metric_empty(struct cmt_map *map);
+
+static size_t get_metric_count(struct cmt *cmt);
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile *
+ initialize_summary_value_at_quantile(
+ double quantile, double value);
+
+static void destroy_summary_value_at_quantile(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile *value);
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile **
+ initialize_summary_value_at_quantile_list(
+ size_t element_count);
+
+static void destroy_summary_value_at_quantile_list(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile **list);
+
+
+static void destroy_metrics_data(
+ Opentelemetry__Proto__Metrics__V1__MetricsData *metrics_data);
+
+static Opentelemetry__Proto__Metrics__V1__MetricsData *
+ initialize_metrics_data(size_t resource_metrics_count);
+
+static void destroy_resource(
+ Opentelemetry__Proto__Resource__V1__Resource *resource);
+
+static void destroy_resource_metrics(
+ Opentelemetry__Proto__Metrics__V1__ResourceMetrics *resource_metrics);
+
+static Opentelemetry__Proto__Metrics__V1__ResourceMetrics *
+ initialize_resource_metrics(
+ struct cfl_kvlist *resource_metrics_root,
+ Opentelemetry__Proto__Resource__V1__Resource *resource,
+ size_t instrumentation_library_metrics_element_count);
+
+static void destroy_resource_metrics_list(
+ Opentelemetry__Proto__Metrics__V1__ResourceMetrics **resource_metrics_list);
+
+static Opentelemetry__Proto__Metrics__V1__ResourceMetrics **
+ initialize_resource_metrics_list(
+ size_t element_count);
+
+static Opentelemetry__Proto__Common__V1__InstrumentationScope *
+ initialize_instrumentation_scope(
+ struct cfl_kvlist *scope_root,
+ int *error_detection_flag);
+
+static void destroy_scope_metrics(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics *metric);
+
+static Opentelemetry__Proto__Metrics__V1__ScopeMetrics *
+ initialize_scope_metrics(
+ struct cfl_kvlist *scope_metrics_root,
+ size_t metric_element_count);
+
+static int append_metric_to_scope_metrics(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics *instrumentation_scope_metrics,
+ Opentelemetry__Proto__Metrics__V1__Metric *metric,
+ size_t metric_slot_hint);
+
+static void destroy_scope_metric_list(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics **metric_list);
+
+static void destroy_attribute(
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute);
+
+static Opentelemetry__Proto__Common__V1__KeyValue *
+ initialize_string_attribute(char *key, char *value);
+
+static void destroy_attribute_list(
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list);
+
+static Opentelemetry__Proto__Common__V1__KeyValue **
+ initialize_attribute_list(
+ size_t element_count);
+
+static void destroy_numerical_data_point(
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint *data_point);
+
+static void destroy_summary_data_point(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *data_point);
+
+static void destroy_histogram_data_point(
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *data_point);
+
+static void destroy_data_point(
+ void *data_point,
+ int data_point_type);
+
+static void destroy_numerical_data_point_list(
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint **data_point_list);
+
+static void destroy_summary_data_point_list(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint **data_point_list);
+
+static void destroy_histogram_data_point_list(
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint **data_point_list);
+
+static Opentelemetry__Proto__Metrics__V1__NumberDataPoint *
+ initialize_numerical_data_point(
+ uint64_t start_time,
+ uint64_t timestamp,
+ double value,
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list,
+ size_t attribute_count);
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *
+ initialize_summary_data_point(
+ uint64_t start_time,
+ uint64_t timestamp,
+ uint64_t count,
+ double sum,
+ size_t quantile_count,
+ double *quantile_list,
+ size_t value_count,
+ uint64_t *value_list,
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list,
+ size_t attribute_count);
+
+static Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *
+ initialize_histogram_data_point(
+ uint64_t start_time,
+ uint64_t timestamp,
+ uint64_t count,
+ double sum,
+ size_t bucket_count,
+ uint64_t *bucket_list,
+ size_t boundary_count,
+ double *boundary_list,
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list,
+ size_t attribute_count);
+
+static int append_attribute_to_numerical_data_point(
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint *data_point,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint);
+
+static int append_attribute_to_summary_data_point(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *data_point,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint);
+
+static int append_attribute_to_histogram_data_point(
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *data_point,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint);
+
+static int append_attribute_to_data_point(
+ void *data_point,
+ int data_point_type,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint);
+
+static int append_attribute_to_data_point(
+ void *data_point,
+ int data_point_type,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint);
+
+static Opentelemetry__Proto__Metrics__V1__NumberDataPoint **
+ initialize_numerical_data_point_list(
+ size_t element_count);
+
+static Opentelemetry__Proto__Metrics__V1__HistogramDataPoint **
+ initialize_histogram_data_point_list(
+ size_t element_count);
+
+static void destroy_metric(
+ Opentelemetry__Proto__Metrics__V1__Metric *metric);
+
+static Opentelemetry__Proto__Metrics__V1__Metric *
+ initialize_metric(int type,
+ char *name,
+ char *description,
+ char *unit,
+ int monotonism_flag,
+ int aggregation_temporality_type,
+ size_t data_point_count);
+
+static int append_data_point_to_metric(
+ Opentelemetry__Proto__Metrics__V1__Metric *metric,
+ void *data_point,
+ size_t data_point_slot_hint);
+
+static void destroy_metric_list(
+ Opentelemetry__Proto__Metrics__V1__Metric **metric_list);
+
+static Opentelemetry__Proto__Metrics__V1__Metric **
+ initialize_metric_list(
+ size_t element_count);
+
+void cmt_encode_opentelemetry_destroy(cfl_sds_t text);
+
+static void destroy_opentelemetry_context(
+ struct cmt_opentelemetry_context *context);
+
+static struct cmt_opentelemetry_context *initialize_opentelemetry_context(
+ struct cmt *cmt);
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_to_otlp_any_value(struct cfl_variant *value);
+static inline Opentelemetry__Proto__Common__V1__KeyValue *cfl_variant_kvpair_to_otlp_kvpair(struct cfl_kvpair *input_pair);
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_kvlist_to_otlp_any_value(struct cfl_variant *value);
+
+static inline void otlp_any_value_destroy(Opentelemetry__Proto__Common__V1__AnyValue *value);
+static inline void otlp_kvpair_destroy(Opentelemetry__Proto__Common__V1__KeyValue *kvpair);
+static inline void otlp_kvlist_destroy(Opentelemetry__Proto__Common__V1__KeyValueList *kvlist);
+static inline void otlp_array_destroy(Opentelemetry__Proto__Common__V1__ArrayValue *array);
+
+static inline void otlp_kvpair_list_destroy(Opentelemetry__Proto__Common__V1__KeyValue **pair_list, size_t entry_count);
+
+static inline void otlp_kvpair_destroy(Opentelemetry__Proto__Common__V1__KeyValue *kvpair)
+{
+ if (kvpair != NULL) {
+ if (kvpair->key != NULL) {
+ free(kvpair->key);
+ }
+
+ if (kvpair->value != NULL) {
+ otlp_any_value_destroy(kvpair->value);
+ }
+
+ free(kvpair);
+ }
+}
+
+static inline void otlp_kvlist_destroy(Opentelemetry__Proto__Common__V1__KeyValueList *kvlist)
+{
+ size_t index;
+
+ if (kvlist != NULL) {
+ if (kvlist->values != NULL) {
+ for (index = 0 ; index < kvlist->n_values ; index++) {
+ otlp_kvpair_destroy(kvlist->values[index]);
+ }
+
+ free(kvlist->values);
+ }
+
+ free(kvlist);
+ }
+}
+
+static inline void otlp_array_destroy(Opentelemetry__Proto__Common__V1__ArrayValue *array)
+{
+ size_t index;
+
+ if (array != NULL) {
+ if (array->values != NULL) {
+ for (index = 0 ; index < array->n_values ; index++) {
+ otlp_any_value_destroy(array->values[index]);
+ }
+
+ free(array->values);
+ }
+
+ free(array);
+ }
+}
+
+static inline void otlp_any_value_destroy(Opentelemetry__Proto__Common__V1__AnyValue *value)
+{
+ if (value != NULL) {
+ if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) {
+ if (value->string_value != NULL) {
+ free(value->string_value);
+ }
+ }
+ else if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_ARRAY_VALUE) {
+ if (value->array_value != NULL) {
+ otlp_array_destroy(value->array_value);
+ }
+ }
+ else if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_KVLIST_VALUE) {
+ if (value->kvlist_value != NULL) {
+ otlp_kvlist_destroy(value->kvlist_value);
+ }
+ }
+ else if (value->value_case == OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE) {
+ if (value->bytes_value.data != NULL) {
+ free(value->bytes_value.data);
+ }
+ }
+
+ free(value);
+ }
+}
+
+static inline Opentelemetry__Proto__Common__V1__KeyValue **otlp_kvpair_list_initialize(size_t entry_count)
+{
+ Opentelemetry__Proto__Common__V1__KeyValue **result;
+
+ result = \
+ calloc(entry_count, sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
+
+ return result;
+}
+
+
+static Opentelemetry__Proto__Common__V1__ArrayValue *otlp_array_value_initialize(size_t entry_count)
+{
+ Opentelemetry__Proto__Common__V1__ArrayValue *value;
+
+ value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__ArrayValue));
+
+ if (value != NULL) {
+ opentelemetry__proto__common__v1__array_value__init(value);
+
+ if (entry_count > 0) {
+ value->values = \
+ calloc(entry_count,
+ sizeof(Opentelemetry__Proto__Common__V1__AnyValue *));
+
+ if (value->values == NULL) {
+ free(value);
+
+ value = NULL;
+ }
+ else {
+ value->n_values = entry_count;
+ }
+ }
+ }
+
+ return value;
+}
+
+static Opentelemetry__Proto__Common__V1__KeyValue *otlp_kvpair_value_initialize()
+{
+ Opentelemetry__Proto__Common__V1__KeyValue *value;
+
+ value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue));
+
+ if (value != NULL) {
+ opentelemetry__proto__common__v1__key_value__init(value);
+ }
+
+ return value;
+}
+
+static Opentelemetry__Proto__Common__V1__KeyValueList *otlp_kvlist_value_initialize(size_t entry_count)
+{
+ Opentelemetry__Proto__Common__V1__KeyValueList *value;
+
+ value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValueList));
+
+ if (value != NULL) {
+ opentelemetry__proto__common__v1__key_value_list__init(value);
+
+ if (entry_count > 0) {
+ value->values = \
+ calloc(entry_count,
+ sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
+
+ if (value->values == NULL) {
+ free(value);
+
+ value = NULL;
+ }
+ else {
+ value->n_values = entry_count;
+ }
+ }
+ }
+
+ return value;
+}
+
+static Opentelemetry__Proto__Common__V1__AnyValue *otlp_any_value_initialize(int data_type, size_t entry_count)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *value;
+
+ value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue));
+
+ if (value == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__common__v1__any_value__init(value);
+
+ if (data_type == CFL_VARIANT_STRING) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE;
+ }
+ else if (data_type == CFL_VARIANT_BOOL) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BOOL_VALUE;
+ }
+ else if (data_type == CFL_VARIANT_INT) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_INT_VALUE;
+ }
+ else if (data_type == CFL_VARIANT_DOUBLE) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_DOUBLE_VALUE;
+ }
+ else if (data_type == CFL_VARIANT_ARRAY) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_ARRAY_VALUE;
+
+ value->array_value = otlp_array_value_initialize(entry_count);
+
+ if (value->array_value == NULL) {
+ free(value);
+
+ value = NULL;
+ }
+ }
+ else if (data_type == CFL_VARIANT_KVLIST) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_KVLIST_VALUE;
+
+ value->kvlist_value = otlp_kvlist_value_initialize(entry_count);
+
+ if (value->kvlist_value == NULL) {
+ free(value);
+
+ value = NULL;
+ }
+ }
+ else if (data_type == CFL_VARIANT_BYTES) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE;
+ }
+ else if (data_type == CFL_VARIANT_REFERENCE) {
+ value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE;
+ }
+ else {
+ free(value);
+
+ value = NULL;
+ }
+
+ return value;
+}
+
+static inline Opentelemetry__Proto__Common__V1__KeyValue *cfl_variant_kvpair_to_otlp_kvpair(struct cfl_kvpair *input_pair)
+{
+ Opentelemetry__Proto__Common__V1__KeyValue *pair;
+
+ pair = otlp_kvpair_value_initialize();
+
+ if (pair != NULL) {
+ pair->key = strdup(input_pair->key);
+
+ if (pair->key != NULL) {
+ pair->value = cfl_variant_to_otlp_any_value(input_pair->val);
+
+ if (pair->value == NULL) {
+ free(pair->key);
+
+ pair->key = NULL;
+ }
+ }
+
+ if (pair->key == NULL) {
+ free(pair);
+
+ pair = NULL;
+ }
+ }
+
+ return pair;
+}
+
+static inline void otlp_kvpair_list_destroy(Opentelemetry__Proto__Common__V1__KeyValue **pair_list, size_t entry_count)
+{
+ size_t index;
+
+ if (pair_list != NULL) {
+ for (index = 0 ; index < entry_count ; index++) {
+ otlp_kvpair_destroy(pair_list[index]);
+ }
+
+ free(pair_list);
+ }
+}
+
+static inline Opentelemetry__Proto__Common__V1__KeyValue **cfl_kvlist_to_otlp_kvpair_list(struct cfl_kvlist *kvlist)
+{
+ size_t entry_count;
+ Opentelemetry__Proto__Common__V1__KeyValue *keyvalue;
+ struct cfl_list *iterator;
+ Opentelemetry__Proto__Common__V1__KeyValue **result;
+ struct cfl_kvpair *kvpair;
+ size_t index;
+
+ entry_count = cfl_kvlist_count(kvlist);
+
+ result = otlp_kvpair_list_initialize(entry_count + 1);
+
+ if (result != NULL) {
+ index = 0;
+
+ cfl_list_foreach(iterator, &kvlist->list) {
+ kvpair = cfl_list_entry(iterator, struct cfl_kvpair, _head);
+
+ keyvalue = cfl_variant_kvpair_to_otlp_kvpair(kvpair);
+
+ if (keyvalue == NULL) {
+ otlp_kvpair_list_destroy(result, entry_count);
+
+ result = NULL;
+
+ break;
+ }
+
+ result[index++] = keyvalue;
+ }
+ }
+
+ return result;
+}
+
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_kvlist_to_otlp_any_value(struct cfl_variant *value)
+{
+ size_t entry_count;
+ Opentelemetry__Proto__Common__V1__KeyValue *keyvalue;
+ struct cfl_list *iterator;
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+ struct cfl_kvpair *kvpair;
+ struct cfl_kvlist *kvlist;
+ size_t index;
+
+
+ kvlist = value->data.as_kvlist;
+
+ entry_count = cfl_kvlist_count(kvlist);
+
+ result = otlp_any_value_initialize(CFL_VARIANT_KVLIST, entry_count);
+
+ if (result != NULL) {
+ index = 0;
+
+ cfl_list_foreach(iterator, &kvlist->list) {
+ kvpair = cfl_list_entry(iterator, struct cfl_kvpair, _head);
+
+ keyvalue = cfl_variant_kvpair_to_otlp_kvpair(kvpair);
+
+ if (keyvalue == NULL) {
+ otlp_any_value_destroy(result);
+
+ result = NULL;
+
+ break;
+ }
+
+ result->kvlist_value->values[index++] = keyvalue;
+ }
+ }
+
+ return result;
+}
+
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_array_to_otlp_any_value(struct cfl_variant *value)
+{
+ size_t entry_count;
+ Opentelemetry__Proto__Common__V1__AnyValue *entry_value;
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+ struct cfl_array *array;
+ size_t index;
+
+ array = value->data.as_array;
+
+ entry_count = array->entry_count;
+
+ result = otlp_any_value_initialize(CFL_VARIANT_ARRAY, entry_count);
+
+ if (result != NULL) {
+ index = 0;
+
+ for (index = 0 ; index < entry_count ; index++) {
+ entry_value = cfl_variant_to_otlp_any_value(cfl_array_fetch_by_index(array, index));
+
+ if (entry_value == NULL) {
+ otlp_any_value_destroy(result);
+
+ result = NULL;
+
+ break;
+ }
+
+ result->array_value->values[index] = entry_value;
+ }
+ }
+
+ return result;
+}
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_string_to_otlp_any_value(struct cfl_variant *value)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+
+ result = otlp_any_value_initialize(CFL_VARIANT_STRING, 0);
+
+ if (result != NULL) {
+ result->string_value = strdup(value->data.as_string);
+
+ if (result->string_value == NULL) {
+ otlp_any_value_destroy(result);
+
+ result = NULL;
+ }
+ }
+
+ return result;
+}
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_boolean_to_otlp_any_value(struct cfl_variant *value)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+
+ result = otlp_any_value_initialize(CFL_VARIANT_BOOL, 0);
+
+ if (result != NULL) {
+ result->bool_value = value->data.as_bool;
+ }
+
+ return result;
+}
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_int64_to_otlp_any_value(struct cfl_variant *value)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+
+ result = otlp_any_value_initialize(CFL_VARIANT_INT, 0);
+
+ if (result != NULL) {
+ result->int_value = value->data.as_int64;
+ }
+
+ return result;
+}
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_double_to_otlp_any_value(struct cfl_variant *value)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+
+ result = otlp_any_value_initialize(CFL_VARIANT_DOUBLE, 0);
+
+ if (result != NULL) {
+ result->double_value = value->data.as_double;
+ }
+
+ return result;
+}
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_binary_to_otlp_any_value(struct cfl_variant *value)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+
+ result = otlp_any_value_initialize(CFL_VARIANT_BYTES, 0);
+
+ if (result != NULL) {
+ result->bytes_value.len = cfl_sds_len(value->data.as_bytes);
+ result->bytes_value.data = calloc(result->bytes_value.len, sizeof(char));
+
+ if (result->bytes_value.data == NULL) {
+ otlp_any_value_destroy(result);
+
+ result = NULL;
+ }
+
+ memcpy(result->bytes_value.data, value->data.as_bytes, result->bytes_value.len);
+ }
+
+ return result;
+}
+
+static inline Opentelemetry__Proto__Common__V1__AnyValue *cfl_variant_to_otlp_any_value(struct cfl_variant *value)
+{
+ Opentelemetry__Proto__Common__V1__AnyValue *result;
+
+ if (value->type == CFL_VARIANT_STRING) {
+ result = cfl_variant_string_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_BOOL) {
+ result = cfl_variant_boolean_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_INT) {
+ result = cfl_variant_int64_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_DOUBLE) {
+ result = cfl_variant_double_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_ARRAY) {
+ result = cfl_variant_array_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_KVLIST) {
+ result = cfl_variant_kvlist_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_BYTES) {
+ result = cfl_variant_binary_to_otlp_any_value(value);
+ }
+ else if (value->type == CFL_VARIANT_REFERENCE) {
+ result = cfl_variant_string_to_otlp_any_value(value);
+ }
+ else {
+ result = NULL;
+ }
+
+ return result;
+}
+
+static char *fetch_metadata_string_key(struct cfl_kvlist *metadata, char *key_name, int *error_flag)
+{
+ struct cfl_variant *value;
+
+ *error_flag = CMT_FALSE;
+
+ value = cfl_kvlist_fetch(metadata, key_name);
+
+ if (value == NULL) {
+ return NULL;
+ }
+
+ if (value->type != CFL_VARIANT_STRING) {
+ *error_flag = CMT_TRUE;
+
+ return NULL;
+ }
+
+ return cfl_sds_create(value->data.as_string);
+}
+
+static int64_t fetch_metadata_int64_key(struct cfl_kvlist *metadata, char *key_name, int *error_flag)
+{
+ struct cfl_variant *value;
+
+ *error_flag = CMT_FALSE;
+
+ value = cfl_kvlist_fetch(metadata, key_name);
+
+ if (value == NULL) {
+ return 0;
+ }
+
+ if (value->type != CFL_VARIANT_INT) {
+ *error_flag = CMT_TRUE;
+
+ return 0;
+ }
+
+ return value->data.as_int64;
+}
+
+static int is_string_releaseable(char *address)
+ {
+ return (address != NULL &&
+ address != protobuf_c_empty_string);
+}
+
+static int is_metric_empty(struct cmt_map *map)
+{
+ size_t sample_count;
+
+ sample_count = cfl_list_size(&map->metrics);
+
+ if (map->metric_static_set) {
+ sample_count++;
+ }
+
+ return (sample_count == 0);
+}
+
+static size_t get_metric_count(struct cmt *cmt)
+{
+ size_t metric_count;
+ struct cmt_histogram *histogram;
+ struct cmt_summary *summary;
+ struct cmt_untyped *untyped;
+ struct cmt_counter *counter;
+ struct cmt_gauge *gauge;
+ struct cfl_list *head;
+
+ metric_count = 0;
+
+ cfl_list_foreach(head, &cmt->counters) {
+ counter = cfl_list_entry(head, struct cmt_counter, _head);
+
+ metric_count += !is_metric_empty(counter->map);
+ }
+
+ cfl_list_foreach(head, &cmt->gauges) {
+ gauge = cfl_list_entry(head, struct cmt_gauge, _head);
+
+ metric_count += !is_metric_empty(gauge->map);
+ }
+
+ cfl_list_foreach(head, &cmt->untypeds) {
+ untyped = cfl_list_entry(head, struct cmt_untyped, _head);
+
+ metric_count += !is_metric_empty(untyped->map);
+ }
+
+ cfl_list_foreach(head, &cmt->summaries) {
+ summary = cfl_list_entry(head, struct cmt_summary, _head);
+
+ metric_count += !is_metric_empty(summary->map);
+ }
+
+ cfl_list_foreach(head, &cmt->histograms) {
+ histogram = cfl_list_entry(head, struct cmt_histogram, _head);
+
+ metric_count += !is_metric_empty(histogram->map);
+ }
+
+ return metric_count;
+}
+
+static void destroy_metrics_data(
+ Opentelemetry__Proto__Metrics__V1__MetricsData *metrics_data)
+{
+ if (metrics_data != NULL) {
+ destroy_resource_metrics_list(metrics_data->resource_metrics);
+
+ free(metrics_data);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__MetricsData *
+ initialize_metrics_data(size_t resource_metrics_count)
+{
+ Opentelemetry__Proto__Metrics__V1__MetricsData *metrics_data;
+
+ metrics_data = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__MetricsData));
+
+ if (metrics_data == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__metrics_data__init(metrics_data);
+
+ metrics_data->resource_metrics = initialize_resource_metrics_list(resource_metrics_count);
+
+ if (metrics_data->resource_metrics == NULL) {
+ destroy_metrics_data(metrics_data);
+
+ return NULL;
+ }
+
+ metrics_data->n_resource_metrics = resource_metrics_count;
+
+ return metrics_data;
+}
+
+static void destroy_resource(
+ Opentelemetry__Proto__Resource__V1__Resource *resource)
+{
+ if (resource != NULL) {
+ if (resource->attributes != NULL) {
+ otlp_kvpair_list_destroy(resource->attributes, resource->n_attributes);
+ }
+
+ free(resource);
+ }
+}
+
+static void destroy_resource_metrics(
+ Opentelemetry__Proto__Metrics__V1__ResourceMetrics *resource_metrics)
+{
+ if (resource_metrics != NULL) {
+ if (is_string_releaseable(resource_metrics->schema_url)) {
+ cfl_sds_destroy(resource_metrics->schema_url);
+ }
+
+ if (resource_metrics->resource != NULL) {
+ destroy_resource(resource_metrics->resource);
+ }
+
+ if (resource_metrics->scope_metrics != NULL) {
+ destroy_scope_metric_list(resource_metrics->scope_metrics);
+ }
+
+ free(resource_metrics);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__ResourceMetrics *
+ initialize_resource_metrics(
+ struct cfl_kvlist *resource_metrics_root,
+ Opentelemetry__Proto__Resource__V1__Resource *resource,
+ size_t scope_metrics_element_count)
+{
+ int error_detection_flag;
+ Opentelemetry__Proto__Metrics__V1__ResourceMetrics *resource_metrics;
+ struct cfl_kvlist *metadata;
+
+ metadata = fetch_metadata_kvlist_key(resource_metrics_root, "metadata");
+
+ resource_metrics = \
+ calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__ResourceMetrics));
+
+ if (resource_metrics == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__resource_metrics__init(
+ resource_metrics);
+
+ if (metadata != NULL) {
+ resource_metrics->schema_url = fetch_metadata_string_key(metadata, "schema_url", &error_detection_flag);
+ }
+ else {
+ error_detection_flag = CMT_FALSE;
+ }
+
+ if (error_detection_flag) {
+ destroy_resource_metrics(resource_metrics);
+
+ return NULL;
+ }
+
+ resource_metrics->scope_metrics = \
+ initialize_scope_metrics_list(
+ scope_metrics_element_count);
+
+ if (resource_metrics->scope_metrics == NULL) {
+ destroy_resource_metrics(resource_metrics);
+
+ return NULL;
+ }
+
+ resource_metrics->n_scope_metrics = \
+ scope_metrics_element_count;
+
+ resource_metrics->resource = resource;
+
+ return resource_metrics;
+}
+
+static void destroy_resource_metrics_list(
+ Opentelemetry__Proto__Metrics__V1__ResourceMetrics **metric_list)
+{
+ size_t element_index;
+
+ if (metric_list != NULL) {
+ for (element_index = 0 ;
+ metric_list[element_index] != NULL ;
+ element_index++) {
+ destroy_resource_metrics(metric_list[element_index]);
+
+ metric_list[element_index] = NULL;
+ }
+
+ free(metric_list);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__ResourceMetrics **
+ initialize_resource_metrics_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__ResourceMetrics **metric_list;
+
+ metric_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__ResourceMetrics *));
+
+ return metric_list;
+}
+
+static void destroy_scope_metrics(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics *metric)
+{
+ if (metric != NULL) {
+ destroy_metric_list(metric->metrics);
+
+ free(metric);
+ }
+}
+
+void destroy_instrumentation_scope(Opentelemetry__Proto__Common__V1__InstrumentationScope *scope)
+{
+ if (scope->name != NULL) {
+ cfl_sds_destroy(scope->name);
+ }
+
+ if (scope->version != NULL) {
+ cfl_sds_destroy(scope->version);
+ }
+
+ if (scope->attributes != NULL) {
+ destroy_attribute_list(scope->attributes);
+ }
+
+ free(scope);
+}
+
+static Opentelemetry__Proto__Common__V1__InstrumentationScope *
+ initialize_instrumentation_scope(
+ struct cfl_kvlist *scope_root,
+ int *error_detection_flag)
+{
+ struct cfl_kvlist *attributes;
+ struct cfl_kvlist *metadata;
+ Opentelemetry__Proto__Common__V1__InstrumentationScope *scope;
+
+ *error_detection_flag = CMT_FALSE;
+
+ if (scope_root == NULL) {
+ return NULL;
+ }
+
+ attributes = fetch_metadata_kvlist_key(scope_root, "attributes");
+ metadata = fetch_metadata_kvlist_key(scope_root, "metadata");
+
+ if (cfl_kvlist_count(attributes) == 0 &&
+ cfl_kvlist_count(metadata) == 0) {
+ return NULL;
+ }
+
+ scope = \
+ calloc(1, sizeof(Opentelemetry__Proto__Common__V1__InstrumentationScope));
+
+ if (scope == NULL) {
+ *error_detection_flag = CMT_TRUE;
+
+ return NULL;
+ }
+
+ opentelemetry__proto__common__v1__instrumentation_scope__init(scope);
+
+ scope->attributes = cfl_kvlist_to_otlp_kvpair_list(attributes);
+
+ if (scope->attributes == NULL) {
+ *error_detection_flag = CMT_TRUE;
+ }
+
+ scope->n_attributes = cfl_kvlist_count(attributes);
+
+ if (!(*error_detection_flag)) {
+ scope->dropped_attributes_count = (uint32_t) fetch_metadata_int64_key(
+ metadata,
+ "dropped_attributes_count",
+ error_detection_flag);
+ }
+
+ if (!(*error_detection_flag)) {
+ scope->name = fetch_metadata_string_key(metadata, "name", error_detection_flag);
+ }
+
+ if (!(*error_detection_flag)) {
+ scope->version = fetch_metadata_string_key(metadata, "version", error_detection_flag);
+ }
+
+ if (*error_detection_flag &&
+ scope != NULL) {
+ destroy_instrumentation_scope(scope);
+
+ scope = NULL;
+ }
+
+ return scope;
+}
+
+static Opentelemetry__Proto__Metrics__V1__ScopeMetrics *
+ initialize_scope_metrics(
+ struct cfl_kvlist *scope_metrics_root,
+ size_t metric_element_count)
+{
+ int error_detection_flag;
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics *scope_metrics;
+ struct cfl_kvlist *metadata;
+
+ metadata = fetch_metadata_kvlist_key(scope_metrics_root, "metadata");
+
+ scope_metrics = \
+ calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__ScopeMetrics));
+
+ if (scope_metrics == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__scope_metrics__init(scope_metrics);
+
+ error_detection_flag = CMT_FALSE;
+
+ if (metric_element_count > 0) {
+ scope_metrics->metrics = \
+ initialize_metric_list(metric_element_count);
+
+ if (scope_metrics->metrics == NULL) {
+ error_detection_flag = CMT_TRUE;
+ }
+ else {
+ scope_metrics->n_metrics = metric_element_count;
+ }
+ }
+
+ if (!error_detection_flag && metadata != NULL) {
+ scope_metrics->schema_url = fetch_metadata_string_key(metadata, "schema_url", &error_detection_flag);
+ }
+
+ if (error_detection_flag &&
+ scope_metrics != NULL) {
+ destroy_scope_metrics(scope_metrics);
+
+ scope_metrics = NULL;
+ }
+
+ return scope_metrics;
+}
+
+static int append_metric_to_scope_metrics(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics *metrics,
+ Opentelemetry__Proto__Metrics__V1__Metric *metric,
+ size_t metric_slot_hint)
+{
+ size_t metric_slot_index;
+
+ for (metric_slot_index = metric_slot_hint ;
+ metric_slot_index < metrics->n_metrics;
+ metric_slot_index++) {
+ if (metrics->metrics[metric_slot_index] == NULL) {
+ metrics->metrics[metric_slot_index] = metric;
+
+ return CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+ }
+ }
+
+ return CMT_ENCODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
+}
+
+static void destroy_scope_metric_list(
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics **metric_list)
+{
+ size_t element_index;
+
+ if (metric_list != NULL) {
+ for (element_index = 0 ;
+ metric_list[element_index] != NULL ;
+ element_index++) {
+ destroy_scope_metrics(metric_list[element_index]);
+
+ metric_list[element_index] = NULL;
+ }
+
+ free(metric_list);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__ScopeMetrics **
+ initialize_scope_metrics_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__ScopeMetrics **metric_list;
+
+ metric_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__ScopeMetrics *));
+
+ return metric_list;
+}
+
+static void destroy_attribute(
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute)
+{
+ if (attribute != NULL) {
+ if (attribute->value != NULL) {
+ if (attribute->value->value_case == \
+ OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) {
+ if (is_string_releaseable(attribute->value->string_value)) {
+ cfl_sds_destroy(attribute->value->string_value);
+ }
+ }
+
+ free(attribute->value);
+ }
+
+ if (is_string_releaseable(attribute->key)) {
+ cfl_sds_destroy(attribute->key);
+ }
+
+ free(attribute);
+ }
+}
+
+static Opentelemetry__Proto__Common__V1__KeyValue *
+ initialize_string_attribute(char *key, char *value)
+{
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute;
+
+ attribute = calloc(1,
+ sizeof(Opentelemetry__Proto__Common__V1__KeyValue));
+
+ if (attribute == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__common__v1__key_value__init(attribute);
+
+ attribute->value = calloc(1,
+ sizeof(Opentelemetry__Proto__Common__V1__AnyValue));
+
+ if (attribute->value == NULL) {
+ destroy_attribute(attribute);
+
+ return NULL;
+ }
+
+ opentelemetry__proto__common__v1__any_value__init(attribute->value);
+
+ attribute->value->string_value = cfl_sds_create(value);
+
+ if (attribute->value->string_value == NULL) {
+ destroy_attribute(attribute);
+
+ return NULL;
+ }
+
+ attribute->value->value_case = OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE;
+
+ attribute->key = cfl_sds_create(key);
+
+ if (attribute->key == NULL) {
+ destroy_attribute(attribute);
+
+ return NULL;
+ }
+
+ return attribute;
+}
+
+static void destroy_attribute_list(
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list)
+{
+ size_t element_index;
+
+ if (attribute_list != NULL) {
+ for (element_index = 0 ;
+ attribute_list[element_index] != NULL ;
+ element_index++) {
+ destroy_attribute(attribute_list[element_index]);
+
+ attribute_list[element_index] = NULL;
+ }
+
+ free(attribute_list);
+ }
+}
+
+static Opentelemetry__Proto__Common__V1__KeyValue **
+ initialize_attribute_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list;
+
+ attribute_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
+
+ return attribute_list;
+}
+
+static void destroy_numerical_data_point(
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint *data_point)
+{
+ if (data_point != NULL) {
+ destroy_attribute_list(data_point->attributes);
+
+ free(data_point);
+ }
+}
+
+static void destroy_summary_data_point(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *data_point)
+{
+ if (data_point != NULL) {
+ destroy_attribute_list(data_point->attributes);
+
+ if (data_point->quantile_values != NULL) {
+ destroy_summary_value_at_quantile_list(data_point->quantile_values);
+ }
+
+ free(data_point);
+ }
+}
+
+static void destroy_histogram_data_point(
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *data_point)
+{
+ if (data_point != NULL) {
+ destroy_attribute_list(data_point->attributes);
+
+ if (data_point->bucket_counts != NULL) {
+ free(data_point->bucket_counts);
+ }
+
+ if (data_point->explicit_bounds != NULL) {
+ free(data_point->explicit_bounds);
+ }
+
+ free(data_point);
+ }
+}
+
+static void destroy_data_point(
+ void *data_point,
+ int data_point_type)
+{
+ switch (data_point_type) {
+ case CMT_COUNTER:
+ case CMT_GAUGE:
+ case CMT_UNTYPED:
+ return destroy_numerical_data_point(data_point);
+ case CMT_SUMMARY:
+ return destroy_summary_data_point(data_point);
+ case CMT_HISTOGRAM:
+ return destroy_histogram_data_point(data_point);
+ }
+}
+
+static void destroy_numerical_data_point_list(
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint **data_point_list)
+{
+ size_t element_index;
+
+ if (data_point_list != NULL) {
+ for (element_index = 0 ;
+ data_point_list[element_index] != NULL ;
+ element_index++) {
+ destroy_numerical_data_point(data_point_list[element_index]);
+
+ data_point_list[element_index] = NULL;
+ }
+
+ free(data_point_list);
+ }
+}
+
+static void destroy_summary_data_point_list(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint **data_point_list)
+{
+ size_t element_index;
+
+ if (data_point_list != NULL) {
+ for (element_index = 0 ;
+ data_point_list[element_index] != NULL ;
+ element_index++) {
+ destroy_summary_data_point(data_point_list[element_index]);
+
+ data_point_list[element_index] = NULL;
+ }
+
+ free(data_point_list);
+ }
+}
+
+static void destroy_histogram_data_point_list(
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint **data_point_list)
+{
+ size_t element_index;
+
+ if (data_point_list != NULL) {
+ for (element_index = 0 ;
+ data_point_list[element_index] != NULL ;
+ element_index++) {
+ destroy_histogram_data_point(data_point_list[element_index]);
+
+ data_point_list[element_index] = NULL;
+ }
+
+ free(data_point_list);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__NumberDataPoint *
+ initialize_numerical_data_point(
+ uint64_t start_time,
+ uint64_t timestamp,
+ double value,
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list,
+ size_t attribute_count)
+{
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint *data_point;
+
+ data_point = calloc(1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__NumberDataPoint));
+
+ if (data_point == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__number_data_point__init(data_point);
+
+ data_point->start_time_unix_nano = start_time;
+ data_point->time_unix_nano = timestamp;
+ data_point->value_case = OPENTELEMETRY__PROTO__METRICS__V1__NUMBER_DATA_POINT__VALUE_AS_DOUBLE;
+ data_point->as_double = value;
+ data_point->attributes = attribute_list;
+ data_point->n_attributes = attribute_count;
+
+ return data_point;
+}
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile *
+ initialize_summary_value_at_quantile(
+ double quantile, double value)
+{
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile *instance;
+
+ instance = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile));
+
+ if (instance != NULL) {
+ opentelemetry__proto__metrics__v1__summary_data_point__value_at_quantile__init(instance);
+
+ instance->quantile = quantile;
+ instance->value = value;
+ }
+
+ return instance;
+}
+
+static void destroy_summary_value_at_quantile(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile *value)
+{
+ if (value != NULL) {
+ free(value);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile **
+ initialize_summary_value_at_quantile_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile **list;
+
+ list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile *));
+
+ return list;
+}
+
+static void destroy_summary_value_at_quantile_list(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint__ValueAtQuantile **list)
+{
+ size_t index;
+
+ if (list != NULL) {
+ for (index = 0 ;
+ list[index] != NULL ;
+ index++) {
+ destroy_summary_value_at_quantile(list[index]);
+
+ list[index] = NULL;
+ }
+
+ free(list);
+ }
+}
+
+
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *
+ initialize_summary_data_point(
+ uint64_t start_time,
+ uint64_t timestamp,
+ uint64_t count,
+ double sum,
+ size_t quantile_count,
+ double *quantile_list,
+ size_t value_count,
+ uint64_t *value_list,
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list,
+ size_t attribute_count)
+{
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *data_point;
+ size_t index;
+
+ data_point = calloc(1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__SummaryDataPoint));
+
+ if (data_point == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__summary_data_point__init(data_point);
+
+ data_point->start_time_unix_nano = start_time;
+ data_point->time_unix_nano = timestamp;
+
+ data_point->count = count;
+ data_point->sum = sum;
+ data_point->n_quantile_values = quantile_count;
+
+ data_point->quantile_values = initialize_summary_value_at_quantile_list(quantile_count);
+
+ if (data_point->quantile_values == NULL) {
+ cmt_errno();
+
+ free(data_point);
+
+ return NULL;
+ }
+
+ if (quantile_count > 0) {
+ if (value_list != NULL) {
+ for (index = 0 ; index < quantile_count ; index++) {
+ data_point->quantile_values[index] =
+ initialize_summary_value_at_quantile(quantile_list[index],
+ cmt_math_uint64_to_d64(value_list[index]));
+
+ if (data_point->quantile_values[index] == NULL) {
+ destroy_summary_value_at_quantile_list(data_point->quantile_values);
+
+ free(data_point);
+
+ return NULL;
+ }
+ }
+ }
+ }
+
+ data_point->attributes = attribute_list;
+ data_point->n_attributes = attribute_count;
+
+ return data_point;
+}
+
+static Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *
+ initialize_histogram_data_point(
+ uint64_t start_time,
+ uint64_t timestamp,
+ uint64_t count,
+ double sum,
+ size_t bucket_count,
+ uint64_t *bucket_list,
+ size_t boundary_count,
+ double *boundary_list,
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list,
+ size_t attribute_count)
+{
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *data_point;
+ size_t index;
+
+ data_point = calloc(1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__HistogramDataPoint));
+
+ if (data_point == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__histogram_data_point__init(data_point);
+
+ data_point->start_time_unix_nano = start_time;
+ data_point->time_unix_nano = timestamp;
+
+ data_point->count = count;
+ data_point->n_bucket_counts = bucket_count;
+
+ data_point->sum = sum;
+
+ if (bucket_count > 0) {
+ data_point->bucket_counts = calloc(bucket_count, sizeof(uint64_t));
+
+ if (data_point->bucket_counts == NULL) {
+ cmt_errno();
+
+ free(data_point);
+
+ return NULL;
+ }
+
+ if (bucket_list != NULL) {
+ for (index = 0 ; index < bucket_count ; index++) {
+ data_point->bucket_counts[index] = bucket_list[index];
+ }
+ }
+ }
+
+ data_point->n_explicit_bounds = boundary_count;
+
+ if (boundary_count > 0) {
+ data_point->explicit_bounds = calloc(boundary_count, sizeof(uint64_t));
+
+ if (data_point->explicit_bounds == NULL) {
+ cmt_errno();
+
+ if (data_point->bucket_counts != NULL) {
+ free(data_point->bucket_counts);
+ }
+
+ free(data_point);
+
+ return NULL;
+ }
+
+ if (boundary_list != NULL) {
+ for (index = 0 ; index < boundary_count ; index++) {
+ data_point->explicit_bounds[index] = boundary_list[index];
+ }
+ }
+ }
+
+ data_point->attributes = attribute_list;
+ data_point->n_attributes = attribute_count;
+
+ return data_point;
+}
+
+static int append_attribute_to_numerical_data_point(
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint *data_point,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint)
+{
+ size_t attribute_slot_index;
+
+ for (attribute_slot_index = attribute_slot_hint ;
+ attribute_slot_index < data_point->n_attributes;
+ attribute_slot_index++) {
+ if (data_point->attributes[attribute_slot_index] == NULL) {
+ data_point->attributes[attribute_slot_index] = attribute;
+
+ return CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+ }
+ }
+
+ return CMT_ENCODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
+}
+
+static int append_attribute_to_summary_data_point(
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *data_point,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint)
+{
+ size_t attribute_slot_index;
+
+ for (attribute_slot_index = attribute_slot_hint ;
+ attribute_slot_index < data_point->n_attributes;
+ attribute_slot_index++) {
+ if (data_point->attributes[attribute_slot_index] == NULL) {
+ data_point->attributes[attribute_slot_index] = attribute;
+
+ return CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+ }
+ }
+
+ return CMT_ENCODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
+}
+
+static int append_attribute_to_histogram_data_point(
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *data_point,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint)
+{
+ size_t attribute_slot_index;
+
+ for (attribute_slot_index = attribute_slot_hint ;
+ attribute_slot_index < data_point->n_attributes;
+ attribute_slot_index++) {
+ if (data_point->attributes[attribute_slot_index] == NULL) {
+ data_point->attributes[attribute_slot_index] = attribute;
+
+ return CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+ }
+ }
+
+ return CMT_ENCODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
+}
+
+static int append_attribute_to_data_point(
+ void *data_point,
+ int data_point_type,
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute,
+ size_t attribute_slot_hint)
+{
+ switch (data_point_type) {
+ case CMT_COUNTER:
+ case CMT_GAUGE:
+ case CMT_UNTYPED:
+ return append_attribute_to_numerical_data_point(data_point,
+ attribute,
+ attribute_slot_hint);
+ case CMT_SUMMARY:
+ return append_attribute_to_summary_data_point(data_point,
+ attribute,
+ attribute_slot_hint);
+ case CMT_HISTOGRAM:
+ return append_attribute_to_histogram_data_point(data_point,
+ attribute,
+ attribute_slot_hint);
+ }
+
+ return CMT_ENCODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
+}
+
+static Opentelemetry__Proto__Metrics__V1__NumberDataPoint **
+ initialize_numerical_data_point_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__NumberDataPoint **data_point_list;
+
+ data_point_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__NumberDataPoint *));
+
+ return data_point_list;
+}
+
+static Opentelemetry__Proto__Metrics__V1__SummaryDataPoint **
+ initialize_summary_data_point_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__SummaryDataPoint **data_point_list;
+
+ data_point_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__SummaryDataPoint *));
+
+ return data_point_list;
+}
+
+static Opentelemetry__Proto__Metrics__V1__HistogramDataPoint **
+ initialize_histogram_data_point_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__HistogramDataPoint **data_point_list;
+
+ data_point_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__HistogramDataPoint *));
+
+ if (data_point_list == NULL) {
+ return NULL;
+ }
+
+ return data_point_list;
+}
+
+static void destroy_metric(
+ Opentelemetry__Proto__Metrics__V1__Metric *metric)
+{
+ if (metric != NULL) {
+ if (is_string_releaseable(metric->name)) {
+ cfl_sds_destroy(metric->name);
+ metric->name = NULL;
+ }
+
+ if (is_string_releaseable(metric->description)) {
+ cfl_sds_destroy(metric->description);
+ metric->description = NULL;
+ }
+
+ if (is_string_releaseable(metric->unit)) {
+ cfl_sds_destroy(metric->unit);
+ metric->unit = NULL;
+ }
+
+ if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUM) {
+ destroy_numerical_data_point_list(metric->sum->data_points);
+
+ free(metric->sum);
+ }
+ else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_GAUGE) {
+ destroy_numerical_data_point_list(metric->gauge->data_points);
+
+ free(metric->gauge);
+ }
+ else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUMMARY) {
+ destroy_summary_data_point_list(metric->summary->data_points);
+
+ free(metric->histogram);
+ }
+ else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_HISTOGRAM) {
+ destroy_histogram_data_point_list(metric->histogram->data_points);
+
+ free(metric->histogram);
+ }
+
+ free(metric);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__Metric *
+ initialize_metric(int type,
+ char *name,
+ char *description,
+ char *unit,
+ int monotonism_flag,
+ int aggregation_temporality_type,
+ size_t data_point_count)
+{
+ Opentelemetry__Proto__Metrics__V1__Metric *metric;
+
+ metric = calloc(1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__Metric));
+
+ if (metric == NULL) {
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__metric__init(metric);
+
+ metric->name = cfl_sds_create(name);
+
+ if (metric->name == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ if (description != NULL) {
+ metric->description = cfl_sds_create(description);
+
+ if (metric->description == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+ }
+
+ if (unit != NULL) {
+ metric->unit = cfl_sds_create(unit);
+
+ if (metric->unit == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+ }
+
+ if (type == CMT_COUNTER) {
+ metric->sum = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__Sum));
+
+ if (metric->sum == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__sum__init(metric->sum);
+
+ metric->data_case = OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUM;
+ metric->sum->data_points = initialize_numerical_data_point_list(data_point_count);
+
+ if (metric->sum->data_points == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+
+ metric->sum->aggregation_temporality = aggregation_temporality_type;
+ metric->sum->is_monotonic = monotonism_flag;
+ metric->sum->n_data_points = data_point_count;
+ }
+ else if (type == CMT_UNTYPED) {
+ metric->gauge = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__Gauge));
+
+ if (metric->gauge == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__gauge__init(metric->gauge);
+
+ metric->data_case = OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_GAUGE;
+ metric->gauge->data_points = initialize_numerical_data_point_list(data_point_count);
+
+ if (metric->gauge->data_points == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ metric->gauge->n_data_points = data_point_count;
+ }
+ else if (type == CMT_GAUGE) {
+ metric->gauge = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__Gauge));
+
+ if (metric->gauge == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__gauge__init(metric->gauge);
+
+ metric->data_case = OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_GAUGE;
+ metric->gauge->data_points = initialize_numerical_data_point_list(data_point_count);
+
+ if (metric->gauge->data_points == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ metric->gauge->n_data_points = data_point_count;
+ }
+ else if (type == CMT_SUMMARY) {
+ metric->summary = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__Summary));
+
+ if (metric->summary == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__summary__init(metric->summary);
+
+ metric->data_case = OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUMMARY;
+ metric->summary->data_points = initialize_summary_data_point_list(data_point_count);
+
+ if (metric->summary->data_points == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ metric->summary->n_data_points = data_point_count;
+ }
+ else if (type == CMT_HISTOGRAM) {
+ metric->histogram = calloc(1, sizeof(Opentelemetry__Proto__Metrics__V1__Histogram));
+
+ if (metric->histogram == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ opentelemetry__proto__metrics__v1__histogram__init(metric->histogram);
+
+ metric->data_case = OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_HISTOGRAM;
+ metric->histogram->data_points = initialize_histogram_data_point_list(data_point_count);
+
+ if (metric->histogram->data_points == NULL) {
+ destroy_metric(metric);
+
+ return NULL;
+ }
+
+ metric->histogram->n_data_points = data_point_count;
+ metric->histogram->aggregation_temporality = aggregation_temporality_type;
+ }
+
+ return metric;
+}
+
+static int append_data_point_to_metric(
+ Opentelemetry__Proto__Metrics__V1__Metric *metric,
+ void *data_point,
+ size_t data_point_slot_hint)
+{
+ void **data_point_list;
+ size_t data_point_slot_index;
+ size_t data_point_slot_count;
+
+ data_point_list = NULL;
+ data_point_slot_count = 0;
+
+ if (metric != NULL) {
+ if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUM) {
+ data_point_list = (void **) metric->sum->data_points;
+ data_point_slot_count = metric->sum->n_data_points;
+ }
+ else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_GAUGE) {
+ data_point_list = (void **) metric->gauge->data_points;
+ data_point_slot_count = metric->gauge->n_data_points;
+ }
+ else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_SUMMARY) {
+ data_point_list = (void **) metric->summary->data_points;
+ data_point_slot_count = metric->summary->n_data_points;
+ }
+ else if (metric->data_case == OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA_HISTOGRAM) {
+ data_point_list = (void **) metric->histogram->data_points;
+ data_point_slot_count = metric->histogram->n_data_points;
+ }
+ }
+
+ for (data_point_slot_index = data_point_slot_hint ;
+ data_point_slot_index < data_point_slot_count;
+ data_point_slot_index++) {
+ if (data_point_list[data_point_slot_index] == NULL) {
+ data_point_list[data_point_slot_index] = data_point;
+
+ return CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+ }
+ }
+
+ return CMT_ENCODE_OPENTELEMETRY_INVALID_ARGUMENT_ERROR;
+}
+
+static void destroy_metric_list(
+ Opentelemetry__Proto__Metrics__V1__Metric **metric_list)
+{
+ size_t element_index;
+
+ if (metric_list != NULL) {
+ for (element_index = 0 ;
+ metric_list[element_index] != NULL ;
+ element_index++) {
+ destroy_metric(metric_list[element_index]);
+
+ metric_list[element_index] = NULL;
+ }
+
+ free(metric_list);
+ }
+}
+
+static Opentelemetry__Proto__Metrics__V1__Metric **
+ initialize_metric_list(
+ size_t element_count)
+{
+ Opentelemetry__Proto__Metrics__V1__Metric **metric_list;
+
+ metric_list = calloc(element_count + 1,
+ sizeof(Opentelemetry__Proto__Metrics__V1__Metric *));
+
+ if (metric_list == NULL) {
+ return NULL;
+ }
+
+ return metric_list;
+}
+
+static void destroy_opentelemetry_context(
+ struct cmt_opentelemetry_context *context)
+{
+ if (context != NULL) {
+ if (context->metrics_data != NULL) {
+ destroy_metrics_data(context->metrics_data);
+ }
+
+ free(context);
+ }
+}
+
+static Opentelemetry__Proto__Resource__V1__Resource *
+ initialize_resource(
+ struct cfl_kvlist *resource_root,
+ int *error_detection_flag)
+{
+ struct cfl_kvlist *attributes;
+ struct cfl_kvlist *metadata;
+ Opentelemetry__Proto__Resource__V1__Resource *resource;
+
+ *error_detection_flag = CMT_FALSE;
+
+ if (resource_root == NULL) {
+ return NULL;
+ }
+
+ attributes = fetch_metadata_kvlist_key(resource_root, "attributes");
+ metadata = fetch_metadata_kvlist_key(resource_root, "metadata");
+
+ if (cfl_kvlist_count(attributes) == 0 &&
+ cfl_kvlist_count(metadata) == 0) {
+ return NULL;
+ }
+
+ resource = \
+ calloc(1, sizeof(Opentelemetry__Proto__Resource__V1__Resource));
+
+ if (resource == NULL) {
+ *error_detection_flag = CMT_TRUE;
+
+ return NULL;
+ }
+
+ opentelemetry__proto__resource__v1__resource__init(resource);
+
+ resource->attributes = cfl_kvlist_to_otlp_kvpair_list(attributes);
+
+ if (resource->attributes == NULL) {
+ *error_detection_flag = CMT_TRUE;
+ }
+
+ resource->n_attributes = cfl_kvlist_count(attributes);
+
+ if (!(*error_detection_flag)) {
+ resource->dropped_attributes_count = (uint32_t) fetch_metadata_int64_key(
+ metadata,
+ "dropped_attributes_count",
+ error_detection_flag);
+ }
+
+ if (*error_detection_flag &&
+ resource != NULL) {
+ destroy_resource(resource);
+
+ resource = NULL;
+ }
+
+ return resource;
+}
+
+static struct cmt_opentelemetry_context *initialize_opentelemetry_context(
+ struct cmt *cmt)
+{
+ struct cfl_kvlist *resource_metrics_root;
+ struct cfl_kvlist *scope_metrics_root;
+ struct cfl_kvlist *resource_root;
+ struct cfl_kvlist *scope_root;
+ Opentelemetry__Proto__Resource__V1__Resource *resource;
+ struct cmt_opentelemetry_context *context;
+ int result;
+
+ resource_metrics_root = fetch_metadata_kvlist_key(cmt->external_metadata, "resource_metrics");
+ resource_root = fetch_metadata_kvlist_key(cmt->external_metadata, "resource");
+ scope_metrics_root = fetch_metadata_kvlist_key(cmt->external_metadata, "scope_metrics");
+ scope_root = fetch_metadata_kvlist_key(cmt->external_metadata, "scope");
+
+ result = CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+
+ context = calloc(1, sizeof(struct cmt_opentelemetry_context));
+
+ if (context == NULL) {
+ result = CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+
+ goto cleanup;
+ }
+
+ memset(context, 0, sizeof(struct cmt_opentelemetry_context));
+
+ context->cmt = cmt;
+
+ resource = initialize_resource(resource_root, &result);
+
+ if (resource == NULL) {
+ if (result) {
+ result = CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+
+ goto cleanup;
+ }
+ }
+
+ context->metrics_data = initialize_metrics_data(1);
+
+ if (context->metrics_data == NULL) {
+ result = CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+
+ goto cleanup;
+ }
+
+ context->metrics_data->resource_metrics[0] = \
+ initialize_resource_metrics(resource_metrics_root, resource, 1);
+
+ if (context->metrics_data->resource_metrics[0] == NULL) {
+ result = CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+
+ goto cleanup;
+ }
+
+ context->metrics_data->resource_metrics[0]->scope_metrics[0] = \
+ initialize_scope_metrics(scope_metrics_root,
+ get_metric_count(cmt));
+
+ if (context->metrics_data->resource_metrics[0]->scope_metrics[0] == NULL) {
+ result = CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+
+ goto cleanup;
+ }
+
+ context->metrics_data->\
+ resource_metrics[0]->\
+ scope_metrics[0]->\
+ scope = \
+ initialize_instrumentation_scope(
+ scope_root, &result);
+
+ if (result) {
+ result = CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+
+ goto cleanup;
+ }
+
+cleanup:
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ if (context != NULL) {
+ destroy_opentelemetry_context(context);
+
+ context = NULL;
+ }
+ }
+
+ return context;
+}
+
+int append_sample_to_metric(struct cmt_opentelemetry_context *context,
+ Opentelemetry__Proto__Metrics__V1__Metric *metric,
+ struct cmt_map *map,
+ struct cmt_metric *sample,
+ size_t sample_index)
+{
+ size_t attribute_index;
+ size_t attribute_count;
+ Opentelemetry__Proto__Common__V1__KeyValue **attribute_list;
+ struct cmt_label *static_label;
+ struct cmt_map_label *label_value;
+ struct cmt_map_label *label_name;
+ void *data_point = NULL;
+ Opentelemetry__Proto__Common__V1__KeyValue *attribute;
+ struct cmt_histogram *histogram;
+ struct cmt_summary *summary;
+ int result;
+ struct cfl_list *head;
+
+ attribute_count = cfl_list_size(&context->cmt->static_labels->list) +
+ cfl_list_size(&sample->labels);
+
+ attribute_list = initialize_attribute_list(attribute_count);
+
+ if (attribute_list == NULL) {
+ return CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+ }
+
+ if (map->type == CMT_COUNTER ||
+ map->type == CMT_GAUGE ||
+ map->type == CMT_UNTYPED ) {
+ data_point = initialize_numerical_data_point(0,
+ cmt_metric_get_timestamp(sample),
+ cmt_metric_get_value(sample),
+ attribute_list,
+ attribute_count);
+ }
+ else if (map->type == CMT_SUMMARY) {
+ summary = (struct cmt_summary *) map->parent;
+
+ data_point = initialize_summary_data_point(0,
+ cmt_metric_get_timestamp(sample),
+ cmt_summary_get_count_value(sample),
+ cmt_summary_get_sum_value(sample),
+ summary->quantiles_count,
+ summary->quantiles,
+ summary->quantiles_count,
+ sample->sum_quantiles,
+ attribute_list,
+ attribute_count);
+ }
+ else if (map->type == CMT_HISTOGRAM) {
+ histogram = (struct cmt_histogram *) map->parent;
+
+ data_point = initialize_histogram_data_point(0,
+ cmt_metric_get_timestamp(sample),
+ cmt_metric_hist_get_count_value(sample),
+ cmt_metric_hist_get_sum_value(sample),
+ histogram->buckets->count + 1,
+ sample->hist_buckets,
+ histogram->buckets->count,
+ histogram->buckets->upper_bounds,
+ attribute_list,
+ attribute_count);
+ }
+
+ if (data_point == NULL) {
+ destroy_attribute_list(attribute_list);
+
+ return CMT_ENCODE_OPENTELEMETRY_DATA_POINT_INIT_ERROR;
+ }
+
+ attribute_index = 0;
+
+ cfl_list_foreach(head, &context->cmt->static_labels->list) {
+ static_label = cfl_list_entry(head, struct cmt_label, _head);
+
+ attribute = initialize_string_attribute(static_label->key,
+ static_label->val);
+
+ if (attribute == NULL) {
+ destroy_data_point(data_point, map->type);
+
+ return CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+ }
+
+ result = append_attribute_to_data_point(data_point,
+ map->type,
+ attribute,
+ attribute_index++);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS)
+ {
+ destroy_data_point(data_point, map->type);
+
+ return result;
+ }
+ }
+
+ label_name = cfl_list_entry_first(&map->label_keys, struct cmt_map_label, _head);
+
+ cfl_list_foreach(head, &sample->labels) {
+ label_value = cfl_list_entry(head, struct cmt_map_label, _head);
+
+ attribute = initialize_string_attribute(label_name->name,
+ label_value->name);
+
+ if (attribute == NULL) {
+ destroy_data_point(data_point, map->type);
+
+ return CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+ }
+
+ result = append_attribute_to_data_point(data_point,
+ map->type,
+ attribute,
+ attribute_index++);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS)
+ {
+ destroy_data_point(data_point, map->type);
+
+ return result;
+ }
+
+ label_name = cfl_list_entry_next(&label_name->_head, struct cmt_map_label,
+ _head, &map->label_keys);
+ }
+
+ result = append_data_point_to_metric(metric, (void *) data_point, sample_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ destroy_data_point(data_point, map->type);
+
+ return result;
+ }
+
+ return result;
+}
+
+int pack_basic_type(struct cmt_opentelemetry_context *context,
+ struct cmt_map *map,
+ size_t *metric_index)
+{
+ int aggregation_temporality_type;
+ int monotonism_flag;
+ size_t sample_index;
+ size_t sample_count;
+ struct cmt_counter *counter;
+ struct cmt_metric *sample;
+ Opentelemetry__Proto__Metrics__V1__Metric *metric;
+ int result;
+ struct cfl_list *head;
+
+ sample_count = 0;
+
+ if (map->metric_static_set) {
+ sample_count++;
+ }
+
+ sample_count += cfl_list_size(&map->metrics);
+
+ if (sample_count == 0) {
+ return CMT_ENCODE_OPENTELEMETRY_SUCCESS;
+ }
+
+ aggregation_temporality_type = OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_UNSPECIFIED;
+ monotonism_flag = CMT_FALSE;
+
+ if (map->type == CMT_COUNTER) {
+ if (map->parent != NULL) {
+ counter = (struct cmt_counter *) map->parent;
+
+ if (counter->aggregation_type == CMT_AGGREGATION_TYPE_DELTA) {
+ aggregation_temporality_type = OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_DELTA;
+ }
+ else if (counter->aggregation_type == CMT_AGGREGATION_TYPE_CUMULATIVE) {
+ aggregation_temporality_type = OPENTELEMETRY__PROTO__METRICS__V1__AGGREGATION_TEMPORALITY__AGGREGATION_TEMPORALITY_CUMULATIVE;
+ }
+
+ monotonism_flag = !counter->allow_reset;
+ }
+ }
+
+ metric = initialize_metric(map->type,
+ map->opts->fqname,
+ map->opts->description,
+ map->unit,
+ monotonism_flag,
+ aggregation_temporality_type,
+ sample_count);
+
+ if (metric == NULL) {
+ return CMT_ENCODE_OPENTELEMETRY_ALLOCATION_ERROR;
+ }
+
+ sample_index = 0;
+
+ if (map->metric_static_set) {
+ result = append_sample_to_metric(context,
+ metric,
+ map,
+ &map->metric,
+ sample_index++);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ destroy_metric(metric);
+
+ return result;
+ }
+ }
+
+ cfl_list_foreach(head, &map->metrics) {
+ sample = cfl_list_entry(head, struct cmt_metric, _head);
+
+ result = append_sample_to_metric(context,
+ metric,
+ map,
+ sample,
+ sample_index++);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ destroy_metric(metric);
+
+ return result;
+ }
+ }
+
+ result = append_metric_to_scope_metrics(
+ context->\
+ metrics_data->\
+ resource_metrics[0]->\
+ scope_metrics[0],
+ metric,
+ *metric_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ destroy_metric(metric);
+
+ return result;
+ }
+
+ (*metric_index)++;
+
+ return result;
+}
+
+static cfl_sds_t render_opentelemetry_context_to_sds(
+ struct cmt_opentelemetry_context *context)
+{
+ cfl_sds_t result_buffer;
+ size_t result_size;
+
+ result_size = opentelemetry__proto__metrics__v1__metrics_data__get_packed_size(
+ context->metrics_data);
+
+ result_buffer = cfl_sds_create_size(result_size);
+
+ if(result_buffer != NULL) {
+ opentelemetry__proto__metrics__v1__metrics_data__pack(
+ context->metrics_data,
+ (uint8_t *) result_buffer);
+
+ cfl_sds_set_len(result_buffer, result_size);
+ }
+
+ return result_buffer;
+}
+
+cfl_sds_t cmt_encode_opentelemetry_create(struct cmt *cmt)
+{
+ size_t metric_index;
+ struct cmt_opentelemetry_context *context;
+ struct cmt_histogram *histogram;
+ struct cmt_summary *summary;
+ struct cmt_untyped *untyped;
+ struct cmt_counter *counter;
+ int result;
+ struct cmt_gauge *gauge;
+ struct cfl_list *head;
+ cfl_sds_t buf;
+
+ buf = NULL;
+ result = 0;
+
+ context = initialize_opentelemetry_context(cmt);
+
+ if (context == NULL) {
+ return NULL;
+ }
+
+ metric_index = 0;
+
+ if (result == CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ cfl_list_foreach(head, &cmt->counters) {
+ counter = cfl_list_entry(head, struct cmt_counter, _head);
+ result = pack_basic_type(context, counter->map, &metric_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ if (result == CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ cfl_list_foreach(head, &cmt->gauges) {
+ gauge = cfl_list_entry(head, struct cmt_gauge, _head);
+ result = pack_basic_type(context, gauge->map, &metric_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ if (result == CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ cfl_list_foreach(head, &cmt->untypeds) {
+ untyped = cfl_list_entry(head, struct cmt_untyped, _head);
+ result = pack_basic_type(context, untyped->map, &metric_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ if (result == CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ cfl_list_foreach(head, &cmt->summaries) {
+ summary = cfl_list_entry(head, struct cmt_summary, _head);
+ result = pack_basic_type(context, summary->map, &metric_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ if (result == CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ cfl_list_foreach(head, &cmt->histograms) {
+ histogram = cfl_list_entry(head, struct cmt_histogram, _head);
+ result = pack_basic_type(context, histogram->map, &metric_index);
+
+ if (result != CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ if (result == CMT_ENCODE_OPENTELEMETRY_SUCCESS) {
+ buf = render_opentelemetry_context_to_sds(context);
+ }
+
+ destroy_opentelemetry_context(context);
+
+ return buf;
+}
+
+void cmt_encode_opentelemetry_destroy(cfl_sds_t text)
+{
+ cfl_sds_destroy(text);
+}