Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
res_prometheus.c File Reference

Core Prometheus metrics API. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/vector.h"
#include "asterisk/http.h"
#include "asterisk/config_options.h"
#include "asterisk/ast_version.h"
#include "asterisk/buildinfo.h"
#include "asterisk/res_prometheus.h"
#include "prometheus/prometheus_internal.h"
Include dependency graph for res_prometheus.c:

Go to the source code of this file.

Macros

#define AST_MODULE_SELF_SYM   __internal_res_prometheus_self
 
#define CORE_LAST_RELOAD_HELP   "Time since last Asterisk reload in seconds."
 
#define CORE_METRICS_SCRAPE_TIME_HELP   "Total time taken to collect metrics, in milliseconds"
 
#define CORE_PROPERTIES_HELP   "Asterisk instance properties. The value of this will always be 1."
 
#define CORE_UPTIME_HELP   "Asterisk instance uptime in seconds."
 
#define METRIC_CORE_PROPS_ARRAY_INDEX   0
 

Functions

struct ast_module__internal_res_prometheus_self (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static AO2_GLOBAL_OBJ_STATIC (global_config)
 The module configuration container. More...
 
 AST_VECTOR (struct prometheus_metric *)
 The actual module config. More...
 
 CONFIG_INFO_STANDARD (cfg_info, global_config, module_config_alloc,.files=ACO_FILES(&prometheus_conf),.pre_apply_config=prometheus_config_pre_apply,.post_apply_config=prometheus_config_post_apply,)
 Register information about the configs being processed by this module. More...
 
static void get_core_uptime_cb (struct prometheus_metric *metric)
 
static void get_last_reload_cb (struct prometheus_metric *metric)
 
static int http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static int load_module (void)
 
static void * module_config_alloc (void)
 Module config constructor. More...
 
static void module_config_dtor (void *obj)
 Configuration object destructor. More...
 
int prometheus_callback_register (struct prometheus_callback *callback)
 
void prometheus_callback_unregister (struct prometheus_callback *callback)
 Remove a registered callback. More...
 
static void prometheus_config_post_apply (void)
 Post-apply callback for the config framework. More...
 
static int prometheus_config_pre_apply (void)
 Pre-apply callback for the config framework. More...
 
struct prometheus_metricprometheus_counter_create (const char *name, const char *help)
 Create a malloc'd counter metric. More...
 
struct prometheus_metricprometheus_gauge_create (const char *name, const char *help)
 Create a malloc'd gauge metric. More...
 
void * prometheus_general_config_alloc (void)
 Allocate a new configuration object. More...
 
static void prometheus_general_config_dtor (void *obj)
 
struct prometheus_general_configprometheus_general_config_get (void)
 Retrieve the current configuration of the module. More...
 
void prometheus_general_config_set (struct prometheus_general_config *config)
 Set the configuration for the module. More...
 
int64_t prometheus_last_scrape_duration_get (void)
 Retrieve the amount of time it took to perform the last scrape. More...
 
struct timeval prometheus_last_scrape_time_get (void)
 Retrieve the timestamp when the last scrape occurred. More...
 
static int prometheus_metric_cmp (struct prometheus_metric *left, struct prometheus_metric *right)
 
static struct prometheus_metricprometheus_metric_create (const char *name, const char *help)
 
void prometheus_metric_free (struct prometheus_metric *metric)
 Destroy a metric and all its children. More...
 
static void prometheus_metric_full_to_string (struct prometheus_metric *metric, struct ast_str **output)
 
int prometheus_metric_register (struct prometheus_metric *metric)
 
int prometheus_metric_registered_count (void)
 
void prometheus_metric_to_string (struct prometheus_metric *metric, struct ast_str **output)
 Convert a metric (and its children) into Prometheus compatible text. More...
 
static const char * prometheus_metric_type_to_string (enum prometheus_metric_type type)
 
int prometheus_metric_unregister (struct prometheus_metric *metric)
 Remove a registered metric. More...
 
void prometheus_metrics_provider_register (const struct prometheus_metrics_provider *provider)
 Register a metrics provider. More...
 
struct ast_strprometheus_scrape_to_string (void)
 Get the raw output of what a scrape would produce. More...
 
static int reload_module (void)
 
static void scrape_metrics (struct ast_str **response)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Prometheus Module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_DEFAULT, #ifdef 1 .requires = "res_pjsip", #endif }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct prometheus_metric core_metrics []
 Core metrics to scrape. More...
 
static struct prometheus_metric core_scrape_metric
 The scrape duration metric. More...
 
static struct aco_type global_option
 
struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
 
struct aco_file prometheus_conf
 
static struct ast_http_uri prometheus_uri
 
static ast_mutex_t scrape_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Lock that protects data structures during an HTTP scrape. More...
 

Detailed Description

Core Prometheus metrics API.

Author
Matt Jordan mjord.nosp@m.an@d.nosp@m.igium.nosp@m..com

Definition in file res_prometheus.c.

Macro Definition Documentation

◆ AST_MODULE_SELF_SYM

#define AST_MODULE_SELF_SYM   __internal_res_prometheus_self

Definition at line 121 of file res_prometheus.c.

◆ CORE_LAST_RELOAD_HELP

#define CORE_LAST_RELOAD_HELP   "Time since last Asterisk reload in seconds."

Definition at line 184 of file res_prometheus.c.

◆ CORE_METRICS_SCRAPE_TIME_HELP

#define CORE_METRICS_SCRAPE_TIME_HELP   "Total time taken to collect metrics, in milliseconds"

Definition at line 186 of file res_prometheus.c.

◆ CORE_PROPERTIES_HELP

#define CORE_PROPERTIES_HELP   "Asterisk instance properties. The value of this will always be 1."

Definition at line 180 of file res_prometheus.c.

◆ CORE_UPTIME_HELP

#define CORE_UPTIME_HELP   "Asterisk instance uptime in seconds."

Definition at line 182 of file res_prometheus.c.

◆ METRIC_CORE_PROPS_ARRAY_INDEX

#define METRIC_CORE_PROPS_ARRAY_INDEX   0

Definition at line 220 of file res_prometheus.c.

Referenced by prometheus_config_post_apply().

Function Documentation

◆ __internal_res_prometheus_self()

struct ast_module* __internal_res_prometheus_self ( void  )

Definition at line 1008 of file res_prometheus.c.

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1008 of file res_prometheus.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1008 of file res_prometheus.c.

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( global_config  )
static

The module configuration container.

◆ AST_VECTOR()

AST_VECTOR ( struct prometheus_metric )

The actual module config.

General settings

Definition at line 138 of file res_prometheus.c.

147  {
148  /*! \brief General settings */
149  struct prometheus_general_config *general;
150 };
Prometheus general configuration.

◆ CONFIG_INFO_STANDARD()

CONFIG_INFO_STANDARD ( cfg_info  ,
global_config  ,
module_config_alloc  ,
files = ACO_FILES(&prometheus_conf),
pre_apply_config = prometheus_config_pre_apply,
post_apply_config = prometheus_config_post_apply 
)

Register information about the configs being processed by this module.

◆ get_core_uptime_cb()

static void get_core_uptime_cb ( struct prometheus_metric metric)
static

Definition at line 188 of file res_prometheus.c.

References ast_startuptime, ast_tvdiff_sec(), ast_tvnow(), and prometheus_metric::value.

189 {
190  struct timeval now = ast_tvnow();
191  int64_t duration = ast_tvdiff_sec(now, ast_startuptime);
192 
193  snprintf(metric->value, sizeof(metric->value), "%" PRIu64, duration);
194 }
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:64
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
char value[PROMETHEUS_MAX_VALUE_LENGTH]
The current value.
struct timeval ast_startuptime
Definition: asterisk.c:336

◆ get_last_reload_cb()

static void get_last_reload_cb ( struct prometheus_metric metric)
static

Definition at line 196 of file res_prometheus.c.

References ast_lastreloadtime, ast_tvdiff_sec(), ast_tvnow(), and prometheus_metric::value.

197 {
198  struct timeval now = ast_tvnow();
199  int64_t duration = ast_tvdiff_sec(now, ast_lastreloadtime);
200 
201  snprintf(metric->value, sizeof(metric->value), "%" PRIu64, duration);
202 }
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:64
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
char value[PROMETHEUS_MAX_VALUE_LENGTH]
The current value.

◆ http_callback()

static int http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 593 of file res_prometheus.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_ref, ast_debug, ast_free, ast_http_get_auth(), ast_http_send(), ast_mutex_lock, ast_mutex_unlock, ast_str_append(), ast_str_create, ast_strlen_zero, ast_tvdiff_ms(), ast_tvnow(), NULL, ast_http_auth::password, prometheus_metric_to_string(), RAII_VAR, scrape_lock, scrape_metrics(), ast_http_auth::userid, and prometheus_metric::value.

596 {
598  struct ast_str *response = NULL;
599  struct timeval start;
600  struct timeval end;
601 
602  /* If there is no module config or we're not enabled, we can't handle requests */
603  if (!mod_cfg || !mod_cfg->general->enabled) {
604  goto err503;
605  }
606 
607  if (!ast_strlen_zero(mod_cfg->general->auth_username)) {
608  struct ast_http_auth *http_auth;
609 
610  http_auth = ast_http_get_auth(headers);
611  if (!http_auth) {
612  goto err401;
613  }
614 
615  if (strcmp(http_auth->userid, mod_cfg->general->auth_username)) {
616  ast_debug(5, "Invalid username provided for auth request: %s\n", http_auth->userid);
617  ao2_ref(http_auth, -1);
618  goto err401;
619  }
620 
621  if (strcmp(http_auth->password, mod_cfg->general->auth_password)) {
622  ast_debug(5, "Invalid password provided for auth request: %s\n", http_auth->password);
623  ao2_ref(http_auth, -1);
624  goto err401;
625  }
626 
627  ao2_ref(http_auth, -1);
628  }
629 
630  response = ast_str_create(512);
631  if (!response) {
632  goto err500;
633  }
634 
635  start = ast_tvnow();
636 
638 
639  last_scrape = start;
640  scrape_metrics(&response);
641 
642  if (mod_cfg->general->core_metrics_enabled) {
643  int64_t duration;
644 
645  end = ast_tvnow();
646  duration = ast_tvdiff_ms(end, start);
647  snprintf(core_scrape_metric.value,
648  sizeof(core_scrape_metric.value),
649  "%" PRIu64,
650  duration);
652  }
654 
655  ast_http_send(ser, method, 200, "OK", NULL, response, 0, 0);
656 
657  return 0;
658 
659 err401:
660  {
661  struct ast_str *auth_challenge_headers;
662 
663  auth_challenge_headers = ast_str_create(128);
664  if (!auth_challenge_headers) {
665  goto err500;
666  }
667  ast_str_append(&auth_challenge_headers, 0,
668  "WWW-Authenticate: Basic realm=\"%s\"\r\n",
669  mod_cfg->general->auth_realm);
670  /* ast_http_send takes ownership of the ast_str */
671  ast_http_send(ser, method, 401, "Unauthorized", auth_challenge_headers, NULL, 0, 1);
672  }
673  ast_free(response);
674  return 0;
675 err503:
676  ast_http_send(ser, method, 503, "Service Unavailable", NULL, NULL, 0, 1);
677  ast_free(response);
678  return 0;
679 err500:
680  ast_http_send(ser, method, 500, "Server Error", NULL, NULL, 0, 1);
681  ast_free(response);
682  return 0;
683 }
char * userid
Definition: http.h:125
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
void ast_http_send(struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, int fd, unsigned int static_content)
Generic function for sending HTTP/1.1 response.
Definition: http.c:456
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * method
Definition: res_pjsip.c:4335
The configuration settings for this module.
Definition: cdr.c:222
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char value[PROMETHEUS_MAX_VALUE_LENGTH]
The current value.
char * password
Definition: http.h:127
#define ast_free(a)
Definition: astmm.h:182
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
void prometheus_metric_to_string(struct prometheus_metric *metric, struct ast_str **output)
Convert a metric (and its children) into Prometheus compatible text.
HTTP authentication information.
Definition: http.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_http_auth * ast_http_get_auth(struct ast_variable *headers)
Get HTTP authentication information from headers.
Definition: http.c:1579
static void scrape_metrics(struct ast_str **response)
static struct prometheus_metric core_scrape_metric
The scrape duration metric.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ load_module()

static int load_module ( void  )
static

Definition at line 945 of file res_prometheus.c.

References ACO_EXACT, aco_info_destroy(), aco_info_init(), aco_option_register, aco_process_config(), ACO_PROCESS_ERROR, ast_http_uri_link(), ast_http_uri_unlink(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEFAULT, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_EXTENDED, AST_VECTOR_FREE, AST_VECTOR_INIT, ASTERISK_GPL_KEY, bridge_metrics_init(), channel_metrics_init(), cleanup(), cli_init(), enabled, endpoint_metrics_init(), FLDSET, HAVE_PJPROJECT, lock, OPT_BOOL_T, OPT_STRINGFIELD_T, pjsip_outbound_registration_metrics_init(), providers, reload(), reload_module(), SCOPED_MUTEX, scrape_lock, STRFLDSET, and unload_module().

946 {
948 
949  if (AST_VECTOR_INIT(&metrics, 64)) {
950  goto cleanup;
951  }
952 
953  if (AST_VECTOR_INIT(&callbacks, 8)) {
954  goto cleanup;
955  }
956 
957  if (AST_VECTOR_INIT(&providers, 8)) {
958  goto cleanup;
959  }
960 
961  if (aco_info_init(&cfg_info)) {
962  goto cleanup;
963  }
965  aco_option_register(&cfg_info, "core_metrics_enabled", ACO_EXACT, global_options, "yes", OPT_BOOL_T, 1, FLDSET(struct prometheus_general_config, core_metrics_enabled));
967  aco_option_register(&cfg_info, "auth_username", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct prometheus_general_config, auth_username));
968  aco_option_register(&cfg_info, "auth_password", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct prometheus_general_config, auth_password));
969  aco_option_register(&cfg_info, "auth_realm", ACO_EXACT, global_options, "Asterisk Prometheus Metrics", OPT_STRINGFIELD_T, 0, STRFLDSET(struct prometheus_general_config, auth_realm));
970  if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
971  goto cleanup;
972  }
973 
974  if (cli_init()
979  goto cleanup;
980  }
981 
983  goto cleanup;
984  }
985 
987 
988 cleanup:
990  aco_info_destroy(&cfg_info);
991  AST_VECTOR_FREE(&metrics);
992  AST_VECTOR_FREE(&callbacks);
994 
996 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
int pjsip_outbound_registration_metrics_init(void)
Initialize PJSIP outbound registration metrics.
Prometheus general configuration.
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:673
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:705
static struct ast_http_uri prometheus_uri
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
int endpoint_metrics_init(void)
Initialize endpoint metrics.
int cli_init(void)
Initialize CLI command.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
struct ao2_container * providers
Their was an error and no changes were applied.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
int channel_metrics_init(void)
Initialize channel metrics.
Definition: channels.c:241
Type for default option handler for bools (ast_true/ast_false)
struct aco_type * global_options[]
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
Type for default option handler for stringfields.
int bridge_metrics_init(void)
Initialize bridge metrics.
Definition: bridges.c:183
static int enabled
Definition: dnsmgr.c:91

