From 72e4561a2c4160ed73915bb562bf2144f6cc24b4 Mon Sep 17 00:00:00 2001 From: Oussama Hammami Date: Fri, 4 May 2012 13:47:10 +0200 Subject: [PATCH 1/2] Munin Kamailio Plugin --- plugins/kamailio/kamailio_memory | 121 +++++++++++ plugins/kamailio/kamailio_mysql_shared_memory | 194 +++++++++++++++++ plugins/kamailio/kamailio_transactions_users | 195 ++++++++++++++++++ 3 files changed, 510 insertions(+) create mode 100755 plugins/kamailio/kamailio_memory create mode 100755 plugins/kamailio/kamailio_mysql_shared_memory create mode 100755 plugins/kamailio/kamailio_transactions_users diff --git a/plugins/kamailio/kamailio_memory b/plugins/kamailio/kamailio_memory new file mode 100755 index 00000000..16767d43 --- /dev/null +++ b/plugins/kamailio/kamailio_memory @@ -0,0 +1,121 @@ +#!/usr/bin/perl +# -*- perl -*- + +=head1 NAME + +Munin plugin to monitor the usage of memory on Voxtrot Sip Server (Kamailio + Freeswitch + RTPproxy). + +=head1 CONFIGURATION + +No configuration + +=head1 AUTHOR + + Copyright 2012 - Voxtrot + Oussama Hammami + +=head1 LICENSE + +GPLv2 + +=head1 VERSION + + $Id: kamailio_memory 2012-04-19 15:09 $ + +=head1 MAGIC MARKERS + + #%# family=manual + #%# capabilities=autoconf + +=cut + +use strict; + +my %WANTED = ( "kamailio" => "ram_total", + "rtpproxy" => "ram_rtpproxy", + "freeswitch" => "ram_freeswitch", + ); + +my %VALUE = ( "ram_total" => 0, + "ram_rtpproxy" => 0, + "ram_freeswitch" => 0, + ); + +my $arg = shift(); + +if ($arg eq 'config') { + print_config(); + exit(); +} elsif ($arg eq 'autoconf') { + unless (test_service() ) { + print "yes\n"; + } else { + print "no\n"; + } + exit 0; +} + +for my $key (keys %WANTED) { + $VALUE{$WANTED{$key}}=get_memory($key); + } + +$VALUE{"ram_total"}+=$VALUE{"ram_rtpproxy"}+$VALUE{"ram_freeswitch"}; + +for my $key (keys %VALUE) { + print ("$key.value $VALUE{$key}\n"); +} + +sub print_config { + print ("graph_title Voxtrot SIP Server Memory\n"); + # Arguments to "rrdtool graph". In this case, tell it that the + # lower limit of the graph is '0', and that 1k=1000 (not 1024). + print("graph_args --base 1024 --lower-limit 0\n"); + print("graph_vlabel MB\n"); + print("graph_scale no\n"); + print("graph_category kamailio\n"); + print("graph_info The graph describes the usage of memory in Voxtrot Sip Server.\n"); + print("ram_total.label total (kam+fs+rtp)\n"); + print("ram_freeswitch.label freeswitch\n"); + print("ram_rtpproxy.label rtpproxy\n"); + print("ram_total.info Average total memory used by kamailio, freeswitch and rtpproxy for the five minutes.\n"); + print("ram_freeswitch.info Average used memory by freeswitch for the five minutes.\n"); + print("ram_rtpproxy.info Average real used memory by rtpproxy for the five minutes.\n"); + print("graph_order ram_total ram_freeswitch ram_rtpproxy\n"); + print("ram_total.type GAUGE\n"); + print("ram_freeswitch.type GAUGE\n"); + print("ram_rtpproxy.type GAUGE\n"); + print("ram_total.draw AREA\n"); + print("ram_freeswitch.draw AREA\n"); + print("ram_rtpproxy.draw LINE1\n"); + print("ram_total.colour 6699FF\n"); + print("ram_freeswitch.colour FF6633\n"); + print("ram_rtpproxy.colour 993399\n"); + # Ensure min values (useful when using 'DERIVE' as 'type'). + print("ram_total.min 0\n"); + print("ram_freeswitch.min 0\n"); + print("ram_rtpproxy.min 0\n"); + # Divide the got value by 1048576 to get MB. + print("ram_total.cdef ram_total,1048576,/\n"); + print("ram_freeswitch.cdef ram_freeswitch,1048576,/\n"); + print("ram_rtpproxy.cdef ram_rtpproxy,1048576,/\n"); +} + + +sub test_service { + print "yes\n"; + exit 0; +} + +######################### +# function Get Memory + +sub get_memory { + my $proc=shift; + my $i = 0; + my @cmd = `ps auwx | grep $proc | grep -v grep | grep -v kamailio_memory`; + foreach (@cmd) { + my @return = split(/ +/, $_); + $i += @return[5]*1024; + } + return $i; +} diff --git a/plugins/kamailio/kamailio_mysql_shared_memory b/plugins/kamailio/kamailio_mysql_shared_memory new file mode 100755 index 00000000..9e399578 --- /dev/null +++ b/plugins/kamailio/kamailio_mysql_shared_memory @@ -0,0 +1,194 @@ +#!/usr/bin/perl +# -*- perl -*- + +=head1 NAME + +Munin plugin to monitor the usage of shared memory in Kamailio using 'statistics' table. + +=head1 APPLICABLE SYSTEMS + +It requires MySQL 'statistics' table created in Kamailio database. +http://siremis.asipto.com/install-charts-panel/ + +=head1 CONFIGURATION + +[kamailio*] + user root + group root + env.mysql + env.mysqlauth -u -p + env.kamailiodb + +It is most usual that root must run the mysql command. + +=head2 Proxy config + +use rtimer module to run periodically a route. In that route you insert the values in database. + +SIP Proxy configuration file: + + loadmodule "rtimer.so" + loadmodule "sqlops.so" + loadmodule "cfgutils.so" + ... + modparam("rtimer", "timer", "name=tst;interval=300;mode=1;") + modparam("rtimer", "exec", "timer=tst;route=8") + modparam("sqlops","sqlcon","ca=>mysql://openser:openserrw@localhost/openser") + ... + route[8] { + sql_query("ca", + "insert into statistics (time_stamp,random,shm_used_size,shm_real_used_size, + shm_max_used_size,shm_free_used_size,ul_users,ul_contacts) values ($Ts, + $RANDOM,$stat(used_size),$stat(real_used_size),$stat(max_used_size), + $stat(free_size),$stat(location-users),$stat(location-contacts))","ra"); + } + +Note: second parameter of sql_query(...) is a single line. Next version, based on SIP-Router.org project will support string parameters broken in multiple lines. + +=head2 Database + +You have to create a new table in Kamailio (OpenSER) database: + +CREATE TABLE `statistics` ( + `id` int(10) unsigned NOT NULL auto_increment, + `time_stamp` int(10) unsigned NOT NULL default '0', + `random` int(10) unsigned NOT NULL default '0', + `shm_used_size` int(10) unsigned NOT NULL default '0', + `shm_real_used_size` int(10) unsigned NOT NULL default '0', + `shm_max_used_size` int(10) unsigned NOT NULL default '0', + `shm_free_used_size` int(10) unsigned NOT NULL default '0', + `ul_users` int(10) unsigned NOT NULL default '0', + `ul_contacts` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM; + +Now all is ready for Kamailio (OpenSER), you can restart it. + +=head1 BUGS + +None known + +=head1 AUTHOR + + Copyright 2012 - Voxtrot + Oussama Hammami + +=head1 LICENSE + +GPLv2 + +=head1 VERSION + + $Id: kamailio_mysql_shared_memory 2012-04-19 11:24 $ + +=head1 MAGIC MARKERS + + #%# family=manual + #%# capabilities=autoconf + +=cut + +use strict; + +my $MYSQLADMIN = $ENV{mysql} || "mysql"; +my $COMMAND = "$MYSQLADMIN $ENV{mysqlauth} $ENV{kamailiodb} -e 'select * from statistics order by id desc limit 1\\G'"; + +my %WANTED = ( "shm_free_used_size" => "shmem_total", + "shm_real_used_size" => "shmem_real_used", + "shm_used_size" => "shmem_used", + ); + +my %VALUE = ( "shmem_total" => 0, + "shmem_real_used" => 0, + "shmem_used" => 0, + ); + +my $arg = shift(); + +if ($arg eq 'config') { + print_config(); + exit(); +} elsif ($arg eq 'autoconf') { + unless (test_service() ) { + print "yes\n"; + } else { + print "no\n"; + } + exit 0; +} + +open(SERVICE, "$COMMAND |") + or die("Could not execute '$COMMAND': $!"); + +while () { + my ($k, $v) = (m/(\w+).*?(\d+(?:\.\d+)?)/); + next unless ($k); + if (exists $WANTED{$k} ) { + $VALUE{$WANTED{$k}}=$v; + } +} + +close(SERVICE); + +$VALUE{"shmem_total"}+=$VALUE{"shmem_real_used"}; + +for my $key (keys %VALUE) { + print ("$key.value $VALUE{$key}\n"); +} + +sub print_config { + print ("graph_title Kamailio Shared Memory\n"); + # Arguments to "rrdtool graph". In this case, tell it that the + # lower limit of the graph is '0', and that 1k=1000 (not 1024). + print("graph_args --base 1024 --lower-limit 0\n"); + print("graph_vlabel MB\n"); + print("graph_scale no\n"); + print("graph_category kamailio\n"); + print("graph_info The graph describes the usage of shared memory.\n"); + print("shmem_total.label total\n"); + print("shmem_used.label used\n"); + print("shmem_real_used.label real used\n"); + print("shmem_total.info Average total shared memory used for the five minutes.\n"); + print("shmem_used.info Average used shared memory for the five minutes.\n"); + print("shmem_real_used.info Average real used shared memory for the five minutes.\n"); + print("graph_order shmem_total shmem_used shmem_real_used\n"); + print("shmem_total.type GAUGE\n"); + print("shmem_used.type GAUGE\n"); + print("shmem_real_used.type GAUGE\n"); + print("shmem_total.draw AREA\n"); + print("shmem_used.draw AREA\n"); + print("shmem_real_used.draw LINE1\n"); + print("shmem_total.colour 11DB58\n"); + print("shmem_used.colour F7CB03\n"); + print("shmem_real_used.colour 990000\n"); + # Ensure min values (useful when using 'DERIVE' as 'type'). + print("shmem_total.min 0\n"); + print("shmem_used.min 0\n"); + print("shmem_real_used.min 0\n"); + # Divide the got value by 1048576 to get MB. + print("shmem_total.cdef shmem_total,1048576,/\n"); + print("shmem_used.cdef shmem_used,1048576,/\n"); + print("shmem_real_used.cdef shmem_real_used,1048576,/\n"); +} + + +sub test_service { + system ("$MYSQLADMIN --version >/dev/null 2>/dev/null"); + if ($? == 0) + { + system ("$COMMAND >/dev/null 2>/dev/null"); + if ($? == 0) + { + print "yes\n"; + } + else + { + print "no (could not connect to mysql)\n"; + } + } + else + { + print "no (mysqladmin not found)\n"; + } + exit 0; +} diff --git a/plugins/kamailio/kamailio_transactions_users b/plugins/kamailio/kamailio_transactions_users new file mode 100755 index 00000000..4b4e9239 --- /dev/null +++ b/plugins/kamailio/kamailio_transactions_users @@ -0,0 +1,195 @@ +#!/usr/bin/perl +# -*- perl -*- + +=head1 NAME + +Munin plugin to monitor the number of users and transactions in Kamailio using 'statistics' table. + +=head1 APPLICABLE SYSTEMS + +It requires MySQL 'statistics' table created in Kamailio database. +http://siremis.asipto.com/install-charts-panel/ + +=head1 CONFIGURATION + +[kamailio*] + user root + group root + env.mysql + env.mysqlauth -u -p + env.kamailiodb + +It is most usual that root must run the mysql command. + +=head2 Proxy config + +use rtimer module to run periodically a route. In that route you insert the values in database. + +SIP Proxy configuration file: + + loadmodule "rtimer.so" + loadmodule "sqlops.so" + loadmodule "cfgutils.so" + ... + modparam("rtimer", "timer", "name=tst;interval=300;mode=1;") + modparam("rtimer", "exec", "timer=tst;route=8") + modparam("sqlops","sqlcon","ca=>mysql://openser:openserrw@localhost/openser") + ... + route[8] { + sql_query("ca", + "insert into statistics (time_stamp,random,shm_used_size,shm_real_used_size, + shm_max_used_size,shm_free_used_size,ul_users,ul_contacts) values ($Ts, + $RANDOM,$stat(used_size),$stat(real_used_size),$stat(max_used_size), + $stat(free_size),$stat(location-users),$stat(location-contacts))","ra"); + } + +Note: second parameter of sql_query(...) is a single line. Next version, based on SIP-Router.org project will support string parameters broken in multiple lines. + +=head2 Database + +You have to create a new table in Kamailio (OpenSER) database: + +CREATE TABLE `statistics` ( + `id` int(10) unsigned NOT NULL auto_increment, + `time_stamp` int(10) unsigned NOT NULL default '0', + `random` int(10) unsigned NOT NULL default '0', + `shm_used_size` int(10) unsigned NOT NULL default '0', + `shm_real_used_size` int(10) unsigned NOT NULL default '0', + `shm_max_used_size` int(10) unsigned NOT NULL default '0', + `shm_free_used_size` int(10) unsigned NOT NULL default '0', + `ul_users` int(10) unsigned NOT NULL default '0', + `ul_contacts` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM; + +Now all is ready for Kamailio (OpenSER), you can restart it. + +=head1 BUGS + +None known + +=head1 AUTHOR + + Copyright 2012 - Voxtrot + Oussama Hammami + +=head1 LICENSE + +GPLv2 + +=head1 VERSION + + $Id: kamailio_transactions_users 2012-04-19 16:13 $ + +=head1 MAGIC MARKERS + + #%# family=manual + #%# capabilities=autoconf + +=cut + +use strict; + +my $MYSQL = $ENV{mysql} || "mysql"; +my $COMMAND = "$MYSQL $ENV{mysqlauth} $ENV{kamailiodb} -e 'select * from statistics order by id desc limit 1\\G'"; + +my %WANTED = ( "ul_users" => "users", + "ul_contact" => "contacts", + "tm_active" => "transactions", + ); + +my %VALUE = ( "users" => 0, + "contacts" => 0, + "transactions" => 0, + ); + +my $arg = shift(); + +if ($arg eq 'config') { + print_config(); + exit(); +} elsif ($arg eq 'autoconf') { + unless (test_service() ) { + print "yes\n"; + } else { + print "no\n"; + } + exit 0; +} + +open(SERVICE, "$COMMAND |") + or die("Could not execute '$COMMAND': $!"); + +while () { + my ($k, $v) = (m/(\w+).*?(\d+(?:\.\d+)?)/); + next unless ($k); + if (exists $WANTED{$k} ) { + $VALUE{$WANTED{$k}}=$v; + } +} + +close(SERVICE); + +for my $key (keys %VALUE) { + print ("$key.value $VALUE{$key}\n"); +} + +sub print_config { + print ("graph_title Kamailio transactions and location\n"); + # Arguments to "rrdtool graph". In this case, tell it that the + # lower limit of the graph is '0', and that 1k=1000 (not 1024). + print("graph_args --base 1000 --lower-limit 0\n"); + print("graph_vlabel user/transaction\n"); + print("graph_scale no\n"); + print("graph_category kamailio\n"); + print("graph_info The graph describes the number of users/transaction on kamailio.\n"); + + print("users.label users\n"); + print("contacts.label contacts\n"); + print("transactions.label transactions\n"); + + print("users.info Average sip users for the five minutes.\n"); + print("contacts.info Average sip contacts for the five minutes.\n"); + print("transactions.info Average sip transactions for the five minutes.\n"); + + print("graph_order transactions users contacts\n"); + + print("users.type GAUGE\n"); + print("contacts.type GAUGE\n"); + print("transactions.type GAUGE\n"); + + print("users.draw LINE1\n"); + print("contacts.draw LINE1\n"); + print("transactions.draw AREA\n"); + + print("users.colour 00CCC9\n"); + print("contacts.colour 8498A0\n"); + print("transactions.colour E6D300\n"); + + # Ensure min values (useful when using 'DERIVE' as 'type'). + print("users.min 0\n"); + print("contacts.min 0\n"); + print("transactions.min 0\n"); +} + + +sub test_service { + system ("$MYSQL --version >/dev/null 2>/dev/null"); + if ($? == 0) + { + system ("$COMMAND >/dev/null 2>/dev/null"); + if ($? == 0) + { + print "yes\n"; + } + else + { + print "no (could not connect to mysql)\n"; + } + } + else + { + print "no (mysql not found)\n"; + } + exit 0; +} From 92cd5fbc8148f881eac18c9f9d622866bebef718 Mon Sep 17 00:00:00 2001 From: Oussama Hammami Date: Mon, 7 May 2012 10:53:52 +0200 Subject: [PATCH 2/2] Add Readme to kamailio plugin --- plugins/kamailio/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 plugins/kamailio/README.md diff --git a/plugins/kamailio/README.md b/plugins/kamailio/README.md new file mode 100644 index 00000000..8594ace5 --- /dev/null +++ b/plugins/kamailio/README.md @@ -0,0 +1,23 @@ +# Kamailio Munin Plugin +Munin plugins for Kamailio. It monitors: +## Number of transactions, user and contact numbers. +![kamailio_transaction](http://desmond.imageshack.us/Himg820/scaled.php?server=820&filename=kamailiotransactionsuse.png&res=landing "kamailio_transaction") + +## Usage of shared memory (total, used and real used). +![kamailio_shared_memory](http://desmond.imageshack.us/Himg837/scaled.php?server=837&filename=kamailiomysqlsharedmemo.png&res=landing "kamailio_shared_memory") + +## Memory usage by Kamailio, Freeswitch and RTPproxy. +![kamailio_memory](http://desmond.imageshack.us/Himg851/scaled.php?server=851&filename=kamailiomemoryweek.png&res=landing "kamailio_memory") + +it requires MySQL [statistics] (http://siremis.asipto.com/install-charts-panel) table created in Kamailio database. + +## Configuration +edit /etc/munin/plugin-conf.d/munin-node and add: + + [kamailio*] + user root + group root + env.mysql [optional-override-of-mysqladmin-path] + env.mysqlauth -u[User] -p[Password] + env.kamailiodb [kamailio data base] +