00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025
00026
00027
00028
00029
00030
00031
00032 #include "../../modparam.h"
00033 #include "../../dprint.h"
00034 #include "../../compiler_opt.h"
00035 #include "../../counters.h"
00036
00037 MODULE_VERSION
00038
00039
00040 static char* cnt_script_grp = "script";
00041
00042 static int add_script_counter(modparam_t type, void* val);
00043 static int cnt_inc_f(struct sip_msg*, char*, char*);
00044 static int cnt_add_f(struct sip_msg*, char*, char*);
00045 static int cnt_reset_f(struct sip_msg*, char*, char*);
00046 static int cnt_fixup1(void** param, int param_no);
00047 static int cnt_int_fixup(void** param, int param_no);
00048
00049
00050
00051 static cmd_export_t cmds[] = {
00052 {"cnt_inc", cnt_inc_f, 1, cnt_fixup1,
00053 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
00054 {"cnt_add", cnt_add_f, 2, cnt_int_fixup,
00055 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
00056 {"cnt_reset", cnt_reset_f, 1, cnt_fixup1,
00057 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
00058 {0,0,0,0,0}
00059 };
00060
00061 static param_export_t params[] = {
00062 {"script_cnt_grp_name", PARAM_STRING, &cnt_script_grp},
00063 {"script_counter", PARAM_STRING|PARAM_USE_FUNC, add_script_counter},
00064 {0,0,0}
00065 };
00066
00067
00068 static void cnt_get_rpc(rpc_t* rpc, void* ctx);
00069 static const char* cnt_get_doc[] = {
00070 "get counter value (takes group and counter name as parameters)", 0
00071 };
00072
00073 static void cnt_reset_rpc(rpc_t* rpc, void* ctx);
00074 static const char* cnt_reset_doc[] = {
00075 "reset counter (takes group and counter name as parameters)", 0
00076 };
00077
00078 static void cnt_get_raw_rpc(rpc_t* rpc, void* ctx);
00079 static const char* cnt_get_raw_doc[] = {
00080 "get raw counter value (debugging version)", 0
00081 };
00082
00083 static void cnt_grps_list_rpc(rpc_t* rpc, void* ctx);
00084 static const char* cnt_grps_list_doc[] = {
00085 "list all the counter group names", 0
00086 };
00087
00088 static void cnt_var_list_rpc(rpc_t* rpc, void* ctx);
00089 static const char* cnt_var_list_doc[] = {
00090 "list all the counters names in a specified group", 0
00091 };
00092
00093 static void cnt_grp_get_all_rpc(rpc_t* rpc, void* ctx);
00094 static const char* cnt_grp_get_all_doc[] = {
00095 "list all counter names and values in a specified group", 0
00096 };
00097
00098 static void cnt_help_rpc(rpc_t* rpc, void* ctx);
00099 static const char* cnt_help_doc[] = {
00100 "print the description of a counter (group and counter name required).", 0
00101 };
00102
00103
00104
00105 static rpc_export_t counters_rpc[] = {
00106 {"cnt.get", cnt_get_rpc, cnt_get_doc, 0 },
00107 {"cnt.reset", cnt_reset_rpc, cnt_reset_doc, 0 },
00108 {"cnt.get_raw", cnt_get_raw_rpc, cnt_get_raw_doc, 0 },
00109 {"cnt.grps_list", cnt_grps_list_rpc, cnt_grps_list_doc, RET_ARRAY },
00110 {"cnt.var_list", cnt_var_list_rpc, cnt_var_list_doc, RET_ARRAY },
00111 {"cnt.grp_get_all", cnt_grp_get_all_rpc, cnt_grp_get_all_doc, 0 },
00112 {"cnt.help", cnt_help_rpc, cnt_help_doc, 0},
00113 { 0, 0, 0, 0}
00114 };
00115
00116
00117
00118 struct module_exports exports= {
00119 "counters",
00120 cmds,
00121 counters_rpc,
00122 params,
00123 0,
00124 0,
00125 0,
00126 0,
00127 0,
00128 };
00129
00130
00131
00140 static int add_script_counter(modparam_t type, void* val)
00141 {
00142 char* name;
00143 counter_handle_t h;
00144 int ret;
00145 char* grp;
00146 char* desc;
00147 char* p;
00148
00149 if ((type & PARAM_STRING) == 0) {
00150 BUG("bad parameter type %d\n", type);
00151 goto error;
00152 }
00153 name = (char*) val;
00154 grp = cnt_script_grp;
00155 desc = "custom script counter.";
00156 if ((p = strchr(name, ':')) != 0 ||
00157 (p = strchr(name, ' ')) != 0) {
00158
00159 *p = 0;
00160 for(p = p+1; *p && (*p == ' ' || *p == '\t'); p++);
00161 if (*p)
00162 desc = p;
00163 }
00164 if ((p = strchr(name, '.')) != 0) {
00165
00166 grp = name;
00167 *p = 0;
00168 name = p+1;
00169 }
00170 ret = counter_register(&h, grp, name, 0, 0, 0, desc, 0);
00171 if (ret < 0) {
00172 if (ret == -2) {
00173 ERR("counter %s.%s already registered\n", grp, name);
00174 return 0;
00175 }
00176 ERR("failed to register counter %s.%s\n", grp, name);
00177 goto error;
00178 }
00179 return 0;
00180 error:
00181 return -1;
00182 }
00183
00184
00185
00186 static int cnt_fixup1(void** param, int param_no)
00187 {
00188 char* name;
00189 char* grp;
00190 char* p;
00191 counter_handle_t h;
00192
00193 name = (char*)*param;
00194 grp = cnt_script_grp;
00195 if ((p = strchr(name, '.')) != 0) {
00196
00197 grp = name;
00198 name = p+1;
00199 *p = 0;
00200 }
00201 if (counter_lookup(&h, grp, name) < 0) {
00202 ERR("counter %s.%s does not exist (forgot to define it?)\n",
00203 grp, name);
00204 return -1;
00205 }
00206 *param = (void*)(long)h.id;
00207 return 0;
00208 }
00209
00210
00211
00212 static int cnt_int_fixup(void** param, int param_no)
00213 {
00214 char* name;
00215 char* grp;
00216 char* p;
00217 counter_handle_t h;
00218
00219 if (param_no == 1) {
00220 name = (char*)*param;
00221 grp = cnt_script_grp;
00222 if ((p = strchr(name, '.')) != 0) {
00223
00224 grp = name;
00225 name = p+1;
00226 *p = 0;
00227 }
00228 if (counter_lookup(&h, grp, name) < 0) {
00229 ERR("counter %s.%s does not exist (forgot to define it?)\n",
00230 grp, name);
00231 return -1;
00232 }
00233 *param = (void*)(long)h.id;
00234 } else
00235 return fixup_var_int_2(param, param_no);
00236 return 0;
00237 }
00238
00239
00240
00241 static int cnt_inc_f(struct sip_msg* msg, char* handle, char* bar)
00242 {
00243 counter_handle_t h;
00244
00245 h.id = (long)(void*)handle;
00246 counter_inc(h);
00247 return 1;
00248 }
00249
00250
00251
00252 static int cnt_add_f(struct sip_msg* msg, char* handle, char* val)
00253 {
00254 counter_handle_t h;
00255 int v;
00256
00257 h.id = (long)(void*)handle;
00258 if (unlikely(get_int_fparam(&v, msg, (fparam_t*)val) < 0)) {
00259 ERR("non integer parameter\n");
00260 return -1;
00261 }
00262 counter_add(h, v);
00263 return 1;
00264 }
00265
00266
00267
00268 static int cnt_reset_f(struct sip_msg* msg, char* handle, char* bar)
00269 {
00270 counter_handle_t h;
00271
00272 h.id = (long)(void*)handle;
00273 counter_reset(h);
00274 return 1;
00275 }
00276
00277
00278
00279 static void cnt_grp_get_all(rpc_t* rpc, void* c, char* group);
00280
00281
00282
00283 static void cnt_get_rpc(rpc_t* rpc, void* c)
00284 {
00285 char* group;
00286 char* name;
00287 counter_val_t v;
00288 counter_handle_t h;
00289
00290 if (rpc->scan(c, "s", &group) < 1)
00291 return;
00292 if (rpc->scan(c, "*s", &name) < 1)
00293 return cnt_grp_get_all(rpc, c, group);
00294
00295 if (counter_lookup(&h, group, name) < 0) {
00296 rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
00297 return;
00298 }
00299 v = counter_get_val(h);
00300 rpc->add(c, "d", (int)v);
00301 return;
00302 }
00303
00304
00305
00306 static void cnt_get_raw_rpc(rpc_t* rpc, void* c)
00307 {
00308 char* group;
00309 char* name;
00310 counter_val_t v;
00311 counter_handle_t h;
00312
00313 if (rpc->scan(c, "ss", &group, &name) < 2) {
00314
00315 return;
00316 }
00317 if (counter_lookup(&h, group, name) < 0) {
00318 rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
00319 return;
00320 }
00321 v = counter_get_raw_val(h);
00322 rpc->add(c, "d", (int)v);
00323 return;
00324 }
00325
00326
00327
00328 static void cnt_reset_rpc(rpc_t* rpc, void* c)
00329 {
00330 char* group;
00331 char* name;
00332 counter_handle_t h;
00333
00334 if (rpc->scan(c, "ss", &group, &name) < 2) {
00335
00336 return;
00337 }
00338 if (counter_lookup(&h, group, name) < 0) {
00339 rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
00340 return;
00341 }
00342 counter_reset(h);
00343 return;
00344 }
00345
00346
00347
00348 struct rpc_list_params {
00349 rpc_t* rpc;
00350 void* ctx;
00351 };
00352
00353
00354
00355 static void rpc_print_name(void* param, str* n)
00356 {
00357 struct rpc_list_params* p;
00358 rpc_t* rpc;
00359 void* ctx;
00360
00361 p = param;
00362 rpc = p->rpc;
00363 ctx = p->ctx;
00364 rpc->add(ctx, "S", n);
00365 }
00366
00367
00368
00369 static void rpc_print_name_val(void* param, str* g, str* n,
00370 counter_handle_t h)
00371 {
00372 struct rpc_list_params* p;
00373 rpc_t* rpc;
00374 void* s;
00375
00376 p = param;
00377 rpc = p->rpc;
00378 s = p->ctx;
00379 rpc->struct_add(s, "d", n->s, (int)counter_get_val(h));
00380 }
00381
00382
00383
00384 static void cnt_grps_list_rpc(rpc_t* rpc, void* c)
00385 {
00386 struct rpc_list_params packed_params;
00387
00388 packed_params.rpc = rpc;
00389 packed_params.ctx = c;
00390 counter_iterate_grp_names(rpc_print_name, &packed_params);
00391 }
00392
00393
00394
00395 static void cnt_var_list_rpc(rpc_t* rpc, void* c)
00396 {
00397 char* group;
00398 struct rpc_list_params packed_params;
00399
00400 if (rpc->scan(c, "s", &group) < 1) {
00401
00402 return;
00403 }
00404 packed_params.rpc = rpc;
00405 packed_params.ctx = c;
00406 counter_iterate_grp_var_names(group, rpc_print_name, &packed_params);
00407 }
00408
00409
00410
00411 static void cnt_grp_get_all(rpc_t* rpc, void* c, char* group)
00412 {
00413 void* s;
00414 struct rpc_list_params packed_params;
00415
00416 if (rpc->add(c, "{", &s) < 0) return;
00417 packed_params.rpc = rpc;
00418 packed_params.ctx = s;
00419 counter_iterate_grp_vars(group, rpc_print_name_val, &packed_params);
00420 }
00421
00422
00423
00424 static void cnt_grp_get_all_rpc(rpc_t* rpc, void* c)
00425 {
00426 char* group;
00427
00428 if (rpc->scan(c, "s", &group) < 1) {
00429
00430 return;
00431 }
00432 return cnt_grp_get_all(rpc, c, group);
00433 }
00434
00435
00436
00437 static void cnt_help_rpc(rpc_t* rpc, void* ctx)
00438 {
00439 char* group;
00440 char* name;
00441 char* desc;
00442 counter_handle_t h;
00443
00444 if (rpc->scan(ctx, "ss", &group, &name) < 2) {
00445
00446 return;
00447 }
00448 if (counter_lookup(&h, group, name) < 0) {
00449 rpc->fault(ctx, 400, "non-existent counter %s.%s\n", group, name);
00450 return;
00451 }
00452 desc = counter_get_doc(h);
00453 if (desc)
00454 rpc->add(ctx, "s", desc);
00455 else
00456 rpc->fault(ctx, 400, "no description for counter %s.%s\n",
00457 group, name);
00458 return;
00459 }
00460
00461