Skip to content

Commit 2bc7b07

Browse files
jukkarnashif
authored andcommitted
samples: net: prometheus: Add support for network statistics
Add separate URL handling for network statistics. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 99abfda commit 2bc7b07

File tree

4 files changed

+111
-2
lines changed

4 files changed

+111
-2
lines changed

samples/net/prometheus/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ endif()
2222

2323

2424
target_sources(app PRIVATE src/main.c)
25+
target_sources_ifdef(CONFIG_NET_STATISTICS_VIA_PROMETHEUS app PRIVATE src/stats.c)
2526

2627
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)
2728

samples/net/prometheus/prj.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,7 @@ CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=n
8484
CONFIG_NET_HTTP_LOG_LEVEL_DBG=n
8585
CONFIG_NET_IPV6_LOG_LEVEL_DBG=n
8686
CONFIG_NET_IPV6_ND_LOG_LEVEL_DBG=n
87+
88+
# Network statistics Prometheus support
89+
CONFIG_NET_STATISTICS_VIA_PROMETHEUS=y
90+
CONFIG_NET_STATISTICS=y

samples/net/prometheus/src/main.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
#include <zephyr/logging/log.h>
2828
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
2929

30-
struct {
30+
extern int init_stats(struct prometheus_counter *counter);
31+
32+
struct app_context {
3133

3234
struct prometheus_collector *collector;
3335

@@ -88,7 +90,7 @@ HTTP_RESOURCE_DEFINE(dyn_resource, test_http_service, "/metrics", &dyn_resource_
8890
#if defined(CONFIG_NET_SAMPLE_HTTPS_SERVICE)
8991
#include "certificate.h"
9092

91-
static const sec_tag_t sec_tag_list_verify_none[] = {
93+
const sec_tag_t sec_tag_list_verify_none[] = {
9294
HTTP_SERVER_CERTIFICATE_TAG,
9395
#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
9496
PSK_TAG,
@@ -160,6 +162,10 @@ int main(void)
160162

161163
prometheus_collector_register_metric(prom_context.collector, &prom_context.counter->base);
162164

165+
#if defined(CONFIG_NET_STATISTICS_VIA_PROMETHEUS)
166+
(void)init_stats(prom_context.counter);
167+
#endif
168+
163169
setup_tls();
164170

165171
http_server_start();

samples/net/prometheus/src/stats.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/logging/log.h>
8+
LOG_MODULE_DECLARE(main, LOG_LEVEL_DBG);
9+
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/kernel.h>
12+
#include <zephyr/net/tls_credentials.h>
13+
#include <zephyr/net/http/server.h>
14+
#include <zephyr/net/http/service.h>
15+
#include <zephyr/net/net_if.h>
16+
#include <zephyr/net/net_ip.h>
17+
18+
#include <zephyr/net/prometheus/formatter.h>
19+
#include <zephyr/net/prometheus/collector.h>
20+
#include <zephyr/net/prometheus/counter.h>
21+
#include <zephyr/net/prometheus/gauge.h>
22+
#include <zephyr/net/prometheus/histogram.h>
23+
#include <zephyr/net/prometheus/summary.h>
24+
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
#include <string.h>
28+
29+
extern struct http_service_desc test_http_service;
30+
31+
static struct prometheus_counter *http_request_counter;
32+
static struct prometheus_collector *stats_collector;
33+
static struct prometheus_collector_walk_context walk_ctx;
34+
35+
static int stats_handler(struct http_client_ctx *client, enum http_data_status status,
36+
uint8_t *buffer, size_t len, struct http_response_ctx *response_ctx,
37+
void *user_data)
38+
{
39+
int ret;
40+
static uint8_t prom_buffer[1024];
41+
42+
if (status == HTTP_SERVER_DATA_FINAL) {
43+
44+
/* incrase counter per request */
45+
prometheus_counter_inc(http_request_counter);
46+
47+
(void)memset(prom_buffer, 0, sizeof(prom_buffer));
48+
49+
ret = prometheus_collector_walk_metrics(user_data,
50+
prom_buffer,
51+
sizeof(prom_buffer));
52+
if (ret < 0 && ret != -EAGAIN) {
53+
LOG_ERR("Cannot format exposition data (%d)", ret);
54+
return ret;
55+
}
56+
57+
response_ctx->body = prom_buffer;
58+
response_ctx->body_len = strlen(prom_buffer);
59+
60+
if (ret == 0) {
61+
response_ctx->final_chunk = true;
62+
ret = prometheus_collector_walk_init(&walk_ctx, stats_collector);
63+
if (ret < 0) {
64+
LOG_ERR("Cannot initialize walk context (%d)", ret);
65+
}
66+
}
67+
}
68+
69+
return 0;
70+
}
71+
72+
struct http_resource_detail_dynamic stats_resource_detail = {
73+
.common = {
74+
.type = HTTP_RESOURCE_TYPE_DYNAMIC,
75+
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
76+
.content_type = "text/plain",
77+
},
78+
.cb = stats_handler,
79+
.user_data = &walk_ctx,
80+
};
81+
82+
HTTP_RESOURCE_DEFINE(stats_resource, test_http_service, "/statistics", &stats_resource_detail);
83+
84+
int init_stats(struct prometheus_counter *counter)
85+
{
86+
/* Use a collector from default network interface */
87+
stats_collector = net_if_get_default()->collector;
88+
if (stats_collector == NULL) {
89+
LOG_ERR("Cannot get collector from default network interface");
90+
return -EINVAL;
91+
}
92+
93+
(void)prometheus_collector_walk_init(&walk_ctx, stats_collector);
94+
95+
http_request_counter = counter;
96+
97+
return 0;
98+
}

0 commit comments

Comments
 (0)