Pārlūkot izejas kodu

kcore stats: rewrote in terms of the counters api

Most of the original kamailio statistics functions and data types are now
wrappers over sr counters.
The only important usage difference is that sr counters are
uniquely identified by group and name (one can have counters with
the same name if they are in different groups), while kamailio
stats vars had unique names. This means that when using the
kamailio get_stat(name) the first counter matching that name will
be returned (in the future this kind of usage should be
obsoleted).

Removed functions (not needed):
 get_stats_collector()
 destroy_stats_collector()
Removed data types:
 stats_collector
 module_stats
New functions:
 stats_support() - partially replaces get_stats_collector().
 get_stat_name() - returns the name of a stat_var.
 get_stat_module() - returns the module of a stat_var.
Andrei Pelinescu-Onciul 15 gadi atpakaļ
vecāks
revīzija
efb487e2a4
4 mainītis faili ar 279 papildinājumiem un 352 dzēšanām
  1. 105 0
      lib/kcore/kstats_wrapper.c
  2. 171 0
      lib/kcore/kstats_wrapper.h
  3. 1 250
      lib/kcore/statistics.c
  4. 2 102
      lib/kcore/statistics.h

+ 105 - 0
lib/kcore/kstats_wrapper.c

@@ -0,0 +1,105 @@
+/* 
+ * $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.
+ */
+/** k compatible statistics implemented in terms of sr counters.
+ * @file kstats_wrapper.h
+ * @ingroup: libkcore
+ */
+/*
+ * History:
+ * --------
+ *  2010-08-08  initial version (andrei)
+*/
+
+#include "kstats_wrapper.h"
+
+#ifdef STATISTICS
+
+
+/** internal wrapper for kamailio type stat callbacks.
+ * sr counter callbacks are different from the kamailio type stat callbacks.
+ * This function is meant as a sr counter callback that will call
+ * k stat callback passed as parameter.
+ * @param h - not used.
+ * @param param - k stat callback function pointer (stat_function).
+ * @return result of calling the passed k stat_function.
+ */
+static counter_val_t cnt_cbk_wrapper(counter_handle_t h, void* param)
+{
+	stat_function k_stat_f;
+	
+	k_stat_f = param;
+	return k_stat_f();
+}
+
+
+
+int register_stat( char *module, char *name, stat_var **pvar, int flags)
+{
+	int cnt_flags;
+	counter_handle_t h;
+	int ret;
+	
+	if (module == 0 || name == 0 || pvar == 0) {
+		BUG("invalid parameters (%p, %p, %p)\n", module, name, pvar);
+		return -1;
+	}
+	/* translate kamailio stat flags into sr counter flags */
+	cnt_flags = (flags & STAT_NO_RESET) ? CNT_F_NO_RESET : 0;
+	if (flags & STAT_IS_FUNC)
+		ret = counter_register(&h, module, name, cnt_flags,
+					cnt_cbk_wrapper,(stat_function)pvar , 0);
+	else
+		ret = counter_register(&h, module, name, cnt_flags, 0, 0, 0);
+	if (ret < 0) {
+		if (ret == -2)
+			ERR("counter %s.%s already registered\n", module, name);
+		goto error;
+	}
+	if (!(flags & STAT_IS_FUNC))
+		*pvar = (void*)(unsigned long)h.id;
+	return 0;
+error:
+	if (!(flags & STAT_IS_FUNC))
+		*pvar = 0;
+	return -1;
+}
+
+
+
+int register_module_stats(char *module, stat_export_t *stats)
+{
+	if (module == 0 || *module == 0) {
+		BUG("null or empty module name\n");
+		goto error;
+	}
+	if (stats == 0 || stats[0].name == 0)
+		/* empty stats */
+		return 0;
+	for (; stats->name; stats++)
+		if (register_stat(module, stats->name, stats->stat_pointer,
+							stats->flags) < 0 ){
+			ERR("failed to add statistic %s.%s\n", module, stats->name);
+			goto error;
+		}
+	return 0;
+error:
+	return -1;
+}
+
+#endif /* STATISTICS */
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */

+ 171 - 0
lib/kcore/kstats_wrapper.h

