123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /*$Id$
- *
- * Copyright (C) 2010 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- /**
- * @brief counters/statistics rpcs and script functions
- * @file
- * @ingroup counters
- * Module: counters.
- */
-
- /*
- * History:
- * -------
- * 2010-08-06 created by andrei
- */
- #include "../../modparam.h"
- #include "../../dprint.h"
- #include "../../compiler_opt.h"
- #include "../../counters.h"
- MODULE_VERSION
- /* default script counter group name */
- static char* cnt_script_grp = "script";
- static int add_script_counter(modparam_t type, void* val);
- static int cnt_inc_f(struct sip_msg*, char*, char*);
- static int cnt_add_f(struct sip_msg*, char*, char*);
- static int cnt_reset_f(struct sip_msg*, char*, char*);
- static int cnt_fixup1(void** param, int param_no);
- static int cnt_int_fixup(void** param, int param_no);
- static cmd_export_t cmds[] = {
- {"cnt_inc", cnt_inc_f, 1, cnt_fixup1,
- REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
- {"cnt_add", cnt_add_f, 2, cnt_int_fixup,
- REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
- {"cnt_reset", cnt_reset_f, 1, cnt_fixup1,
- REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
- {0,0,0,0,0}
- };
- static param_export_t params[] = {
- {"script_cnt_grp_name", PARAM_STRING, &cnt_script_grp},
- {"script_counter", PARAM_STRING|PARAM_USE_FUNC, add_script_counter},
- {0,0,0}
- };
- static void cnt_get_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_get_doc[] = {
- "get counter value (takes group and counter name as parameters)", 0
- };
- static void cnt_reset_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_reset_doc[] = {
- "reset counter (takes group and counter name as parameters)", 0
- };
- static void cnt_get_raw_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_get_raw_doc[] = {
- "get raw counter value (debugging version)", 0
- };
- static void cnt_grps_list_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_grps_list_doc[] = {
- "list all the counter group names", 0
- };
- static void cnt_var_list_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_var_list_doc[] = {
- "list all the counters names in a specified group", 0
- };
- static void cnt_grp_get_all_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_grp_get_all_doc[] = {
- "list all counter names and values in a specified group", 0
- };
- static void cnt_help_rpc(rpc_t* rpc, void* ctx);
- static const char* cnt_help_doc[] = {
- "print the description of a counter (group and counter name required).", 0
- };
- static rpc_export_t counters_rpc[] = {
- {"cnt.get", cnt_get_rpc, cnt_get_doc, 0 },
- {"cnt.reset", cnt_reset_rpc, cnt_reset_doc, 0 },
- {"cnt.get_raw", cnt_get_raw_rpc, cnt_get_raw_doc, 0 },
- {"cnt.grps_list", cnt_grps_list_rpc, cnt_grps_list_doc, RET_ARRAY },
- {"cnt.var_list", cnt_var_list_rpc, cnt_var_list_doc, RET_ARRAY },
- {"cnt.grp_get_all", cnt_grp_get_all_rpc, cnt_grp_get_all_doc, 0 },
- {"cnt.help", cnt_help_rpc, cnt_help_doc, 0},
- { 0, 0, 0, 0}
- };
- struct module_exports exports= {
- "counters",
- cmds,
- counters_rpc, /* RPC methods */
- params,
- 0, /* module initialization function */
- 0, /* response function */
- 0, /* destroy function */
- 0, /* on_cancel function */
- 0, /* per-child init function */
- };
- /** parse the the script_counter modparam.
- * Format: [grp.]name[( |:)desc]
- * E.g.:
- * "name" => new counter: *cnt_script_grp."name"
- * "grp.name" => new counter: "grp"."name"
- * "name desc" => new counter "name", desc = "desc"
- * "grp.name desc" => "grp"."name", desc = "desc".
- */
- static int add_script_counter(modparam_t type, void* val)
- {
- char* name;
- counter_handle_t h;
- int ret;
- char* grp;
- char* desc;
- char* p;
- if ((type & PARAM_STRING) == 0) {
- BUG("bad parameter type %d\n", type);
- goto error;
- }
- name = (char*) val;
- grp = cnt_script_grp; /* default group */
- desc = "custom script counter."; /* default desc. */
- if ((p = strchr(name, ':')) != 0 ||
- (p = strchr(name, ' ')) != 0) {
- /* found desc. */
- *p = 0;
- for(p = p+1; *p && (*p == ' ' || *p == '\t'); p++);
- if (*p)
- desc = p;
- }
- if ((p = strchr(name, '.')) != 0) {
- /* found group */
- grp = name;
- *p = 0;
- name = p+1;
- }
- ret = counter_register(&h, grp, name, 0, 0, 0, desc, 0);
- if (ret < 0) {
- if (ret == -2) {
- ERR("counter %s.%s already registered\n", grp, name);
- return 0;
- }
- ERR("failed to register counter %s.%s\n", grp, name);
- goto error;
- }
- return 0;
- error:
- return -1;
- }
- static int cnt_fixup1(void** param, int param_no)
- {
- char* name;
- char* grp;
- char* p;
- counter_handle_t h;
- name = (char*)*param;
- grp = cnt_script_grp; /* default group */
- if ((p = strchr(name, '.')) != 0) {
- /* found group */
- grp = name;
- name = p+1;
- *p = 0;
- }
- if (counter_lookup(&h, grp, name) < 0) {
- ERR("counter %s.%s does not exist (forgot to define it?)\n",
- grp, name);
- return -1;
- }
- *param = (void*)(long)h.id;
- return 0;
- }
- static int cnt_int_fixup(void** param, int param_no)
- {
- char* name;
- char* grp;
- char* p;
- counter_handle_t h;
- if (param_no == 1) {
- name = (char*)*param;
- grp = cnt_script_grp; /* default group */
- if ((p = strchr(name, '.')) != 0) {
- /* found group */
- grp = name;
- name = p+1;
- *p = 0;
- }
- if (counter_lookup(&h, grp, name) < 0) {
- ERR("counter %s.%s does not exist (forgot to define it?)\n",
- grp, name);
- return -1;
- }
- *param = (void*)(long)h.id;
- } else
- return fixup_var_int_2(param, param_no);
- return 0;
- }
- static int cnt_inc_f(struct sip_msg* msg, char* handle, char* bar)
- {
- counter_handle_t h;
-
- h.id = (long)(void*)handle;
- counter_inc(h);
- return 1;
- }
- static int cnt_add_f(struct sip_msg* msg, char* handle, char* val)
- {
- counter_handle_t h;
- int v;
-
- h.id = (long)(void*)handle;
- if (unlikely(get_int_fparam(&v, msg, (fparam_t*)val) < 0)) {
- ERR("non integer parameter\n");
- return -1;
- }
- counter_add(h, v);
- return 1;
- }
- static int cnt_reset_f(struct sip_msg* msg, char* handle, char* bar)
- {
- counter_handle_t h;
-
- h.id = (long)(void*)handle;
- counter_reset(h);
- return 1;
- }
- static void cnt_grp_get_all(rpc_t* rpc, void* c, char* group);
- static void cnt_get_rpc(rpc_t* rpc, void* c)
- {
- char* group;
- char* name;
- counter_val_t v;
- counter_handle_t h;
-
- if (rpc->scan(c, "s", &group) < 1)
- return;
- if (rpc->scan(c, "*s", &name) < 1)
- return cnt_grp_get_all(rpc, c, group);
- /* group & name read */
- if (counter_lookup(&h, group, name) < 0) {
- rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
- return;
- }
- v = counter_get_val(h);
- rpc->add(c, "d", (int)v);
- return;
- }
- static void cnt_get_raw_rpc(rpc_t* rpc, void* c)
- {
- char* group;
- char* name;
- counter_val_t v;
- counter_handle_t h;
-
- if (rpc->scan(c, "ss", &group, &name) < 2) {
- /* rpc->fault(c, 400, "group and counter name required"); */
- return;
- }
- if (counter_lookup(&h, group, name) < 0) {
- rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
- return;
- }
- v = counter_get_raw_val(h);
- rpc->add(c, "d", (int)v);
- return;
- }
- static void cnt_reset_rpc(rpc_t* rpc, void* c)
- {
- char* group;
- char* name;
- counter_handle_t h;
-
- if (rpc->scan(c, "ss", &group, &name) < 2) {
- /* rpc->fault(c, 400, "group and counter name required"); */
- return;
- }
- if (counter_lookup(&h, group, name) < 0) {
- rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
- return;
- }
- counter_reset(h);
- return;
- }
- struct rpc_list_params {
- rpc_t* rpc;
- void* ctx;
- };
- /* helper callback for iterating groups or names */
- static void rpc_print_name(void* param, str* n)
- {
- struct rpc_list_params* p;
- rpc_t* rpc;
- void* ctx;
- p = param;
- rpc = p->rpc;
- ctx = p->ctx;
- rpc->add(ctx, "S", n);
- }
- /* helper callback for iterating on variable names & values*/
- static void rpc_print_name_val(void* param, str* g, str* n,
- counter_handle_t h)
- {
- struct rpc_list_params* p;
- rpc_t* rpc;
- void* s;
- p = param;
- rpc = p->rpc;
- s = p->ctx;
- rpc->struct_add(s, "d", n->s, (int)counter_get_val(h));
- }
- static void cnt_grps_list_rpc(rpc_t* rpc, void* c)
- {
- struct rpc_list_params packed_params;
-
- packed_params.rpc = rpc;
- packed_params.ctx = c;
- counter_iterate_grp_names(rpc_print_name, &packed_params);
- }
- static void cnt_var_list_rpc(rpc_t* rpc, void* c)
- {
- char* group;
- struct rpc_list_params packed_params;
-
- if (rpc->scan(c, "s", &group) < 1) {
- /* rpc->fault(c, 400, "group name required"); */
- return;
- }
- packed_params.rpc = rpc;
- packed_params.ctx = c;
- counter_iterate_grp_var_names(group, rpc_print_name, &packed_params);
- }
- static void cnt_grp_get_all(rpc_t* rpc, void* c, char* group)
- {
- void* s;
- struct rpc_list_params packed_params;
-
- if (rpc->add(c, "{", &s) < 0) return;
- packed_params.rpc = rpc;
- packed_params.ctx = s;
- counter_iterate_grp_vars(group, rpc_print_name_val, &packed_params);
- }
- static void cnt_grp_get_all_rpc(rpc_t* rpc, void* c)
- {
- char* group;
-
- if (rpc->scan(c, "s", &group) < 1) {
- /* rpc->fault(c, 400, "group name required"); */
- return;
- }
- return cnt_grp_get_all(rpc, c, group);
- }
- static void cnt_help_rpc(rpc_t* rpc, void* ctx)
- {
- char* group;
- char* name;
- char* desc;
- counter_handle_t h;
-
- if (rpc->scan(ctx, "ss", &group, &name) < 2) {
- /* rpc->fault(c, 400, "group and counter name required"); */
- return;
- }
- if (counter_lookup(&h, group, name) < 0) {
- rpc->fault(ctx, 400, "non-existent counter %s.%s\n", group, name);
- return;
- }
- desc = counter_get_doc(h);
- if (desc)
- rpc->add(ctx, "s", desc);
- else
- rpc->fault(ctx, 400, "no description for counter %s.%s\n",
- group, name);
- return;
- }
- /* vi: set ts=4 sw=4 tw=79:ai:cindent: */
|