From 90d9a70789a0874cff3a29caca5046995a54dbd4 Mon Sep 17 00:00:00 2001 From: Matt Jordan Date: Wed, 18 Nov 2015 10:07:09 -0600 Subject: res_pjsip/pjsip_options: Add StatsD statistics for PJSIP contacts This patch adds the ability to send StatsD statistics related to the state of PJSIP contacts. This includes: * A GUAGE statistic measuring the count of contacts in a particular state. This measures how many contacts are reachable, unreachable, etc. * The RTT time for each contact, if those contacts are qualified. This provides StatsD engines useful time-based data about each contact. ASTERISK-25571 Change-Id: Ib8378d73afedfc622be0643b87c542557e0b332c --- CHANGES | 8 ++++++++ res/res_pjsip/location.c | 12 ++++++++++++ res/res_pjsip/pjsip_options.c | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 348927b1d..fcbbcec29 100644 --- a/CHANGES +++ b/CHANGES @@ -55,6 +55,14 @@ res_pjsip * The ability to use "like" has been added to the pjsip list and show CLI commands. For instance: CLI> pjsip list endpoints like abc + * If res_statsd is loaded and a StatsD server is configured, basic statistics + regarding the state of PJSIP contacts will not be emitted. This includes: + - A GUAGE statistic for the overall number of contacts in a particular + state, e.g.: + PJSIP.contacts.states.Reachable + - A TIMER statistic for the RTT time for each qualified contact, e.g.: + PJSIP.contacts.alice@@127.0.0.1:5061.rtt + func_callerid ------------------- * CALLERID(pres) is now documented as a valid alternative to setting both diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index eef1d43d2..9cc7f1629 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -26,6 +26,7 @@ #include "asterisk/sorcery.h" #include "include/res_pjsip_private.h" #include "asterisk/res_pjsip_cli.h" +#include "asterisk/statsd.h" /*! \brief Destructor for AOR */ static void aor_destroy(void *obj) @@ -940,6 +941,8 @@ static int contact_apply_handler(const struct ast_sorcery *sorcery, void *object int ast_sip_initialize_sorcery_location(void) { struct ast_sorcery *sorcery = ast_sip_get_sorcery(); + int i; + ast_sorcery_apply_default(sorcery, "contact", "astdb", "registrar"); ast_sorcery_apply_default(sorcery, "aor", "config", "pjsip.conf,criteria=type=aor"); @@ -1006,6 +1009,15 @@ int ast_sip_initialize_sorcery_location(void) ast_sip_register_cli_formatter(aor_formatter); ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands)); + /* + * Reset StatsD gauges in case we didn't shut down cleanly. + * Note that this must done here, as contacts will create the contact_status + * object before PJSIP options handling is initialized. + */ + for (i = 0; i < REMOVED; i++) { + ast_statsd_log_full_va("PJSIP.contacts.states.%s", AST_STATSD_GUAGE, 0, 1.0, ast_sip_get_contact_status_label(i)); + } + return 0; } diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index 32ee401ea..58519a91f 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -29,6 +29,7 @@ #include "asterisk/cli.h" #include "asterisk/time.h" #include "asterisk/test.h" +#include "asterisk/statsd.h" #include "include/res_pjsip_private.h" #define DEFAULT_LANGUAGE "en" @@ -113,6 +114,9 @@ struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const return NULL; } + ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GUAGE, + "+1", 1.0, ast_sip_get_contact_status_label(status->status)); + return status; } @@ -143,6 +147,12 @@ static void update_contact_status(const struct ast_sip_contact *contact, update->last_status = status->status; update->status = value; + if (update->last_status != update->status) { + ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GUAGE, + "-1", 1.0, ast_sip_get_contact_status_label(update->last_status)); + ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GUAGE, + "+1", 1.0, ast_sip_get_contact_status_label(update->status)); + } /* if the contact is available calculate the rtt as the diff between the last start time and "now" */ @@ -151,10 +161,12 @@ static void update_contact_status(const struct ast_sip_contact *contact, update->rtt_start = ast_tv(0, 0); + ast_statsd_log_full_va("PJSIP.contacts.%s.rtt", AST_STATSD_TIMER, + update->rtt / 1000, 1.0, ast_sorcery_object_get_id(update)); ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT", "Contact: %s\r\n" - "Status: %s\r\n" - "RTT: %" PRId64, + "Status: %s\r\n" + "RTT: %" PRId64, ast_sorcery_object_get_id(update), ast_sip_get_contact_status_label(update->status), update->rtt); -- cgit v1.2.3