@@ -0,0 +1,171 @@
+/* 
+ * $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.
+ */
+/** k compatible statistics implemented in terms of sr counters.
+ * New functions:
+ *  stats_support() - partially replaces get_stats_collector().
+ *    Returns 1 if statistics support is compiled, 0 otherwise.
+ *  get_stat_name() - returns the name of a stat_var.
+ *  get_stat_module() - returns the module of a stat_var.
+ * Removed functions:
+ *  get_stats_collector()
+ *  destroy_stats_collector()
+ * Removed variables/structures:
+ *   stats_collector
+ *   module_stats
+ *
+ * @file kstats_wrapper.h
+ * @ingroup: libkcore
+ */
+/*
+ * History:
+ * --------
+ *  2010-08-08  initial version (andrei)
+*/
+
+#ifndef __kstats_wrapper_h
+#define __kstats_wrapper_h
+
+#include "../../counters.h"
+
+/* k stat flags */
+#define STAT_NO_RESET	1  /* used in dialog(k), nat_traversal(k),
+							  registrar(k), statistics(k), usrloc(k) */
+/* #define STAT_NO_SYN	2  -- not used */
+#define STAT_SHM_NAME	4 /* used only from usrloc(k) */
+#define STAT_IS_FUNC	8
+
+/* types */
+
+typedef counter_val_t    stat_val;
+/* stat_var is always used as a pointer in k, we missuse
+   stat_var* for holding out counter id */
+typedef void stat_var;
+/* get val callback
+ * TODO: change it to counter_cbk_f compatible callback?
+ */
+typedef counter_val_t (*stat_function)(void);
+
+/* statistic module interface */
+struct stat_export_s {
+	char* name;
+	int flags;
+	stat_var** stat_pointer; /* pointer to the memory location
+								(where a counter handle will be stored)
+								Note: it's a double pointer because of
+								the original k version which needed it
+								allocated in shm. This version
+								will store the counter id at *stat_pointer.
+							  */
+};
+
+typedef struct stat_export_s stat_export_t;
+
+#ifdef STATISTICS
+
+/* statistics support check */
+#define stats_support() 1
+
+int register_stat( char *module, char *name, stat_var **pvar, int flags);
+int register_module_stats(char *module, stat_export_t *stats);
+
+inline static stat_var* get_stat(str *name)
+{
+	counter_handle_t h;
+	str grp;
+	
+	grp.s = 0;
+	grp.len = 0;
+	if (counter_lookup_str(&h, &grp, name) < 0)
+		return 0;
+	return (void*)(unsigned long)h.id;
+}
+
+
+
+inline static unsigned int get_stat_val(stat_var *v)
+{
+	counter_handle_t h;
+	h.id = (unsigned short)(unsigned long)v;
+	return counter_get_val(h);
+}
+
+
+
+inline static char* get_stat_name(stat_var *v)
+{
+	counter_handle_t h;
+	h.id = (unsigned short)(unsigned long)v;
+	return counter_get_name(h);
+}
+
+
+
+inline static char* get_stat_module(stat_var *v)
+{
+	counter_handle_t h;
+	h.id = (unsigned short)(unsigned long)v;
+	return counter_get_group(h);
+}
+
+
+
+inline static void update_stat(stat_var* v, int n)
+{
+	counter_handle_t h;
+	h.id = (unsigned short)(unsigned long)v;
+	counter_add(h, n);
+}
+
+
+
+inline static void reset_stat(stat_var* v)
+{
+	counter_handle_t h;
+	h.id = (unsigned short)(unsigned long)v;
+	counter_reset(h);
+}
+
+
+#define if_update_stat(c, var, n) \
+	do{ \
+		if ((c)) update_stat((var), (n)); \
+	}while(0)
+
+#define if_reset_stat(c, var) \
+	do{ \
+		if ((c)) reset_stat((var)); \
+	}while(0)
+
+#else /* STATISTICS */
+
+/* statistics support check */
+#define stats_support() 0
+#define register_module_stats(mod, stats) 0
+#define register_stat(mod, name, var, flags) 0
+#define get_stat(name)  0
+#define get_stat_val(var) 0
+#define update_stat(v, n)
+#define reset_stat(v)
+#define if_update_stat(c, v, n)
+#define if_reset_stat(c, v)
+
+#endif /* STATISTICS */
+
+#endif /*__kstats_wrapper_h*/
+
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */

