#!/usr/bin/env ruby require File.expand_path('../../lib/riemann/tools', __FILE__) class Riemann::Tools::FreeSWITCH include Riemann::Tools opt :calls_warning, "Calls warning threshold", :default => 100 opt :calls_critical, "Calls critical threshold", :default => 300 opt :pid_file, "FreeSWITCH daemon pidfile", :type => String, :default => "/var/run/freeswitch/freeswitch.pid" def initialize @limits = { :calls => {:critical => opts[:calls_critical], :warning => opts[:calls_warning]} } end def dead_proc?(pid) begin Process.getpgid(pid) false rescue Errno::ESRCH true end end def alert(service, state, metric, description) report( :service => service.to_s, :state => state.to_s, :metric => metric.to_f, :description => description ) end def exec_with_timeout(cmd, timeout) pid = Process.spawn(cmd, {[:err,:out] => :close, :pgroup => true}) begin Timeout.timeout(timeout) do Process.waitpid(pid, 0) $?.exitstatus == 0 end rescue Timeout::Error Process.kill(15, -Process.getpgid(pid)) puts "Killed pid: #{pid}" false end end def tick # Determine how many current calls I have according to FreeSWITCH fs_calls = %x[fs_cli -x "show calls count"| grep -Po '^\\d+'].to_i # Determine how many current channels I have according to FreeSWITCH fs_channels = %x[fs_cli -x "show channels count"| grep -Po '^\\d+'].to_i # Determine how many conferences I have according to FreeSWITCH fs_conferences = %x[fs_cli -x "conference list"| grep -Pco '^Conference'].to_i # Try to read pidfile. If it fails use Devil's dummy PID begin fs_pid = File.read(opts[:pid_file]).to_i rescue puts "Couldn't read pidfile: #{opts[:pid_file]}" fs_pid = -666 end fs_threads = fs_pid > 0 ? %x[ps huH p #{fs_pid} | wc -l].to_i : 0 # Submit calls to riemann if fs_calls > @limits[:calls][:critical] alert "FreeSWITCH current calls", :critical, fs_calls, "Number of calls are #{fs_calls}" elsif fs_calls > @limits[:calls][:warning] alert "FreeSWITCH current calls", :warning, fs_calls, "Number of calls are #{fs_calls}" else alert "FreeSWITCH current calls", :ok, fs_calls, "Number of calls are #{fs_calls}" end # Submit channels to riemann if fs_channels > @limits[:calls][:critical] alert "FreeSWITCH current channels", :critical, fs_channels, "Number of channels are #{fs_channels}" elsif fs_channels > @limits[:calls][:warning] alert "FreeSWITCH current channels", :warning, fs_channels, "Number of channels are #{fs_channels}" else alert "FreeSWITCH current channels", :ok, fs_channels, "Number of channels are #{fs_channels}" end # Submit conferences to riemann if fs_conferences > @limits[:calls][:critical] alert "FreeSWITCH current conferences", :critical, fs_conferences, "Number of conferences are #{fs_conferences}" elsif fs_conferences > @limits[:calls][:warning] alert "FreeSWITCH current conferences", :warning, fs_conferences, "Number of conferences are #{fs_conferences}" else alert "FreeSWITCH current conferences", :ok, fs_conferences, "Number of conferences are #{fs_conferences}" end # Submit threads to riemann if fs_threads alert "FreeSWITCH current threads", :ok, fs_threads, "Number of threads are #{fs_threads}" end # Submit status to riemann if dead_proc?(fs_pid) alert "FreeSWITCH status", :critical, -1, "FreeSWITCH service status: not running" else alert "FreeSWITCH status", :ok, nil, "FreeSWITCH service status: running" end # Submit CLI status to riemann using timeout in case it's unresponsive if exec_with_timeout("fs_cli -x status", 2) alert "FreeSWITCH CLI status", :ok, nil, "FreeSWITCH CLI status: responsive" else alert "FreeSWITCH CLI status", :critical, -1, "FreeSWITCH CLI status: not responding" end end end Riemann::Tools::FreeSWITCH.run