#!/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 voip\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; }