+ 1 - 250
lib/kcore/statistics.c

@@ -25,6 +25,7 @@
  *  2006-01-16  first version (bogdan)
  *  2006-11-28  added get_stat_var_from_num_code() (Jeffrey Magder -
  *              SOMA Networks)
+ *  2010-08-08  removed all the parts emulated by kstats_wrapper.[ch] (andrei)
  */
 
 /*!
@@ -37,26 +38,14 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "../../mem/shm_mem.h"
 #include "../../ut.h"
 #include "../../dprint.h"
-#include "../../locking.h"
 #include "../../socket_info.h"
 #include "km_ut.h"
-#include "hash_func.h"
 #include "statistics.h"
 
 #ifdef STATISTICS
 
-static stats_collector *collector = NULL;
-
-
-#define stat_hash(_s) core_hash( _s, 0, STATS_HASH_SIZE)
-
-stats_collector* get_stats_collector(void)
-{
-	return collector;
-}
 
 /*! \brief
  * Returns the statistic associated with 'numerical_code' and 'out_codes'.
@@ -89,244 +78,6 @@ stat_var *get_stat_var_from_num_code(unsigned int numerical_code, int out_codes)
 }
 
 
-
-int init_stats_collector(void)
-{
-	if(collector != NULL) /* already initialized */
-		return 0;
-	/* init the collector */
-	collector = (stats_collector*)shm_malloc(sizeof(stats_collector));
-	if (collector==0) {
-		LM_ERR("no more shm mem\n");
-		goto error;
-	}
-	memset( collector, 0 , sizeof(stats_collector));
-
-	LM_DBG("statistics manager successfully initialized\n");
-
-	return 0;
-error:
-	return -1;
-}
-
-
-void destroy_stats_collector(void)
-{
-	stat_var *stat;
-	stat_var *tmp_stat;
-	int i;
-
-	if (collector) {
-		/* destroy hash table */
-		for( i=0 ; i<STATS_HASH_SIZE ; i++ ) {
-			for( stat=collector->hstats[i] ; stat ; ) {
-				tmp_stat = stat;
-				stat = stat->hnext;
-				if ((tmp_stat->flags&STAT_IS_FUNC)==0 && tmp_stat->u.val)
-					shm_free(tmp_stat->u.val);
-				if ( (tmp_stat->flags&STAT_SHM_NAME) && tmp_stat->name.s)
-					shm_free(tmp_stat->name.s);
-				shm_free(tmp_stat);
-			}
-		}
-
-		/* destroy sts_module array */
-		if (collector->amodules)
-			shm_free(collector->amodules);
-
-		/* destroy the collector */
-		shm_free(collector);
-		collector = NULL;
-	}
-
-	return;
-}
-
-
-module_stats* get_stat_module(str *module)
-{
-	int i;
-
-	if ( (module==0) || module->s==0 || module->len==0 )
-		return 0;
-
-	for( i=0 ; i<collector->mod_no ; i++ ) {
-		if ( (collector->amodules[i].name.len == module->len) &&
-		(strncasecmp(collector->amodules[i].name.s,module->s,module->len)==0) )
-			return &collector->amodules[i];
-	}
-
-	return 0;
-}
-
-
-static inline module_stats* add_stat_module( char *module)
-{
-	module_stats *amods;
-	module_stats *mods;
-	int len;
-
-	if ( (module==0) || ((len = strlen(module))==0 ) )
-		return 0;
-	if(init_stats_collector()!=0)
-		return 0;
-
-	amods = (module_stats*)shm_realloc( collector->amodules,
-			(collector->mod_no+1)*sizeof(module_stats) );
-	if (amods==0) {
-		LM_ERR("no more shm memory\n");
-		return 0;
-	}
-
-	collector->amodules = amods;
-	collector->mod_no++;
-
-	mods = &amods[collector->mod_no-1];
-	memset( mods, 0, sizeof(module_stats) );
-
-	mods->name.s = module;
-	mods->name.len = len;
-
-	return mods;
-}
-
-
-int register_stat( char *module, char *name, stat_var **pvar, int flags)
-{
-	module_stats* mods;
-	stat_var *stat;
-	stat_var *it;
-	str smodule;
-	int hash;
-
-	if (module==0 || name==0 || pvar==0) {
-		LM_ERR("invalid parameters module=%p, name=%p, pvar=%p \n", 
-				module, name, pvar);
-		goto error;
-	}
-
-	if(init_stats_collector()!=0)
-		return -1;
-
-	stat = (stat_var*)shm_malloc(sizeof(stat_var));
-	if (stat==0) {
-		LM_ERR("no more shm memory\n");
-		goto error;
-	}
-	memset( stat, 0, sizeof(stat_var));
-
-	if ( (flags&STAT_IS_FUNC)==0 ) {
-		stat->u.val = (stat_val*)shm_malloc(sizeof(stat_val));
-		if (stat->u.val==0) {
-			LM_ERR("no more shm memory\n");
-			goto error1;
-		}
-		atomic_set(stat->u.val,0);
-		*pvar = stat;
-	} else {
-		stat->u.f = (stat_function)(pvar);
-	}
-
-	/* is the module already recorded? */
-	smodule.s = module;
-	smodule.len = strlen(module);
-	mods = get_stat_module(&smodule);
-	if (mods==0) {
-		mods = add_stat_module(module);
-		if (mods==0) {
-			LM_ERR("failed to add new module\n");
-			goto error2;
-		}
-	}
-
-	/* fill the stat record */
-	stat->mod_idx = collector->mod_no-1;
-
-	stat->name.s = name;
-	stat->name.len = strlen(name);
-	stat->flags = flags;
-
-
-	/* compute the hash by name */
-	hash = stat_hash( &stat->name );
-
-	/* link it */
-	if (collector->hstats[hash]==0) {
-		collector->hstats[hash] = stat;
-	} else {
-		it = collector->hstats[hash];
-		while(it->hnext)
-			it = it->hnext;
-		it->hnext = stat;
-	}
-	collector->stats_no++;
-
-	/* add the statistic also to the module statistic list */
-	if (mods->tail) {
-		mods->tail->lnext = stat;
-	} else {
-		mods->head = stat;
-	}
-	mods->tail = stat;
-	mods->no++;
-
-	return 0;
-error2:
-	if ( (flags&STAT_IS_FUNC)==0 ) {
-		shm_free(*pvar);
-		*pvar = 0;
-	}
-error1:
-	shm_free(stat);
-error:
-	*pvar = 0;
-	return -1;
-}
-
-
-
-int register_module_stats(char *module, stat_export_t *stats)
-{
-	int ret;
-
-	if (module==0 || module[0]==0 || !stats || !stats[0].name)
-		return 0;
-
-	for( ; stats->name ; stats++) {
-		ret = register_stat( module, stats->name, stats->stat_pointer,
-			stats->flags);
-		if (ret!=0) {
-			LM_CRIT("failed to add statistic\n");
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-
-
-stat_var* get_stat( str *name )
-{
-	stat_var *stat;
-	int hash;
-
-	if (name==0 || name->s==0 || name->len==0)
-		return 0;
-
-	/* compute the hash by name */
-	hash = stat_hash( name );
-
-	/* and look for it */
-	for( stat=collector->hstats[hash] ; stat ; stat=stat->hnext ) {
-		if ( (stat->name.len==name->len) &&
-		(strncasecmp( stat->name.s, name->s, name->len)==0) )
-			return stat;
-	}
-
-	return 0;
-}
-
 #endif /*STATISTICS*/
 
 #define MAX_PROC_BUFFER 256

+ 2 - 102
lib/kcore/statistics.h

@@ -24,6 +24,7 @@
  *  2006-01-16  first version (bogdan)
  *  2006-11-28  added get_stat_var_from_num_code() (Jeffrey Magder -
  *              SOMA Networks)
+ *  2010-08-08  removed all the parts emulated by kstats_wrapper.[ch] (andrei)
  */
 
 /*!
@@ -35,73 +36,13 @@
 #ifndef _KSTATISTICS_H_
 #define _KSTATISTICS_H_
 
-#include <string.h>
-#include "../../str.h"
-#include "../../atomic_ops.h"
+#include "kstats_wrapper.h"
 
-#define STATS_HASH_POWER   8
-#define STATS_HASH_SIZE    (1<<(STATS_HASH_POWER))
 
 #define NUM_IP_OCTETS 4
 
-#define STAT_NO_RESET  (1<<0)
-#define STAT_NO_SYNC   (1<<1)
-#define STAT_SHM_NAME  (1<<2)
-#define STAT_IS_FUNC   (1<<3)
-
-typedef atomic_t stat_val;
-
-typedef unsigned long (*stat_function)(void);
-
-struct module_stats_;
-
-typedef struct stat_var_{
-	unsigned int mod_idx;
-	str name;
-	int flags;
-	union{
-		stat_val *val;
-		stat_function f;
-	}u;
-	struct stat_var_ *hnext;
-	struct stat_var_ *lnext;
-} stat_var;
-
-typedef struct module_stats_ {
-	str name;
-	int no;
-	stat_var *head;
-	stat_var *tail;
-} module_stats;
-
-typedef struct stats_collector_ {
-	int stats_no;
-	int mod_no;
-	stat_var* hstats[STATS_HASH_SIZE];
-	module_stats *amodules;
-}stats_collector;
-
-typedef struct stat_export_ {
-	char* name;                /* null terminated statistic name */
-	int flags;                 /* flags */
-	stat_var** stat_pointer;   /* pointer to the variable's mem location *
-	                            * NOTE - it's in shm mem */
-} stat_export_t;
-
 
 #ifdef STATISTICS
-int init_stats_collector(void);
-
-void destroy_stats_collector(void);
-
-int register_stat( char *module, char *name, stat_var **pvar, int flags);
-
-int register_module_stats(char *module, stat_export_t *stats);
-
-stat_var* get_stat( str *name );
-
-unsigned int get_stat_val( stat_var *var );
-
 /*! \brief
  * Returns the statistic associated with 'numerical_code' and 'is_a_reply'.
  * Specifically:
@@ -113,52 +54,11 @@ unsigned int get_stat_val( stat_var *var );
  */
 stat_var *get_stat_var_from_num_code(unsigned int numerical_code, int in_codes);
 
-stats_collector* get_stats_collector(void);
-module_stats* get_stat_module(str *module);
-
 #else
-	#define init_stats_collector()  0
-	#define destroy_stats_collector()
-	#define register_module_stats(_mod,_stats) 0
-	#define register_stat( _mod, _name, _pvar, _flags) 0
-	#define get_stat( _name )  0
-	#define get_stat_val( _var ) 0
 	#define get_stat_var_from_num_code( _n_code, _in_code) NULL
-	#define get_stats_collector() NULL
-	#define get_stat_module(_module) NULL
 #endif
 
 
-#ifdef STATISTICS
-	#define update_stat( _var, _n) \
-		do { \
-			if ( !((_var)->flags&STAT_IS_FUNC) ) {\
-				atomic_add((_var)->u.val, _n);\
-			}\
-		}while(0)
-	#define reset_stat( _var) \
-		do { \
-			if ( ((_var)->flags&(STAT_NO_RESET|STAT_IS_FUNC))==0 ) {\
-				atomic_set( (_var)->u.val, 0);\
-			}\
-		}while(0)
-	#define get_stat_val( _var ) ((unsigned long)\
-		((_var)->flags&STAT_IS_FUNC)?(_var)->u.f():(_var)->u.val->val)
-
-	#define if_update_stat(_c, _var, _n) \
-		do { \
-			if (_c) update_stat( _var, _n); \
-		}while(0)
-	#define if_reset_stat(_c, _var) \
-		do { \
-			if (_c) reset_stat( _var); \
-		}while(0)
-#else
-	#define update_stat( _var, _n)
-	#define reset_stat( _var)
-	#define if_update_stat( _c, _var, _n)
-	#define if_reset_stat( _c, _var)
-#endif /*STATISTICS*/
 
 /*!
  * This function will retrieve a list of all ip addresses and ports that OpenSER