Line data Source code
1 1 : /* 2 : * Copyright (c) 2024 Mustafa Abdullah Kus, Sparse Technology 3 : * Copyright (c) 2024 Nordic Semiconductor 4 : * 5 : * SPDX-License-Identifier: Apache-2.0 6 : */ 7 : 8 : #ifndef ZEPHYR_INCLUDE_PROMETHEUS_COLLECTOR_H_ 9 : #define ZEPHYR_INCLUDE_PROMETHEUS_COLLECTOR_H_ 10 : 11 : /** 12 : * @file 13 : * 14 : * @brief Prometheus collector APIs. 15 : * 16 : * @defgroup prometheus Prometheus API 17 : * @since 4.0 18 : * @version 0.1.0 19 : * @ingroup networking 20 : * @{ 21 : */ 22 : 23 : #include <zephyr/kernel.h> 24 : #include <zephyr/sys/iterable_sections.h> 25 : #include <zephyr/net/prometheus/metric.h> 26 : 27 : #include <stddef.h> 28 : 29 : struct prometheus_collector; 30 : 31 : /** 32 : * @typedef prometheus_scrape_cb_t 33 : * @brief Callback used to scrape a collector for a specific metric. 34 : * 35 : * @param collector A valid pointer on the collector to scrape 36 : * @param metric A valid pointer on the metric to scrape 37 : * @param user_data A valid pointer to a user data or NULL 38 : * 39 : * @return 0 if successful, otherwise a negative error code. 40 : */ 41 1 : typedef int (*prometheus_scrape_cb_t)(struct prometheus_collector *collector, 42 : struct prometheus_metric *metric, 43 : void *user_data); 44 : 45 : /** 46 : * @brief Prometheus collector definition 47 : * 48 : * This structure defines a Prometheus collector. 49 : */ 50 1 : struct prometheus_collector { 51 : /** Name of the collector */ 52 1 : const char *name; 53 : /** Array of metrics associated with the collector */ 54 1 : sys_slist_t metrics; 55 : /** Mutex to protect the metrics list manipulation */ 56 1 : struct k_mutex lock; 57 : /** User callback function. If set, then the metric data is fetched 58 : * via the function callback. 59 : */ 60 1 : prometheus_scrape_cb_t user_cb; 61 : /** User data */ 62 1 : void *user_data; 63 : }; 64 : 65 : /** 66 : * @brief Prometheus Collector definition. 67 : * 68 : * This macro defines a Collector. 69 : * 70 : * @param _name The collector's name. 71 : * @param ... Optional user callback function. If set, this function is called 72 : * when the collector is scraped. The function should be of type 73 : * prometheus_scrape_cb_t. 74 : * Optional user data to pass to the user callback function. 75 : */ 76 1 : #define PROMETHEUS_COLLECTOR_DEFINE(_name, ...) \ 77 : STRUCT_SECTION_ITERABLE(prometheus_collector, _name) = { \ 78 : .name = STRINGIFY(_name), \ 79 : .metrics = SYS_SLIST_STATIC_INIT(&_name.metrics), \ 80 : .lock = Z_MUTEX_INITIALIZER(_name.lock), \ 81 : .user_cb = COND_CODE_0( \ 82 : NUM_VA_ARGS_LESS_1( \ 83 : LIST_DROP_EMPTY(__VA_ARGS__, _)), \ 84 : (NULL), \ 85 : (GET_ARG_N(1, __VA_ARGS__))), \ 86 : .user_data = COND_CODE_0( \ 87 : NUM_VA_ARGS_LESS_1(__VA_ARGS__), (NULL), \ 88 : (GET_ARG_N(1, \ 89 : GET_ARGS_LESS_N(1, __VA_ARGS__)))), \ 90 : } 91 : 92 : /** 93 : * @brief Register a metric with a Prometheus collector 94 : * 95 : * Registers the specified metric with the given collector. 96 : * 97 : * @param collector Pointer to the collector to register the metric with. 98 : * @param metric Pointer to the metric to register. 99 : * 100 : * @return 0 if successful, otherwise a negative error code. 101 : * @retval -EINVAL Invalid arguments. 102 : * @retval -ENOMEM Not enough memory to register the metric. 103 : */ 104 1 : int prometheus_collector_register_metric(struct prometheus_collector *collector, 105 : struct prometheus_metric *metric); 106 : 107 : /** 108 : * @brief Get a metric from a Prometheus collector 109 : * 110 : * Retrieves the metric with the specified name from the given collector. 111 : * 112 : * @param collector Pointer to the collector to retrieve the metric from. 113 : * @param name Name of the metric to retrieve. 114 : * @return Pointer to the retrieved metric, or NULL if not found. 115 : */ 116 1 : const void *prometheus_collector_get_metric(struct prometheus_collector *collector, 117 : const char *name); 118 : 119 : /** @cond INTERNAL_HIDDEN */ 120 : 121 : enum prometheus_walk_state { 122 : PROMETHEUS_WALK_START, 123 : PROMETHEUS_WALK_CONTINUE, 124 : PROMETHEUS_WALK_STOP, 125 : }; 126 : 127 : struct prometheus_collector_walk_context { 128 : struct prometheus_collector *collector; 129 : struct prometheus_metric *metric; 130 : struct prometheus_metric *tmp; 131 : enum prometheus_walk_state state; 132 : }; 133 : 134 : /** @endcond */ 135 : 136 : /** 137 : * @brief Walk through all metrics in a Prometheus collector and format them 138 : * into a buffer. 139 : * 140 : * @param ctx Pointer to the walker context. 141 : * @param buffer Pointer to the buffer to store the formatted metrics. 142 : * @param buffer_size Size of the buffer. 143 : * @return 0 if successful and we went through all metrics, -EAGAIN if we 144 : * need to call this function again, any other negative error code 145 : * means an error occurred. 146 : */ 147 1 : int prometheus_collector_walk_metrics(struct prometheus_collector_walk_context *ctx, 148 : uint8_t *buffer, size_t buffer_size); 149 : 150 : /** 151 : * @brief Initialize the walker context to walk through all metrics. 152 : * 153 : * @param ctx Pointer to the walker context. 154 : * @param collector Pointer to the collector to walk through. 155 : * 156 : * @return 0 if successful, otherwise a negative error code. 157 : */ 158 1 : static inline int prometheus_collector_walk_init(struct prometheus_collector_walk_context *ctx, 159 : struct prometheus_collector *collector) 160 : { 161 : if (collector == NULL) { 162 : return -EINVAL; 163 : } 164 : 165 : ctx->collector = collector; 166 : ctx->state = PROMETHEUS_WALK_START; 167 : ctx->metric = NULL; 168 : ctx->tmp = NULL; 169 : 170 : return 0; 171 : } 172 : 173 : /** 174 : * @} 175 : */ 176 : 177 : #endif /* ZEPHYR_INCLUDE_PROMETHEUS_COLLECTOR_H_ */