◆ module_config_alloc()

static void * module_config_alloc ( void  )
static

Module config constructor.

Definition at line 773 of file res_prometheus.c.

References ao2_alloc, ao2_ref, config, module_config::general, module_config_dtor(), NULL, and prometheus_general_config_alloc().

774 {
775  struct module_config *config;
776 
777  config = ao2_alloc(sizeof(*config), module_config_dtor);
778  if (!config) {
779  return NULL;
780  }
781 
783  if (!config->general) {
784  ao2_ref(config, -1);
785  config = NULL;
786  }
787 
788  return config;
789 }
char * config
Definition: conf2ael.c:66
void * prometheus_general_config_alloc(void)
Allocate a new configuration object.
#define NULL
Definition: resample.c:96
static void module_config_dtor(void *obj)
Configuration object destructor.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
The configuration settings for this module.
Definition: cdr.c:222
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ast_cdr_config * general
Definition: cdr.c:223

◆ module_config_dtor()

static void module_config_dtor ( void *  obj)
static

Configuration object destructor.

Definition at line 763 of file res_prometheus.c.

References ao2_ref, config, and module_config::general.

Referenced by module_config_alloc().

764 {
765  struct module_config *config = obj;
766 
767  if (config->general) {
768  ao2_ref(config->general, -1);
769  }
770 }
char * config
Definition: conf2ael.c:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
The configuration settings for this module.
Definition: cdr.c:222
struct ast_cdr_config * general
Definition: cdr.c:223

