Asterisk - The Open Source Telephony Project GIT-master-a358458
bridges.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2019 Sangoma, Inc.
5 *
6 * Matt Jordan <mjordan@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*!
20 * \file
21 * \brief Prometheus Bridge Metrics
22 *
23 * \author Matt Jordan <mjordan@digium.com>
24 *
25 */
26
27#include "asterisk.h"
28
31#include "prometheus_internal.h"
32
33#define BRIDGES_CHANNELS_COUNT_HELP "Number of channels in the bridge."
34
35/*!
36 * \internal
37 * \brief Callback function to get the number of channels in a bridge
38 *
39 * \param metric The metric to populate
40 * \param snapshot Bridge snapshot
41 */
42static void get_bridge_channel_count(struct prometheus_metric *metric, struct ast_bridge_snapshot *snapshot)
43{
44 snprintf(metric->value, sizeof(metric->value), "%d", snapshot->num_channels);
45}
46
47/*!
48 * \internal
49 * \brief Helper struct for generating individual bridge stats
50 */
52 /*!
53 * \brief Help text to display
54 */
55 const char *help;
56 /*!
57 * \brief Name of the metric
58 */
59 const char *name;
60 /*!
61 * \brief Callback function to generate a metric value for a given bridge
62 */
63 void (* const get_value)(struct prometheus_metric *metric, struct ast_bridge_snapshot *snapshot);
65 {
67 .name = "asterisk_bridges_channels_count",
68 .get_value = get_bridge_channel_count,
69 },
70};
71
72/*!
73 * \internal
74 * \brief Callback invoked when Prometheus scrapes the server
75 *
76 * \param response The response to populate with formatted metrics
77 */
78static void bridges_scrape_cb(struct ast_str **response)
79{
80 struct ao2_container *bridge_cache;
81 struct ao2_container *bridges;
82 struct ao2_iterator it_bridges;
83 struct ast_bridge *bridge;
85 struct prometheus_metric **bridge_metrics;
86 char eid_str[32];
87 int i, j, num_bridges, num_outputs = 0;
90 "asterisk_bridges_count",
91 "Current bridge count.",
92 NULL
93 );
94
95 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
96
97 bridge_cache = ast_bridges();
98 if (!bridge_cache) {
99 return;
100 }
101
102 bridges = ao2_container_clone(bridge_cache, 0);
103 ao2_ref(bridge_cache, -1);
104 if (!bridges) {
105 return;
106 }
107
108 num_bridges = ao2_container_count(bridges);
109
110 /* Current endpoint count */
111 PROMETHEUS_METRIC_SET_LABEL(&bridge_count, 0, "eid", eid_str);
112 snprintf(bridge_count.value, sizeof(bridge_count.value), "%d", num_bridges);
113 prometheus_metric_to_string(&bridge_count, response);
114
115 if (num_bridges == 0) {
116 ao2_ref(bridges, -1);
117 return;
118 }
119
120 metrics = ast_calloc(ARRAY_LEN(bridge_metric_defs) * num_bridges, sizeof(*metrics));
121 if (!metrics) {
122 ao2_ref(bridges, -1);
123 return;
124 }
125
126 bridge_metrics = ast_calloc(ARRAY_LEN(bridge_metric_defs), sizeof(bridge_metrics));
127 if (!bridge_metrics) {
129 ao2_ref(bridges, -1);
130 return;
131 }
132
133 /* Bridge dependent values */
134 it_bridges = ao2_iterator_init(bridges, 0);
135 for (i = 0; (bridge = ao2_iterator_next(&it_bridges)); ao2_ref(bridge, -1), i++) {
136 struct ast_bridge_snapshot *snapshot;
137
138 /* Invisible bridges don't get shown externally and have no snapshot */
140 continue;
141 }
142
143 snapshot = ast_bridge_get_snapshot(bridge);
144 if (!snapshot) {
145 continue;
146 }
147
148 for (j = 0; j < ARRAY_LEN(bridge_metric_defs); j++) {
149 int index = num_outputs++;
150
151 metrics[index].type = PROMETHEUS_METRIC_GAUGE;
152 ast_copy_string(metrics[index].name, bridge_metric_defs[j].name, sizeof(metrics[index].name));
153 metrics[index].help = bridge_metric_defs[j].help;
154 PROMETHEUS_METRIC_SET_LABEL(&metrics[index], 0, "eid", eid_str);
155 PROMETHEUS_METRIC_SET_LABEL(&metrics[index], 1, "id", (snapshot->uniqueid));
156 PROMETHEUS_METRIC_SET_LABEL(&metrics[index], 2, "tech", (snapshot->technology));
157 PROMETHEUS_METRIC_SET_LABEL(&metrics[index], 3, "subclass", (snapshot->subclass));
158 PROMETHEUS_METRIC_SET_LABEL(&metrics[index], 4, "creator", (snapshot->creator));
159 PROMETHEUS_METRIC_SET_LABEL(&metrics[index], 5, "name", (snapshot->name));
160 bridge_metric_defs[j].get_value(&metrics[index], snapshot);
161
162 if (bridge_metrics[j] == NULL) {
163 bridge_metrics[j] = &metrics[index];
164 } else {
165 AST_LIST_INSERT_TAIL(&bridge_metrics[j]->children, &metrics[index], entry);
166 }
167 }
168 ao2_ref(snapshot, -1);
169 }
170 ao2_iterator_destroy(&it_bridges);
171
172 for (j = 0; j < ARRAY_LEN(bridge_metric_defs); j++) {
173 if (bridge_metrics[j]) {
174 prometheus_metric_to_string(bridge_metrics[j], response);
175 }
176 }
177
178 ast_free(bridge_metrics);
180 ao2_ref(bridges, -1);
181}
182
184 .name = "bridges callback",
185 .callback_fn = bridges_scrape_cb,
186};
187
188/*!
189 * \internal
190 * \brief Callback invoked when the core module is unloaded
191 */
193{
195}
196
197/*!
198 * \internal
199 * \brief Metrics provider definition
200 */
202 .name = "bridges",
203 .unload_cb = bridge_metrics_unload_cb,
204};
205
207{
210
211 return 0;
212}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_container_clone(orig, flags)
Create a clone/copy of the given container.
Definition: astobj2.h:1419
static struct ao2_container * bridges
Definition: bridge.c:123
struct ao2_container * ast_bridges(void)
Returns the global bridges container.
Definition: bridge.c:174
@ AST_BRIDGE_FLAG_INVISIBLE
#define BRIDGES_CHANNELS_COUNT_HELP
Definition: bridges.c:33
struct prometheus_callback bridges_callback
Definition: bridges.c:183
static void bridge_metrics_unload_cb(void)
Definition: bridges.c:192
static struct prometheus_metrics_provider provider
Definition: bridges.c:201
static void bridges_scrape_cb(struct ast_str **response)
Definition: bridges.c:78
int bridge_metrics_init(void)
Initialize bridge metrics.
Definition: bridges.c:206
static void get_bridge_channel_count(struct prometheus_metric *metric, struct ast_bridge_snapshot *snapshot)
Definition: bridges.c:42
static const char name[]
Definition: format_mp3.c:68
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
Prometheus Metric Internal API.
struct @467 metrics
Asterisk Prometheus Metrics.
#define PROMETHEUS_METRIC_SET_LABEL(metric, label, n, v)
Convenience macro for setting a label / value in a metric.
#define PROMETHEUS_METRIC_STATIC_INITIALIZATION(mtype, n, h, cb)
Convenience macro for initializing a metric on the stack.
@ PROMETHEUS_METRIC_GAUGE
A metric whose value can bounce around like a jackrabbit.
void prometheus_callback_unregister(struct prometheus_callback *callback)
Remove a registered callback.
void prometheus_metric_to_string(struct prometheus_metric *metric, struct ast_str **output)
Convert a metric (and its children) into Prometheus compatible text.
void prometheus_metrics_provider_register(const struct prometheus_metrics_provider *provider)
Register a metrics provider.
int prometheus_callback_register(struct prometheus_callback *callback)
#define NULL
Definition: resample.c:96
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
const ast_string_field creator
Definition: bridge.h:328
const ast_string_field uniqueid
Definition: bridge.h:328
unsigned int num_channels
Definition: bridge.h:337
const ast_string_field technology
Definition: bridge.h:328
const ast_string_field name
Definition: bridge.h:328
const ast_string_field subclass
Definition: bridge.h:328
Structure that contains information about a bridge.
Definition: bridge.h:349
struct ast_flags feature_flags
Definition: bridge.h:369
Support for dynamic strings.
Definition: strings.h:623
void(*const get_value)(struct prometheus_metric *metric, struct ast_bridge_snapshot *snapshot)
Callback function to generate a metric value for a given bridge.
Definition: bridges.c:63
const char * name
Name of the metric.
Definition: bridges.c:59
const char * help
Help text to display.
Definition: bridges.c:55
Definition: search.h:40
Defines a callback that will be invoked when the HTTP route is called.
const char * name
The name of our callback (always useful for debugging)
An actual, honest to god, metric.
char value[PROMETHEUS_MAX_VALUE_LENGTH]
The current value.
A function table for a metrics provider.
const char * name
Handy name of the provider for debugging purposes.
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
#define ARRAY_LEN(a)
Definition: utils.h:666
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93