Asterisk - The Open Source Telephony Project  18.5.0
res_chan_stats.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <[email protected]>
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  * \brief Statsd channel stats. Exmaple of how to subscribe to Stasis events.
21  *
22  * This module subscribes to the channel caching topic and issues statsd stats
23  * based on the received messages.
24  *
25  * \author David M. Lee, II <[email protected]>
26  * \since 12
27  */
28 
29 /*** MODULEINFO
30  <depend>res_statsd</depend>
31  <defaultenabled>no</defaultenabled>
32  <support_level>extended</support_level>
33  ***/
34 
35 #include "asterisk.h"
36 
37 #include "asterisk/module.h"
40 #include "asterisk/statsd.h"
41 #include "asterisk/time.h"
42 
43 /*! Regular Stasis subscription */
44 static struct stasis_subscription *sub;
45 /*! Stasis message router */
47 
48 /*!
49  * \brief Subscription callback for all channel messages.
50  * \param data Data pointer given when creating the subscription.
51  * \param sub This subscription.
52  * \param topic The topic the message was posted to. This is not necessarily the
53  * topic you subscribed to, since messages may be forwarded between
54  * topics.
55  * \param message The message itself.
56  */
57 static void statsmaker(void *data, struct stasis_subscription *sub,
58  struct stasis_message *message)
59 {
60  RAII_VAR(struct ast_str *, metric, NULL, ast_free);
61 
62  if (stasis_subscription_final_message(sub, message)) {
63  /* Normally, data points to an object that must be cleaned up.
64  * The final message is an unsubscribe notification that's
65  * guaranteed to be the last message this subscription receives.
66  * This would be a safe place to kick off any needed cleanup.
67  */
68  return;
69  }
70 
71  /* For no good reason, count message types */
72  metric = ast_str_create(80);
73  if (metric) {
74  ast_str_set(&metric, 0, "stasis.message.%s",
77  }
78 }
79 
80 /*!
81  * \brief Router callback for \ref ast_channel_snapshot_update messages.
82  * \param data Data pointer given when added to router.
83  * \param sub This subscription.
84  * \param topic The topic the message was posted to. This is not necessarily the
85  * topic you subscribed to, since messages may be forwarded between
86  * topics.
87  * \param message The message itself.
88  */
89 static void updates(void *data, struct stasis_subscription *sub,
90  struct stasis_message *message)
91 {
92  /* Since this came from a message router, we know the type of the
93  * message. We can cast the data without checking its type.
94  */
96 
97  /* There are three types of channel snapshot updates.
98  * !old && new -> Initial channel creation
99  * old && new -> Updated channel snapshot
100  * old && dead -> Final channel snapshot
101  */
102 
103  if (!update->old_snapshot && update->new_snapshot) {
104  /* Initial channel snapshot; count a channel creation */
105  ast_statsd_log_string("channels.count", AST_STATSD_GAUGE, "+1", 1.0);
106  } else if (update->old_snapshot && ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
107  /* Channel is gone. Compute the age of the channel and post
108  * that, as well as decrementing the channel count.
109  */
110  int64_t age;
111 
112  age = ast_tvdiff_ms(*stasis_message_timestamp(message),
113  update->new_snapshot->base->creationtime);
114  ast_statsd_log("channels.calltime", AST_STATSD_TIMER, age);
115 
116  /* And decrement the channel count */
117  ast_statsd_log_string("channels.count", AST_STATSD_GAUGE, "-1", 1.0);
118  }
119 }
120 
121 /*!
122  * \brief Router callback for any message that doesn't otherwise have a route.
123  * \param data Data pointer given when added to router.
124  * \param sub This subscription.
125  * \param topic The topic the message was posted to. This is not necessarily the
126  * topic you subscribed to, since messages may be forwarded between
127  * topics.
128  * \param message The message itself.
129  */
130 static void default_route(void *data, struct stasis_subscription *sub,
131  struct stasis_message *message)
132 {
133  if (stasis_subscription_final_message(sub, message)) {
134  /* Much like with the regular subscription, you may need to
135  * perform some cleanup when done with a message router. You
136  * can look for the final message in the default route.
137  */
138  return;
139  }
140 }
141 
142 static int unload_module(void)
143 {
145  sub = NULL;
147  router = NULL;
148  return 0;
149 }
150 
151 static int load_module(void)
152 {
153  /* You can create a message router to route messages by type */
156  if (!router) {
158  }
160  updates, NULL);
162 
163  /* Or a subscription to receive all of the messages from a topic */
165  if (!sub) {
166  unload_module();
168  }
170 }
171 
172 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Example of how to use Stasis",
173  .support_level = AST_MODULE_SUPPORT_EXTENDED,
174  .load = load_module,
175  .unload = unload_module,
176  .requires = "res_statsd"
177 );
const char * stasis_message_type_name(const struct stasis_message_type *type)
Gets the name of a given message type.
struct ast_channel_snapshot_base * base
Asterisk main include file. File version handling, generic pbx functions.
static int unload_module(void)
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
Time-related functions and macros.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed...
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define AST_STATSD_METER
Definition: statsd.h:45
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
Structure representing a change of snapshot of channel state.
void ast_statsd_log_string(const char *metric_name, const char *metric_type, const char *value, double sample_rate)
Send a stat to the configured statsd server.
Definition: res_statsd.c:111
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
static void default_route(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Router callback for any message that doesn&#39;t otherwise have a route.
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
#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
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
static void updates(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Router callback for ast_channel_snapshot_update messages.
static struct stasis_message_router * router
static int load_module(void)
void ast_statsd_log(const char *metric_name, const char *metric_type, intmax_t value)
Send a stat to the configured statsd server.
Definition: res_statsd.c:222
#define stasis_message_router_create(topic)
static void statsmaker(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Subscription callback for all channel messages.
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
Definition: stasis.c:1176
#define ast_free(a)
Definition: astmm.h:182
#define AST_STATSD_TIMER
Definition: statsd.h:41
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136
struct ast_channel_snapshot * new_snapshot
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int stasis_message_router_set_default(struct stasis_message_router *router, stasis_subscription_cb callback, void *data)
Sets the default route of a router.
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
struct ast_channel_snapshot * old_snapshot
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
#define AST_STATSD_GAUGE
Support for publishing to a statsd server.
Definition: statsd.h:32
struct ast_flags flags
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620