◆ prometheus_callback_register()

int prometheus_callback_register ( struct prometheus_callback callback)

Register a metric callback

Parameters
callbackThe callback to register
Return values
0success
-1error

Definition at line 535 of file res_prometheus.c.

References ast_strlen_zero, AST_VECTOR_APPEND, prometheus_callback::callback_fn, lock, prometheus_callback::name, SCOPED_MUTEX, and scrape_lock.

Referenced by AST_TEST_DEFINE(), bridge_metrics_init(), channel_metrics_init(), and endpoint_metrics_init().

536 {
538 
539  if (!callback || !callback->callback_fn || ast_strlen_zero(callback->name)) {
540  return -1;
541  }
542 
543  AST_VECTOR_APPEND(&callbacks, callback);
544 
545  return 0;
546 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
const char * name
The name of our callback (always useful for debugging)
#define ast_strlen_zero(foo)
Definition: strings.h:52
void(* callback_fn)(struct ast_str **output)
The callback function to invoke.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.

◆ prometheus_callback_unregister()

void prometheus_callback_unregister ( struct prometheus_callback callback)

Remove a registered callback.

Parameters
callbackThe callback to unregister

Definition at line 548 of file res_prometheus.c.

References AST_VECTOR_GET, AST_VECTOR_REMOVE, AST_VECTOR_SIZE, lock, prometheus_callback::name, SCOPED_MUTEX, and scrape_lock.

Referenced by AST_TEST_DEFINE(), bridge_metrics_unload_cb(), channel_metrics_unload_cb(), and endpoint_metrics_unload_cb().

549 {
551  int i;
552 
553  for (i = 0; i < AST_VECTOR_SIZE(&callbacks); i++) {
554  struct prometheus_callback *entry = AST_VECTOR_GET(&callbacks, i);
555 
556  if (!strcmp(callback->name, entry->name)) {
557  AST_VECTOR_REMOVE(&callbacks, i, 1);
558  return;
559  }
560  }
561 }
const char * name
The name of our callback (always useful for debugging)
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
Definition: search.h:40
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
Defines a callback that will be invoked when the HTTP route is called.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ prometheus_config_post_apply()

static void prometheus_config_post_apply ( void  )
static

Post-apply callback for the config framework.

This sets any run-time information derived from the configuration

Definition at line 827 of file res_prometheus.c.

References ao2_cleanup, ao2_global_obj_ref, ARRAY_LEN, ast_build_date, ast_build_hostname, ast_build_kernel, ast_build_os, ast_eid_default, ast_eid_to_str(), ast_get_build_opts(), ast_get_version(), METRIC_CORE_PROPS_ARRAY_INDEX, prometheus_metric_register(), PROMETHEUS_METRIC_SET_LABEL, prometheus_metric_unregister(), RAII_VAR, ast_http_uri::uri, and value.

Referenced by prometheus_general_config_set().

828 {
830  int i;
831 
832  /* We can get away with this as the lifetime of the URI
833  * registered with the HTTP core is contained within
834  * the lifetime of the module configuration
835  */
836  prometheus_uri.uri = mod_cfg->general->uri;
837 
838  /* Re-register the core metrics */
839  for (i = 0; i < ARRAY_LEN(core_metrics); i++) {
841  }
842  if (mod_cfg->general->core_metrics_enabled) {
843  char eid_str[32];
844  ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
845 
846  PROMETHEUS_METRIC_SET_LABEL(&core_scrape_metric, 0, "eid", eid_str);
847 
849  1, "version", ast_get_version());
850  PROMETHEUS_METRIC_SET_LABEL(&core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX],
851  2, "build_options", ast_get_build_opts());
852  PROMETHEUS_METRIC_SET_LABEL(&core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX],
853  3, "build_date", ast_build_date);
854  PROMETHEUS_METRIC_SET_LABEL(&core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX],
855  4, "build_os", ast_build_os);
856  PROMETHEUS_METRIC_SET_LABEL(&core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX],
857  5, "build_kernel", ast_build_kernel);
858  PROMETHEUS_METRIC_SET_LABEL(&core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX],
859  6, "build_host", ast_build_hostname);
860  snprintf(core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX].value,
861  sizeof(core_metrics[METRIC_CORE_PROPS_ARRAY_INDEX].value),
862  "%d", 1);
863 
864  for (i = 0; i < ARRAY_LEN(core_metrics); i++) {
865  PROMETHEUS_METRIC_SET_LABEL(&core_metrics[i], 0, "eid", eid_str);
867  }
868  }
869 }
int prometheus_metric_unregister(struct prometheus_metric *metric)
Remove a registered metric.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: main/utils.c:2587
#define METRIC_CORE_PROPS_ARRAY_INDEX
const char * ast_get_version(void)
Retrieve the Asterisk version string.
Definition: version.c:16
const char * ast_build_date
Definition: buildinfo.c:33
const char * ast_get_build_opts(void)
Definition: version.c:26
const char * ast_build_os
Definition: buildinfo.c:32
static struct ast_http_uri prometheus_uri
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
int value
Definition: syslog.c:37
const char * ast_build_hostname
Definition: buildinfo.c:29
const char * ast_build_kernel
Definition: buildinfo.c:30
#define PROMETHEUS_METRIC_SET_LABEL(metric, label, n, v)
Convenience macro for setting a label / value in a metric.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
The configuration settings for this module.
Definition: cdr.c:222
int prometheus_metric_register(struct prometheus_metric *metric)
static struct prometheus_metric core_metrics[]
Core metrics to scrape.
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * uri
Definition: http.h:103
static struct prometheus_metric core_scrape_metric
The scrape duration metric.

