Browse code

counters: new modules for counters manipulations

New module for manipulating counters via the script, or RPCs.

Script functions:
cnt_inc(name)
cnt_add(name, val)
cnt_reset(name)

Before using a counter in the script it must be declared using:
modparam("counters", "script_counter", counter_name)

RPCs:
cnt.get grp name - get counter value
cnt.reset grp name - reset counter
cnt.grps_list - list all the counter groups
cnt.var_list grp - list all the counters names in a group
cnt.grp_get_all grp - list all the counters and their value, in a
group

Andrei Pelinescu-Onciul authored on 08/08/2010 17:25:07
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+# $Id$
1
+#
2
+
3
+include ../../Makefile.defs
4
+auto_gen=
5
+NAME=counters.so
6
+LIBS=
7
+
8
+DEFS+=-DSER_MOD_INTERFACE
9
+
10
+include ../../Makefile.modules
11
+
0 12
new file mode 100644
... ...
@@ -0,0 +1,368 @@
0
+/*$Id$
1
+ *
2
+ * Copyright (C) 2010 iptelorg GmbH
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+/** counters/statistics rpcs and script functions.
17
+ * @file counters.c
18
+ * @ingroup counters
19
+ * Module: counters.
20
+ */
21
+/*
22
+ * History:
23
+ * -------
24
+ *  2010-08-06  created by andrei
25
+ */
26
+
27
+
28
+#include "../../modparam.h"
29
+#include "../../dprint.h"
30
+#include "../../compiler_opt.h"
31
+#include "../../counters.h"
32
+
33
+MODULE_VERSION
34
+
35
+/* default script counter group name */
36
+static char* cnt_script_grp = "script";
37
+
38
+static int add_script_counter(modparam_t type, void* val);
39
+static int cnt_inc_f(struct sip_msg*, char*, char*);
40
+static int cnt_add_f(struct sip_msg*, char*, char*);
41
+static int cnt_reset_f(struct sip_msg*, char*, char*);
42
+static int cnt_fixup1(void** param, int param_no);
43
+static int cnt_int_fixup(void** param, int param_no);
44
+
45
+
46
+
47
+static cmd_export_t cmds[] = {
48
+	{"cnt_inc",    cnt_inc_f,   1,  cnt_fixup1,
49
+			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
50
+	{"cnt_add",    cnt_add_f,   2,  cnt_int_fixup,
51
+			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
52
+	{"cnt_reset", cnt_reset_f,  1, cnt_fixup1,
53
+			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
54
+	{0,0,0,0,0}
55
+};
56
+
57
+static param_export_t params[] = {
58
+	{"script_cnt_grp_name", PARAM_STRING, &cnt_script_grp},
59
+	{"script_counter", PARAM_STRING|PARAM_USE_FUNC, add_script_counter},
60
+	{0,0,0}
61
+};
62
+
63
+
64
+static void cnt_get_rpc(rpc_t* rpc, void* ctx);
65
+static const char* cnt_get_doc[] = {
66
+	"get counter value (takes group and counter name as parameters)", 0
67
+};
68
+
69
+static void cnt_reset_rpc(rpc_t* rpc, void* ctx);
70
+static const char* cnt_reset_doc[] = {
71
+	"reset counter (takes group and counter name as parameters)", 0
72
+};
73
+
74
+static void cnt_get_raw_rpc(rpc_t* rpc, void* ctx);
75
+static const char* cnt_get_raw_doc[] = {
76
+	"get raw counter value (debugging version)", 0
77
+};
78
+
79
+static void cnt_grps_list_rpc(rpc_t* rpc, void* ctx);
80
+static const char* cnt_grps_list_doc[] = {
81
+	"list all the counter group names", 0
82
+};
83
+
84
+static void cnt_var_list_rpc(rpc_t* rpc, void* ctx);
85
+static const char* cnt_var_list_doc[] = {
86
+	"list all the counters names in a specified group", 0
87
+};
88
+
89
+static void cnt_grp_get_all_rpc(rpc_t* rpc, void* ctx);
90
+static const char* cnt_grp_get_all_doc[] = {
91
+	"list all counter names and values in a specified group", 0
92
+};
93
+
94
+
95
+
96
+
97
+static rpc_export_t counters_rpc[] = {
98
+	{"cnt.get", cnt_get_rpc, cnt_get_doc, 0 },
99
+	{"cnt.reset", cnt_reset_rpc, cnt_reset_doc, 0 },
100
+	{"cnt.get_raw", cnt_get_raw_rpc, cnt_get_raw_doc, 0 },
101
+	{"cnt.grps_list", cnt_grps_list_rpc, cnt_grps_list_doc, RET_ARRAY },
102
+	{"cnt.var_list", cnt_var_list_rpc, cnt_var_list_doc, RET_ARRAY },
103
+	{"cnt.grp_get_all", cnt_grp_get_all_rpc, cnt_grp_get_all_doc, 0 },
104
+	{ 0, 0, 0, 0}
105
+};
106
+
107
+
108
+
109
+struct module_exports exports= {
110
+	"counters",
111
+	cmds,
112
+	counters_rpc,        /* RPC methods */
113
+	params,
114
+	0, /* module initialization function */
115
+	0, /* response function */
116
+	0, /* destroy function */
117
+	0, /* on_cancel function */
118
+	0, /* per-child init function */
119
+};
120
+
121
+
122
+static int add_script_counter(modparam_t type, void* val)
123
+{
124
+	char* name;
125
+	counter_handle_t h;
126
+	int ret;
127
+
128
+	if ((type & PARAM_STRING) == 0) {
129
+		BUG("bad parameter type %d\n", type);
130
+		goto error;
131
+	}
132
+	name = (char*) val;
133
+	ret = counter_register(&h, cnt_script_grp, name, 0, 0, 0, 0);
134
+	if (ret < 0) {
135
+		if (ret == -2) {
136
+			ERR("counter %s.%s already registered\n", cnt_script_grp, name);
137
+			return 0;
138
+		}
139
+		ERR("failed to register counter %s.%s\n", cnt_script_grp, name);
140
+		goto error;
141
+	}
142
+	return 0;
143
+error:
144
+	return -1;
145
+}
146
+
147
+
148
+
149
+static int cnt_fixup1(void** param, int param_no)
150
+{
151
+	char* name;
152
+	counter_handle_t h;
153
+
154
+	name = (char*)*param;
155
+	if (counter_lookup(&h, cnt_script_grp, name) < 0) {
156
+		ERR("counter %s.%s does not exist (forgot to define it?)\n",
157
+				cnt_script_grp, name);
158
+		return -1;
159
+	}
160
+	*param = (void*)(long)h.id;
161
+	return 0;
162
+}
163
+
164
+
165
+
166
+static int cnt_int_fixup(void** param, int param_no)
167
+{
168
+	char* name;
169
+	counter_handle_t h;
170
+
171
+	if (param_no == 1) {
172
+		name = (char*)*param;
173
+		if (counter_lookup(&h, cnt_script_grp, name) < 0) {
174
+			ERR("counter %s.%s does not exist (forgot to define it?)\n",
175
+					cnt_script_grp, name);
176
+			return -1;
177
+		}
178
+		*param = (void*)(long)h.id;
179
+	} else
180
+		return fixup_var_int_2(param, param_no);
181
+	return 0;
182
+}
183
+
184
+
185
+
186
+static int cnt_inc_f(struct sip_msg* msg, char* handle, char* bar)
187
+{
188
+	counter_handle_t h;
189
+	
190
+	h.id = (long)(void*)handle;
191
+	counter_inc(h);
192
+	return 1;
193
+}
194
+
195
+
196
+
197
+static int cnt_add_f(struct sip_msg* msg, char* handle, char* val)
198
+{
199
+	counter_handle_t h;
200
+	int v;
201
+	
202
+	h.id = (long)(void*)handle;
203
+	if (unlikely(get_int_fparam(&v, msg, (fparam_t*)val) < 0)) {
204
+		ERR("non integer parameter\n");
205
+		return -1;
206
+	}
207
+	counter_add(h, v);
208
+	return 1;
209
+}
210
+
211
+
212
+
213
+static int cnt_reset_f(struct sip_msg* msg, char* handle, char* bar)
214
+{
215
+	counter_handle_t h;
216
+	
217
+	h.id = (long)(void*)handle;
218
+	counter_reset(h);
219
+	return 1;
220
+}
221
+
222
+
223
+
224
+static void cnt_get_rpc(rpc_t* rpc, void* c)
225
+{
226
+	char* group;
227
+	char* name;
228
+	counter_val_t v;
229
+	counter_handle_t h;
230
+	
231
+	if (rpc->scan(c, "ss", &group, &name) < 2) {
232
+		/* rpc->fault(c, 400, "group and counter name required"); */
233
+		return;
234
+	}
235
+	if (counter_lookup(&h, group, name) < 0) {
236
+		rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
237
+		return;
238
+	}
239
+	v = counter_get_val(h);
240
+	rpc->add(c, "d", (int)v);
241
+	return;
242
+}
243
+
244
+
245
+
246
+static void cnt_get_raw_rpc(rpc_t* rpc, void* c)
247
+{
248
+	char* group;
249
+	char* name;
250
+	counter_val_t v;
251
+	counter_handle_t h;
252
+	
253
+	if (rpc->scan(c, "ss", &group, &name) < 2) {
254
+		/* rpc->fault(c, 400, "group and counter name required"); */
255
+		return;
256
+	}
257
+	if (counter_lookup(&h, group, name) < 0) {
258
+		rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
259
+		return;
260
+	}
261
+	v = counter_get_raw_val(h);
262
+	rpc->add(c, "d", (int)v);
263
+	return;
264
+}
265
+
266
+
267
+
268
+static void cnt_reset_rpc(rpc_t* rpc, void* c)
269
+{
270
+	char* group;
271
+	char* name;
272
+	counter_handle_t h;
273
+	
274
+	if (rpc->scan(c, "ss", &group, &name) < 2) {
275
+		/* rpc->fault(c, 400, "group and counter name required"); */
276
+		return;
277
+	}
278
+	if (counter_lookup(&h, group, name) < 0) {
279
+		rpc->fault(c, 400, "non-existent counter %s.%s\n", group, name);
280
+		return;
281
+	}
282
+	counter_reset(h);
283
+	return;
284
+}
285
+
286
+
287
+
288
+struct rpc_list_params {
289
+	rpc_t* rpc;
290
+	void* ctx;
291
+};
292
+
293
+
294
+/* helper callback for iterating groups or names */
295
+static  void rpc_print_name(void* param, str* n)
296
+{
297
+	struct rpc_list_params* p;
298
+	rpc_t* rpc;
299
+	void* ctx;
300
+
301
+	p = param;
302
+	rpc = p->rpc;
303
+	ctx = p->ctx;
304
+	rpc->add(ctx, "S", n);
305
+}
306
+
307
+
308
+/* helper callback for iterating on variable names & values*/
309
+static  void rpc_print_name_val(void* param, str* g, str* n,
310
+								counter_handle_t h)
311
+{
312
+	struct rpc_list_params* p;
313
+	rpc_t* rpc;
314
+	void* s;
315
+
316
+	p = param;
317
+	rpc = p->rpc;
318
+	s = p->ctx;
319
+	rpc->struct_add(s, "d", n->s, (int)counter_get_val(h));
320
+}
321
+
322
+
323
+
324
+static void cnt_grps_list_rpc(rpc_t* rpc, void* c)
325
+{
326
+	struct rpc_list_params packed_params;
327
+	
328
+	packed_params.rpc = rpc;
329
+	packed_params.ctx = c;
330
+	counter_iterate_grp_names(rpc_print_name, &packed_params);
331
+}
332
+
333
+
334
+
335
+static void cnt_var_list_rpc(rpc_t* rpc, void* c)
336
+{
337
+	char* group;
338
+	struct rpc_list_params packed_params;
339
+	
340
+	if (rpc->scan(c, "s", &group) < 1) {
341
+		/* rpc->fault(c, 400, "group name required"); */
342
+		return;
343
+	}
344
+	packed_params.rpc = rpc;
345
+	packed_params.ctx = c;
346
+	counter_iterate_grp_var_names(group, rpc_print_name, &packed_params);
347
+}
348
+
349
+
350
+
351
+static void cnt_grp_get_all_rpc(rpc_t* rpc, void* c)
352
+{
353
+	void* s;
354
+	char* group;
355
+	struct rpc_list_params packed_params;
356
+	
357
+	if (rpc->scan(c, "s", &group) < 1) {
358
+		/* rpc->fault(c, 400, "group name required"); */
359
+		return;
360
+	}
361
+	if (rpc->add(c, "{", &s) < 0) return;
362
+	packed_params.rpc = rpc;
363
+	packed_params.ctx = s;
364
+	counter_iterate_grp_vars(group, rpc_print_name_val, &packed_params);
365
+}
366
+
367
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */