Module: sip-router Branch: master Commit: 829b7ff2e663c3ab7cc4ea95d2831eabef57b543 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=829b7ff2...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Mon Dec 20 09:51:05 2010 +0100
kex: print private memory usage per process via rpc
- new rpc command pkg.stats that prints used, free and real_used metrics per process for private memory (pkg) - you can see how much pkg each process is eating and how much is still available - should be useful to track pkg memory leaks and/or trigger alerts when there is no more pkg available
---
modules_k/kex/kex_mod.c | 18 +++- modules_k/kex/pkg_stats.c | 249 +++++++++++++++++++++++++++++++++++++++++++++ modules_k/kex/pkg_stats.h | 39 +++++++ 3 files changed, 305 insertions(+), 1 deletions(-)
diff --git a/modules_k/kex/kex_mod.c b/modules_k/kex/kex_mod.c index d0d7525..c6b55b4 100644 --- a/modules_k/kex/kex_mod.c +++ b/modules_k/kex/kex_mod.c @@ -36,6 +36,7 @@ #include "km_core.h" #include "mi_core.h" #include "core_stats.h" +#include "pkg_stats.h"
MODULE_VERSION @@ -47,6 +48,7 @@ MODULE_VERSION int w_is_myself(struct sip_msg *msg, char *uri, str *s2);
static int mod_init(void); +static int child_init(int rank); static void destroy(void);
static cmd_export_t cmds[]={ @@ -106,7 +108,7 @@ struct module_exports exports= { mod_init, /* module initialization function */ 0, (destroy_function) destroy, - 0 /* per-child init function */ + child_init /* per-child init function */ };
/** @@ -122,10 +124,24 @@ static int mod_init(void) if(register_mi_stats()<0) return -1; #endif + register_pkg_proc_stats(); + pkg_proc_stats_init_rpc(); return 0; }
/** + * + */ +static int child_init(int rank) +{ + LM_DBG("rank is (%d)\n", rank); + if (rank==PROC_INIT) + return pkg_proc_stats_init(); + return pkg_proc_stats_myinit(rank); +} + + +/** * destroy function */ static void destroy(void) diff --git a/modules_k/kex/pkg_stats.c b/modules_k/kex/pkg_stats.c new file mode 100644 index 0000000..7a8d9c3 --- /dev/null +++ b/modules_k/kex/pkg_stats.c @@ -0,0 +1,249 @@ +/* + * $Id$ + * + * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/*! + * \file + * \brief Kamailio pkg statistics + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include "../../dprint.h" +#include "../../ut.h" +#include "../../pt.h" +#include "../../events.h" +#include "../../mem/mem.h" +#include "../../mem/shm_mem.h" +#include "../../rpc.h" +#include "../../rpc_lookup.h" + + +/** + * + */ +typedef struct pkg_proc_stats { + int rank; + unsigned int pid; + unsigned int used; + unsigned int available; + unsigned int real_used; +} pkg_proc_stats_t; + +/** + * + */ +static pkg_proc_stats_t *_pkg_proc_stats_list = NULL; + +/** + * + */ +static int _pkg_proc_stats_no = 0; + +/** + * + */ +int pkg_proc_stats_init(void) +{ + _pkg_proc_stats_no = get_max_procs(); + + if(_pkg_proc_stats_no<=0) + return -1; + if(_pkg_proc_stats_list!=NULL) + return -1; + _pkg_proc_stats_list = (pkg_proc_stats_t*)shm_malloc( + _pkg_proc_stats_no*sizeof(pkg_proc_stats_t)); + if(_pkg_proc_stats_list==NULL) + return -1; + memset(_pkg_proc_stats_list, 0, + _pkg_proc_stats_no*sizeof(pkg_proc_stats_t)); + return 0; +} + +/** + * + */ +int pkg_proc_stats_myinit(int rank) +{ + struct mem_info info; + if(_pkg_proc_stats_list==NULL) + return -1; + if(process_no>=_pkg_proc_stats_no) + return -1; + _pkg_proc_stats_list[process_no].pid = (unsigned int)my_pid(); + _pkg_proc_stats_list[process_no].rank = rank; + + /* init pkg usage values */ + pkg_info(&info); + _pkg_proc_stats_list[process_no].used = info.used; + _pkg_proc_stats_list[process_no].real_used = info.real_used; + return 0; +} + +/** + * + */ +int pkg_proc_stats_destroy(void) +{ + if(_pkg_proc_stats_list==NULL) + return -1; + shm_free(_pkg_proc_stats_list); + _pkg_proc_stats_list = 0; + _pkg_proc_stats_no = 0; + return 0; +} + + +/** + * + */ +static int pkg_proc_update_used(void *data) +{ + if(_pkg_proc_stats_list==NULL) + return -1; + if(process_no>=_pkg_proc_stats_no) + return -1; + _pkg_proc_stats_list[process_no].used = (unsigned int)data; + return 0; +} + +/** + * + */ +static int pkg_proc_update_real_used(void *data) +{ + if(_pkg_proc_stats_list==NULL) + return -1; + if(process_no>=_pkg_proc_stats_no) + return -1; + _pkg_proc_stats_list[process_no].real_used = (unsigned int)data; + _pkg_proc_stats_list[process_no].available = pkg_available(); + return 0; +} + +/** + * + */ +int register_pkg_proc_stats(void) +{ + sr_event_register_cb(SREV_PKG_SET_USED, pkg_proc_update_used); + sr_event_register_cb(SREV_PKG_SET_REAL_USED, pkg_proc_update_real_used); + return 0; +} + +/** + * + */ +static const char* rpc_pkg_stats_doc[2] = { + "Private memory (pkg) statistics per process", + 0 +}; + +/** + * + */ +int pkg_proc_get_pid_index(unsigned int pid) +{ + int i; + for(i=0; i<_pkg_proc_stats_no; i++) + { + if(_pkg_proc_stats_list[i].pid == pid) + return i; + } + return -1; +} + +/** + * + */ +static void rpc_pkg_stats(rpc_t* rpc, void* ctx) +{ + int i; + int limit; + int lpid; + void* th; + + if(_pkg_proc_stats_list==NULL) + { + rpc->fault(ctx, 500, "Not initialized"); + return; + } + i = 0; + limit = _pkg_proc_stats_no; + if (rpc->scan(ctx, "*d", &lpid) == 1) + { + i = pkg_proc_get_pid_index((unsigned int)lpid); + if(i<0) + { + rpc->fault(ctx, 500, "No such pid"); + return; + } + limit = i + 1; + } + + for(; i<limit; i++) + { + /* add entry node */ + if (rpc->add(ctx, "{", &th) < 0) + { + rpc->fault(ctx, 500, "Internal error creating rpc"); + return; + } + if(rpc->struct_add(th, "dddddd", + "entry", i, + "pid", _pkg_proc_stats_list[i].pid, + "rank", _pkg_proc_stats_list[i].rank, + "used", _pkg_proc_stats_list[i].used, + "free", _pkg_proc_stats_list[i].available, + "real_used", _pkg_proc_stats_list[i].real_used + )<0) + { + rpc->fault(ctx, 500, "Internal error creating rpc"); + return; + } + } +} + +/** + * + */ +rpc_export_t kex_pkg_rpc[] = { + {"pkg.stats", rpc_pkg_stats, rpc_pkg_stats_doc, 0}, + {0, 0, 0, 0} +}; + +/** + * + */ +int pkg_proc_stats_init_rpc(void) +{ + if (rpc_register_array(kex_pkg_rpc)!=0) + { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + return 0; +} + diff --git a/modules_k/kex/pkg_stats.h b/modules_k/kex/pkg_stats.h new file mode 100644 index 0000000..4f42758 --- /dev/null +++ b/modules_k/kex/pkg_stats.h @@ -0,0 +1,39 @@ +/* + * $Id$ + * + * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/*! + * \file + * \brief Kamailio pkg statistics + */ + + +#ifndef _PKG_STATS_H_ +#define _PKG_STATS_H_ + +int pkg_proc_stats_init(void); +int pkg_proc_stats_myinit(int rank); +int pkg_proc_stats_destroy(void); +int register_pkg_proc_stats(void); +int pkg_proc_stats_init_rpc(void); + +#endif /*_PKG_STATS_H_*/