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_ */
|