res_prometheus: Add Asterisk channel metrics

This patch adds basic Asterisk channel statistics to the res_prometheus
module. This includes:

* asterisk_calls_sum: A running sum of the total number of
  processed calls

* asterisk_calls_count: The current number of calls

* asterisk_channels_count: The current number of channels

* asterisk_channels_state: The state of any particular channel

* asterisk_channels_duration_seconds: How long a channel has existed,
  in seconds

In all cases, enough information is provided with each channel metric
to determine a unique instance of Asterisk that provided the data, as
well as the name, type, unique ID, and - if present - linked ID of each
channel.

ASTERISK-28403

Change-Id: I0db306ec94205d4f58d1e7fbabfe04b185869f59
This commit is contained in:
Matt Jordan
2019-05-02 19:45:27 -05:00
parent 54f7f7dc20
commit 0760af71ad
7 changed files with 371 additions and 11 deletions

View File

@@ -128,6 +128,8 @@
#include "asterisk/buildinfo.h"
#include "asterisk/res_prometheus.h"
#include "prometheus/prometheus_internal.h"
/*! \brief Lock that protects data structures during an HTTP scrape */
AST_MUTEX_DEFINE_STATIC(scrape_lock);
@@ -135,6 +137,8 @@ AST_VECTOR(, struct prometheus_metric *) metrics;
AST_VECTOR(, struct prometheus_callback *) callbacks;
AST_VECTOR(, const struct prometheus_metrics_provider *) providers;
/*! \brief The actual module config */
struct module_config {
/*! \brief General settings */
@@ -812,6 +816,11 @@ static void prometheus_config_post_apply(void)
}
}
void prometheus_metrics_provider_register(const struct prometheus_metrics_provider *provider)
{
AST_VECTOR_APPEND(&providers, provider);
}
static int unload_module(void)
{
SCOPED_MUTEX(lock, &scrape_lock);
@@ -819,6 +828,16 @@ static int unload_module(void)
ast_http_uri_unlink(&prometheus_uri);
for (i = 0; i < AST_VECTOR_SIZE(&providers); i++) {
const struct prometheus_metrics_provider *provider = AST_VECTOR_GET(&providers, i);
if (!provider->unload_cb) {
continue;
}
provider->unload_cb();
}
for (i = 0; i < AST_VECTOR_SIZE(&metrics); i++) {
struct prometheus_metric *metric = AST_VECTOR_GET(&metrics, i);
@@ -827,7 +846,7 @@ static int unload_module(void)
AST_VECTOR_FREE(&metrics);
AST_VECTOR_FREE(&callbacks);
AST_VECTOR_FREE(&providers);
aco_info_destroy(&cfg_info);
ao2_global_obj_release(global_config);
@@ -836,11 +855,31 @@ static int unload_module(void)
static int reload_module(void) {
SCOPED_MUTEX(lock, &scrape_lock);
int i;
struct prometheus_general_config *general_config;
ast_http_uri_unlink(&prometheus_uri);
if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
return -1;
}
/* Our config should be all reloaded now */
general_config = prometheus_general_config_get();
for (i = 0; i < AST_VECTOR_SIZE(&providers); i++) {
const struct prometheus_metrics_provider *provider = AST_VECTOR_GET(&providers, i);
if (!provider->reload_cb) {
continue;
}
if (provider->reload_cb(general_config)) {
ast_log(AST_LOG_WARNING, "Failed to reload metrics provider %s\n", provider->name);
ao2_ref(general_config, -1);
return -1;
}
}
ao2_ref(general_config, -1);
if (ast_http_uri_link(&prometheus_uri)) {
ast_log(AST_LOG_WARNING, "Failed to re-register Prometheus Metrics URI during reload\n");
return -1;
@@ -861,6 +900,10 @@ static int load_module(void)
goto cleanup;
}
if (AST_VECTOR_INIT(&providers, 8)) {
goto cleanup;
}
if (aco_info_init(&cfg_info)) {
goto cleanup;
}
@@ -874,6 +917,10 @@ static int load_module(void)
goto cleanup;
}
if (channel_metrics_init()) {
goto cleanup;
}
if (ast_http_uri_link(&prometheus_uri)) {
goto cleanup;
}
@@ -885,6 +932,7 @@ cleanup:
aco_info_destroy(&cfg_info);
AST_VECTOR_FREE(&metrics);
AST_VECTOR_FREE(&callbacks);
AST_VECTOR_FREE(&providers);
return AST_MODULE_LOAD_DECLINE;
}