◆ prometheus_config_pre_apply()

static int prometheus_config_pre_apply ( void  )
static

Pre-apply callback for the config framework.

This validates that required fields exist and are populated.

Definition at line 804 of file res_prometheus.c.

References aco_pending_config(), ast_log, AST_LOG_ERROR, ast_strlen_zero, config, and module_config::general.

805 {
806  struct module_config *config = aco_pending_config(&cfg_info);
807 
808  if (!config->general->enabled) {
809  /* If we're not enabled, we don't care about anything else */
810  return 0;
811  }
812 
813  if (!ast_strlen_zero(config->general->auth_username)
814  && ast_strlen_zero(config->general->auth_password)) {
815  ast_log(AST_LOG_ERROR, "'auth_username' set without a corresponding 'auth_password'\n");
816  return -1;
817  }
818 
819  return 0;
820 }
char * config
Definition: conf2ael.c:66
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
The configuration settings for this module.
Definition: cdr.c:222
struct ast_cdr_config * general
Definition: cdr.c:223

◆ prometheus_counter_create()

struct prometheus_metric* prometheus_counter_create ( const char *  name,
const char *  help 
)

Create a malloc'd counter metric.

Note
The metric must be registered after creation
Parameters
nameThe name of the metric
helpHelp text for the metric
Return values
prometheus_metricon success
NULLon error

Definition at line 452 of file res_prometheus.c.

References NULL, PROMETHEUS_METRIC_COUNTER, prometheus_metric_create(), and prometheus_metric::type.

Referenced by AST_TEST_DEFINE().

453 {
454  struct prometheus_metric *metric;
455 
457  if (!metric) {
458  return NULL;
459  }
461 
462  return metric;
463 }
An actual, honest to god, metric.
A metric whose value always goes up.
enum prometheus_metric_type type
What type of metric we are.
#define NULL
Definition: resample.c:96
static struct prometheus_metric * prometheus_metric_create(const char *name, const char *help)
const char * help
Pointer to a static string defining this metric&#39;s help text.
static const char name[]
Definition: cdr_mysql.c:74

◆ prometheus_gauge_create()

struct prometheus_metric* prometheus_gauge_create ( const char *  name,
const char *  help 
)

Create a malloc'd gauge metric.

Note
The metric must be registered after creation
Parameters
nameThe name of the metric
helpHelp text for the metric
Return values
prometheus_metricon success
NULLon error

Definition at line 439 of file res_prometheus.c.

References NULL, prometheus_metric_create(), PROMETHEUS_METRIC_GAUGE, and prometheus_metric::type.

Referenced by AST_TEST_DEFINE(), and registry_message_cb().

440 {
441  struct prometheus_metric *metric;
442 
444  if (!metric) {
445  return NULL;
446  }
447  metric->type = PROMETHEUS_METRIC_GAUGE;
448 
449  return metric;
450 }
An actual, honest to god, metric.
enum prometheus_metric_type type
What type of metric we are.
#define NULL
Definition: resample.c:96
static struct prometheus_metric * prometheus_metric_create(const char *name, const char *help)
const char * help
Pointer to a static string defining this metric&#39;s help text.
static const char name[]
Definition: cdr_mysql.c:74

◆ prometheus_general_config_alloc()

void* prometheus_general_config_alloc ( void  )

Allocate a new configuration object.

The returned object is an AO2 ref counted object

Return values
NULLon error
configon success

Definition at line 726 of file res_prometheus.c.

References ao2_alloc, ast_string_field_init, config, NULL, and prometheus_general_config_dtor().

Referenced by config_alloc(), and module_config_alloc().

727 {
729 
730  config = ao2_alloc(sizeof(*config), prometheus_general_config_dtor);
731  if (!config || ast_string_field_init(config, 32)) {
732  return NULL;
733  }
734 
735  return config;
736 }
char * config
Definition: conf2ael.c:66
Prometheus general configuration.
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void prometheus_general_config_dtor(void *obj)

◆ prometheus_general_config_dtor()

static void prometheus_general_config_dtor ( void *  obj)
static

Definition at line 719 of file res_prometheus.c.

References ast_string_field_free_memory, and config.

Referenced by prometheus_general_config_alloc().

720 {
721  struct prometheus_general_config *config = obj;
722 
724 }
char * config
Definition: conf2ael.c:66
Prometheus general configuration.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ prometheus_general_config_get()

struct prometheus_general_config* prometheus_general_config_get ( void  )

Retrieve the current configuration of the module.

Note
This should primarily be done for testing purposes.

config is an AO2 ref counted object

Return values
NULLon error
configon success

Definition at line 738 of file res_prometheus.c.

References ao2_bump, ao2_cleanup, ao2_global_obj_ref, NULL, and RAII_VAR.

Referenced by prometheus_show_status(), reload_module(), and test_init_cb().

739 {
741 
742  if (!mod_cfg) {
743  return NULL;
744  }
745  ao2_bump(mod_cfg->general);
746 
747  return mod_cfg->general;
748 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
The configuration settings for this module.
Definition: cdr.c:222
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ prometheus_general_config_set()

void prometheus_general_config_set ( struct prometheus_general_config config)

Set the configuration for the module.

Note
This should primarily be done for testing purposes

This is not a ref-stealing function. The reference count to config will be incremented as a result of calling this method.

Definition at line 750 of file res_prometheus.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_replace, prometheus_config_post_apply(), and RAII_VAR.

Referenced by AST_TEST_DEFINE(), test_cleanup_cb(), and test_init_cb().

751 {
753 
754  if (!mod_cfg) {
755  return;
756  }
757  ao2_replace(mod_cfg->general, config);
759 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
The configuration settings for this module.
Definition: cdr.c:222
#define ao2_replace(dst, src)
Definition: astobj2.h:517
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void prometheus_config_post_apply(void)
Post-apply callback for the config framework.

◆ prometheus_last_scrape_duration_get()

int64_t prometheus_last_scrape_duration_get ( void  )

Retrieve the amount of time it took to perform the last scrape.

Time returned is in milliseconds

Return values
Thescrape duration, in milliseconds

Definition at line 701 of file res_prometheus.c.

References prometheus_metric::value.

Referenced by prometheus_show_status().

702 {
703  int64_t duration;
704 
705  if (sscanf(core_scrape_metric.value, "%" PRIu64, &duration) != 1) {
706  return -1;
707  }
708 
709  return duration;
710 }
char value[PROMETHEUS_MAX_VALUE_LENGTH]
The current value.
static struct prometheus_metric core_scrape_metric
The scrape duration metric.

◆ prometheus_last_scrape_time_get()

struct timeval prometheus_last_scrape_time_get ( void  )

Retrieve the timestamp when the last scrape occurred.

Return values
Thetime when the last scrape occurred

Definition at line 712 of file res_prometheus.c.

References lock, SCOPED_MUTEX, and scrape_lock.

Referenced by prometheus_show_status().

713 {
715 
716  return last_scrape;
717 }
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.

◆ prometheus_metric_cmp()

static int prometheus_metric_cmp ( struct prometheus_metric left,
struct prometheus_metric right 
)
static

Definition at line 252 of file res_prometheus.c.

References ast_debug, prometheus_metric::labels, prometheus_label::name, prometheus_metric::name, PROMETHEUS_MAX_LABELS, and prometheus_label::value.

Referenced by prometheus_metric_register(), and prometheus_metric_unregister().

254 {
255  int i;
256  ast_debug(5, "Comparison: Names %s == %s\n", left->name, right->name);
257  if (strcmp(left->name, right->name)) {
258  return 0;
259  }
260 
261  for (i = 0; i < PROMETHEUS_MAX_LABELS; i++) {
262  ast_debug(5, "Comparison: Label %d Names %s == %s\n", i,
263  left->labels[i].name, right->labels[i].name);
264  if (strcmp(left->labels[i].name, right->labels[i].name)) {
265  return 0;
266  }
267 
268  ast_debug(5, "Comparison: Label %d Values %s == %s\n", i,
269  left->labels[i].value, right->labels[i].value);
270  if (strcmp(left->labels[i].value, right->labels[i].value)) {
271  return 0;
272  }
273  }
274 
275  ast_debug(5, "Copmarison: %s (%p) is equal to %s (%p)\n",
276  left->name, left, right->name, right);
277  return 1;
278 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define PROMETHEUS_MAX_LABELS
How many labels a single metric can have.
char name[PROMETHEUS_MAX_NAME_LENGTH]
The name of the label.
struct prometheus_label labels[PROMETHEUS_MAX_LABELS]
The metric&#39;s labels.
char value[PROMETHEUS_MAX_LABEL_LENGTH]
The value of the label.
char name[PROMETHEUS_MAX_NAME_LENGTH]
Our metric name.

◆ prometheus_metric_create()

static struct prometheus_metric* prometheus_metric_create ( const char *  name,
const char *  help 
)
static

Definition at line 422 of file res_prometheus.c.

References prometheus_metric::allocation_strategy, ast_calloc, ast_copy_string(), ast_mutex_init, prometheus_metric::help, prometheus_metric::lock, prometheus_metric::name, NULL, and PROMETHEUS_METRIC_MALLOCD.

Referenced by prometheus_counter_create(), and prometheus_gauge_create().

423 {
424  struct prometheus_metric *metric = NULL;
425 
426  metric = ast_calloc(1, sizeof(*metric));
427  if (!metric) {
428  return NULL;
429  }
431  ast_mutex_init(&metric->lock);
432 
433  ast_copy_string(metric->name, name, sizeof(metric->name));
434  metric->help = help;
435 
436  return metric;
437 }
An actual, honest to god, metric.
enum prometheus_metric_allocation_strategy allocation_strategy
How this metric was allocated.
#define NULL
Definition: resample.c:96
const char * help
Pointer to a static string defining this metric&#39;s help text.
static const char name[]
Definition: cdr_mysql.c:74
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char name[PROMETHEUS_MAX_NAME_LENGTH]
Our metric name.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
ast_mutex_t lock
A lock protecting the metric value.
The metric was allocated on the heap.
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ prometheus_metric_free()

void prometheus_metric_free ( struct prometheus_metric metric)

Destroy a metric and all its children.

Note
If you still want the children, make sure you remove the head of the children list first.
Parameters
metricThe metric to destroy

Definition at line 392 of file res_prometheus.c.

References prometheus_metric::allocation_strategy, ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_destroy, prometheus_metric::children, prometheus_metric::lock, PROMETHEUS_METRIC_ALLOCD, and PROMETHEUS_METRIC_MALLOCD.

Referenced by AST_TEST_DEFINE(), prometheus_metric_free_wrapper(), prometheus_metric_unregister(), and unload_module().

393 {
394  struct prometheus_metric *child;
395 
396  if (!metric) {
397  return;
398  }
399 
400  while ((child = AST_LIST_REMOVE_HEAD(&metric->children, entry))) {
401  prometheus_metric_free(child);
402  }
403  ast_mutex_destroy(&metric->lock);
404 
406  return;
407  } else if (metric->allocation_strategy == PROMETHEUS_METRIC_MALLOCD) {
408  ast_free(metric);
409  }
410 }
An actual, honest to god, metric.
enum prometheus_metric_allocation_strategy allocation_strategy
How this metric was allocated.
The metric was allocated on the stack.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct prometheus_metric::@312 children
A list of children metrics.
#define ast_free(a)
Definition: astmm.h:182
ast_mutex_t lock
A lock protecting the metric value.
Definition: search.h:40
The metric was allocated on the heap.
#define ast_mutex_destroy(a)
Definition: lock.h:186
void prometheus_metric_free(struct prometheus_metric *metric)
Destroy a metric and all its children.

◆ prometheus_metric_full_to_string()

static void prometheus_metric_full_to_string ( struct prometheus_metric metric,
struct ast_str **  output 
)
static

Definition at line 485 of file res_prometheus.c.

References ast_str_append(), ast_strlen_zero, prometheus_metric::labels, prometheus_label::name, prometheus_metric::name, PROMETHEUS_MAX_LABELS, prometheus_label::value, and prometheus_metric::value.

Referenced by prometheus_metric_to_string().

487 {
488  int i;
489  int labels_exist = 0;
490 
491  ast_str_append(output, 0, "%s", metric->name);
492 
493  for (i = 0; i < PROMETHEUS_MAX_LABELS; i++) {
494  if (!ast_strlen_zero(metric->labels[i].name)) {
495  labels_exist = 1;
496  if (i == 0) {
497  ast_str_append(output, 0, "%s", "{");
498  } else {
499  ast_str_append(output, 0, "%s", ",");
500  }
501  ast_str_append(output, 0, "%s=\"%s\"",
502  metric->labels[i].name,
503  metric->labels[i].value);
504  }
505  }
506 
507  if (labels_exist) {
508  ast_str_append(output, 0, "%s", "}");
509  }
510 
511  /*
512  * If no value exists, put in a 0. That ensures we don't anger Prometheus.
513  */
514  if (ast_strlen_zero(metric->value)) {
515  ast_str_append(output, 0, " 0\n");
516  } else {
517  ast_str_append(output, 0, " %s\n", metric->value);
518  }
519 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define PROMETHEUS_MAX_LABELS
How many labels a single metric can have.
char name[PROMETHEUS_MAX_NAME_LENGTH]
The name of the label.
struct prometheus_label labels[PROMETHEUS_MAX_LABELS]
The metric&#39;s labels.
char value[PROMETHEUS_MAX_VALUE_LENGTH]
The current value.
char value[PROMETHEUS_MAX_LABEL_LENGTH]
The value of the label.
char name[PROMETHEUS_MAX_NAME_LENGTH]
Our metric name.

◆ prometheus_metric_register()

int prometheus_metric_register ( struct prometheus_metric metric)

Register a metric for collection

Parameters
metricThe metric to register
Return values
0success
-1error

Definition at line 287 of file res_prometheus.c.

References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log, AST_LOG_NOTICE, AST_LOG_WARNING, AST_VECTOR_APPEND, AST_VECTOR_GET, AST_VECTOR_SIZE, prometheus_metric::children, lock, prometheus_metric::name, prometheus_metric_cmp(), SCOPED_MUTEX, and scrape_lock.

Referenced by AST_TEST_DEFINE(), prometheus_config_post_apply(), and registry_message_cb().

288 {
290  int i;
291 
292  if (!metric) {
293  return -1;
294  }
295 
296  for (i = 0; i < AST_VECTOR_SIZE(&metrics); i++) {
297  struct prometheus_metric *existing = AST_VECTOR_GET(&metrics, i);
298  struct prometheus_metric *child;
299 
300  if (prometheus_metric_cmp(existing, metric)) {
302  "Refusing registration of existing Prometheus metric: %s\n",
303  metric->name);
304  return -1;
305  }
306 
307  AST_LIST_TRAVERSE(&existing->children, child, entry) {
308  if (prometheus_metric_cmp(child, metric)) {
310  "Refusing registration of existing Prometheus metric: %s\n",
311  metric->name);
312  return -1;
313  }
314  }
315 
316  if (!strcmp(metric->name, existing->name)) {
317  ast_debug(3, "Nesting metric '%s' as child (%p) under existing (%p)\n",
318  metric->name, metric, existing);
319  AST_LIST_INSERT_TAIL(&existing->children, metric, entry);
320  return 0;
321  }
322  }
323 
324  ast_debug(3, "Tracking new root metric '%s'\n", metric->name);
325  if (AST_VECTOR_APPEND(&metrics, metric)) {
326  ast_log(AST_LOG_WARNING, "Failed to grow vector to make room for Prometheus metric: %s\n",
327  metric->name);
328  return -1;
329  }
330 
331  return 0;
332 }
An actual, honest to god, metric.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_LOG_WARNING
Definition: logger.h:279
#define AST_LOG_NOTICE
Definition: logger.h:268
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
struct prometheus_metric::@312 children
A list of children metrics.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char name[PROMETHEUS_MAX_NAME_LENGTH]
Our metric name.
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static int prometheus_metric_cmp(struct prometheus_metric *left, struct prometheus_metric *right)
Definition: search.h:40
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ prometheus_metric_registered_count()

int prometheus_metric_registered_count ( void  )

The current number of registered metrics

Return values
Thecurrent number of registered metrics

Definition at line 280 of file res_prometheus.c.

References AST_VECTOR_SIZE, lock, SCOPED_MUTEX, and scrape_lock.

Referenced by AST_TEST_DEFINE().

281 {
283 
284  return AST_VECTOR_SIZE(&metrics);
285 }
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ prometheus_metric_to_string()

void prometheus_metric_to_string ( struct prometheus_metric metric,
struct ast_str **  output 
)

Convert a metric (and its children) into Prometheus compatible text.

Parameters
metricThe metric to convert to a string
[out]outputThe ast_str string to populate with the metric(s)

Definition at line 521 of file res_prometheus.c.

References AST_LIST_TRAVERSE, ast_str_append(), prometheus_metric::children, prometheus_metric::help, prometheus_metric::name, prometheus_metric_full_to_string(), prometheus_metric_type_to_string(), and prometheus_metric::type.

Referenced by AST_TEST_DEFINE(), bridges_scrape_cb(), channels_scrape_cb(), endpoints_scrape_cb(), http_callback(), prometheus_metric_callback(), and scrape_metrics().

523 {
524  struct prometheus_metric *child;
525 
526  ast_str_append(output, 0, "# HELP %s %s\n", metric->name, metric->help);
527  ast_str_append(output, 0, "# TYPE %s %s\n", metric->name,
529  prometheus_metric_full_to_string(metric, output);
530  AST_LIST_TRAVERSE(&metric->children, child, entry) {
531  prometheus_metric_full_to_string(child, output);
532  }
533 }
An actual, honest to god, metric.
enum prometheus_metric_type type
What type of metric we are.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
static void prometheus_metric_full_to_string(struct prometheus_metric *metric, struct ast_str **output)
struct prometheus_metric::@312 children
A list of children metrics.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const char * help
Pointer to a static string defining this metric&#39;s help text.
char name[PROMETHEUS_MAX_NAME_LENGTH]
Our metric name.
Definition: search.h:40
static const char * prometheus_metric_type_to_string(enum prometheus_metric_type type)

◆ prometheus_metric_type_to_string()

static const char* prometheus_metric_type_to_string ( enum prometheus_metric_type  type)
static

Definition at line 465 of file res_prometheus.c.

References ast_assert, PROMETHEUS_METRIC_COUNTER, and PROMETHEUS_METRIC_GAUGE.

Referenced by prometheus_metric_to_string().

466 {
467  switch (type) {
469  return "counter";
471  return "gauge";
472  default:
473  ast_assert(0);
474  return "unknown";
475  }
476 }
static const char type[]
Definition: chan_ooh323.c:109
A metric whose value always goes up.
#define ast_assert(a)
Definition: utils.h:695

◆ prometheus_metric_unregister()

int prometheus_metric_unregister ( struct prometheus_metric metric)

Remove a registered metric.

Parameters
metricThe metric to unregister
Note
Unregistering also destroys the metric, if found
Return values
0The metric was found, unregistered, and disposed of
-1The metric was not found

Definition at line 334 of file res_prometheus.c.

References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_VECTOR_GET, AST_VECTOR_INSERT_AT, AST_VECTOR_REMOVE, AST_VECTOR_SIZE, prometheus_metric::children, lock, prometheus_metric::name, prometheus_metric_cmp(), prometheus_metric_free(), SCOPED_MUTEX, and scrape_lock.

Referenced by AST_TEST_DEFINE(), prometheus_config_post_apply(), prometheus_metric_free_wrapper(), registration_deleted_observer(), and registration_loaded_observer().

335 {
336  if (!metric) {
337  return -1;
338  }
339 
340  {
342  int i;
343 
344  ast_debug(3, "Removing metric '%s'\n", metric->name);
345  for (i = 0; i < AST_VECTOR_SIZE(&metrics); i++) {
346  struct prometheus_metric *existing = AST_VECTOR_GET(&metrics, i);
347 
348  /*
349  * If this is a complete match, remove the matching metric
350  * and place its children back into the list
351  */
352  if (prometheus_metric_cmp(existing, metric)) {
353  struct prometheus_metric *root;
354 
355  AST_VECTOR_REMOVE(&metrics, i, 1);
356  root = AST_LIST_REMOVE_HEAD(&existing->children, entry);
357  if (root) {
358  struct prometheus_metric *child;
359  AST_LIST_TRAVERSE_SAFE_BEGIN(&existing->children, child, entry) {
361  AST_LIST_INSERT_TAIL(&root->children, child, entry);
362  }
364  AST_VECTOR_INSERT_AT(&metrics, i, root);
365  }
366  prometheus_metric_free(existing);
367  return 0;
368  }
369 
370  /*
371  * Name match, but labels don't match. Find the matching entry with
372  * labels and remove it along with all of its children
373  */
374  if (!strcmp(existing->name, metric->name)) {
375  struct prometheus_metric *child;
376 
377  AST_LIST_TRAVERSE_SAFE_BEGIN(&existing->children, child, entry) {
378  if (prometheus_metric_cmp(child, metric)) {
380  prometheus_metric_free(child);
381  return 0;
382  }
383  }
385  }
386  }
387  }
388 
389  return -1;
390 }
An actual, honest to god, metric.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct prometheus_metric::@312 children
A list of children metrics.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
char name[PROMETHEUS_MAX_NAME_LENGTH]
Our metric name.
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static int prometheus_metric_cmp(struct prometheus_metric *left, struct prometheus_metric *right)
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:338
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
void prometheus_metric_free(struct prometheus_metric *metric)
Destroy a metric and all its children.
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ prometheus_metrics_provider_register()

void prometheus_metrics_provider_register ( const struct prometheus_metrics_provider provider)

Register a metrics provider.

Parameters
providerThe provider function table to register

Definition at line 871 of file res_prometheus.c.

References AST_VECTOR_APPEND, and providers.

Referenced by bridge_metrics_init(), channel_metrics_init(), cli_init(), endpoint_metrics_init(), and pjsip_outbound_registration_metrics_init().

872 {
873  AST_VECTOR_APPEND(&providers, provider);
874 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
struct ao2_container * providers

◆ prometheus_scrape_to_string()

struct ast_str* prometheus_scrape_to_string ( void  )

Get the raw output of what a scrape would produce.

It can be useful to dump what a scrape will look like. This function returns the raw string representation of the metrics.

Return values
NULLon error
Malloc'dast_str on success

Definition at line 685 of file res_prometheus.c.

References ast_mutex_lock, ast_mutex_unlock, ast_str_create, NULL, scrape_lock, and scrape_metrics().

Referenced by prometheus_show_metrics().

686 {
687  struct ast_str *response;
688 
689  response = ast_str_create(512);
690  if (!response) {
691  return NULL;
692  }
693 
695  scrape_metrics(&response);
697 
698  return response;
699 }
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
static void scrape_metrics(struct ast_str **response)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 910 of file res_prometheus.c.

References aco_process_config(), ACO_PROCESS_ERROR, ao2_ref, ast_http_uri_link(), ast_http_uri_unlink(), ast_log, AST_LOG_WARNING, AST_VECTOR_GET, AST_VECTOR_SIZE, lock, prometheus_metrics_provider::name, prometheus_general_config_get(), provider, providers, prometheus_metrics_provider::reload_cb, SCOPED_MUTEX, and scrape_lock.

Referenced by load_module().

910  {
912  int i;
913  struct prometheus_general_config *general_config;
914 
916  if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
917  return -1;
918  }
919 
920  /* Our config should be all reloaded now */
921  general_config = prometheus_general_config_get();
922  for (i = 0; i < AST_VECTOR_SIZE(&providers); i++) {
924 
925  if (!provider->reload_cb) {
926  continue;
927  }
928 
929  if (provider->reload_cb(general_config)) {
930  ast_log(AST_LOG_WARNING, "Failed to reload metrics provider %s\n", provider->name);
931  ao2_ref(general_config, -1);
932  return -1;
933  }
934  }
935  ao2_ref(general_config, -1);
936 
938  ast_log(AST_LOG_WARNING, "Failed to re-register Prometheus Metrics URI during reload\n");
939  return -1;
940  }
941 
942  return 0;
943 }
Prometheus general configuration.
struct prometheus_general_config * prometheus_general_config_get(void)
Retrieve the current configuration of the module.
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:673
#define AST_LOG_WARNING
Definition: logger.h:279
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:705
static struct ast_http_uri prometheus_uri
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define ast_log
Definition: astobj2.c:42
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * providers
Their was an error and no changes were applied.
int(*const reload_cb)(struct prometheus_general_config *config)
Reload callback.
const char * name
Handy name of the provider for debugging purposes.
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
A function table for a metrics provider.
static struct prometheus_metrics_provider provider
Definition: bridges.c:178
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ scrape_metrics()

static void scrape_metrics ( struct ast_str **  response)
static

Definition at line 563 of file res_prometheus.c.

References ast_mutex_lock, ast_mutex_unlock, AST_VECTOR_GET, AST_VECTOR_SIZE, prometheus_callback::callback_fn, prometheus_metric::get_metric_value, prometheus_metric::lock, and prometheus_metric_to_string().

Referenced by http_callback(), and prometheus_scrape_to_string().

564 {
565  int i;
566 
567  for (i = 0; i < AST_VECTOR_SIZE(&callbacks); i++) {
568  struct prometheus_callback *callback = AST_VECTOR_GET(&callbacks, i);
569 
570  if (!callback) {
571  continue;
572  }
573 
574  callback->callback_fn(response);
575  }
576 
577  for (i = 0; i < AST_VECTOR_SIZE(&metrics); i++) {
578  struct prometheus_metric *metric = AST_VECTOR_GET(&metrics, i);
579 
580  if (!metric) {
581  continue;
582  }
583 
584  ast_mutex_lock(&metric->lock);
585  if (metric->get_metric_value) {
586  metric->get_metric_value(metric);
587  }
588  prometheus_metric_to_string(metric, response);
589  ast_mutex_unlock(&metric->lock);
590  }
591 }
An actual, honest to god, metric.
void(* get_metric_value)(struct prometheus_metric *metric)
#define ast_mutex_lock(a)
Definition: lock.h:187
void(* callback_fn)(struct ast_str **output)
The callback function to invoke.
void prometheus_metric_to_string(struct prometheus_metric *metric, struct ast_str **output)
Convert a metric (and its children) into Prometheus compatible text.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
ast_mutex_t lock
A lock protecting the metric value.
Defines a callback that will be invoked when the HTTP route is called.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 876 of file res_prometheus.c.

References aco_info_destroy(), ao2_global_obj_release, ast_http_uri_unlink(), AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_SIZE, lock, prometheus_metric_free(), provider, providers, SCOPED_MUTEX, scrape_lock, and prometheus_metrics_provider::unload_cb.

Referenced by load_module().

877 {
879  int i;
880 
882 
883  for (i = 0; i < AST_VECTOR_SIZE(&providers); i++) {
885 
886  if (!provider->unload_cb) {
887  continue;
888  }
889 
890  provider->unload_cb();
891  }
892 
893  for (i = 0; i < AST_VECTOR_SIZE(&metrics); i++) {
894  struct prometheus_metric *metric = AST_VECTOR_GET(&metrics, i);
895 
896  prometheus_metric_free(metric);
897  }
898  AST_VECTOR_FREE(&metrics);
899 
900  AST_VECTOR_FREE(&callbacks);
901 
903 
904  aco_info_destroy(&cfg_info);
906 
907  return 0;
908 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
An actual, honest to god, metric.
void(*const unload_cb)(void)
Unload callback.
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:705
static struct ast_http_uri prometheus_uri
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
struct ao2_container * providers
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
static ast_mutex_t scrape_lock
Lock that protects data structures during an HTTP scrape.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
A function table for a metrics provider.
void prometheus_metric_free(struct prometheus_metric *metric)
Destroy a metric and all its children.
static struct prometheus_metrics_provider provider
Definition: bridges.c:178
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Prometheus Module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_DEFAULT, #ifdef 1 .requires = "res_pjsip", #endif }
static

Definition at line 1008 of file res_prometheus.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1008 of file res_prometheus.c.

◆ core_metrics

struct prometheus_metric core_metrics[]
static

Core metrics to scrape.

Definition at line 224 of file res_prometheus.c.

◆ core_scrape_metric

struct prometheus_metric core_scrape_metric
static

The scrape duration metric.

This metric is special in that it should never be registered. Instead, the HTTP callback function that walks the metrics will always populate this metric explicitly if core metrics are enabled.

Definition at line 213 of file res_prometheus.c.

◆ global_option

struct aco_type global_option
static

Definition at line 152 of file res_prometheus.c.

◆ global_options

struct aco_type* global_options[] = ACO_TYPES(&global_option)

Definition at line 160 of file res_prometheus.c.

◆ prometheus_conf

struct aco_file prometheus_conf
Initial value:
= {
.filename = "prometheus.conf",
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type global_option

Definition at line 162 of file res_prometheus.c.

◆ prometheus_uri

struct ast_http_uri prometheus_uri
static

Definition at line 791 of file res_prometheus.c.

◆ scrape_lock

ast_mutex_t scrape_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static