Ruby plugins: apply style changes as suggested by "rubocop --fix-layout"

This commit is contained in:
Lars Kruse 2020-08-25 16:52:39 +02:00
parent 26c29daa2b
commit b0b39b018e
30 changed files with 1447 additions and 1384 deletions

View File

@ -1,48 +1,53 @@
#!/usr/bin/env ruby
# netstat_bsd_m revision 1 (Feb 2012)
#
# This plugin shows various statistics from 'netstat -m'
#
# Required privileges: none
#
# OS:
# Supposed: BSD
# Tested: FreeBSD 8.2
#
# Author: Artem Sheremet <dot.doom@gmail.com>
#
=begin
netstat_bsd_m revision 1 (Feb 2012)
This plugin shows various statistics from 'netstat -m'
Required privileges: none
OS:
Supposed: BSD
Tested: FreeBSD 8.2
Author: Artem Sheremet <dot.doom@gmail.com>
#%# family=auto
#%# capabilities=autoconf suggest
=end
# original filename
PLUGIN_NAME = 'netstat_bsd_m_'
class String
def escape
self.gsub /[^\w]/, '_'
end
def escape
self.gsub /[^\w]/, '_'
end
unless method_defined? :start_with?
def start_with?(str)
self[0...str.size] == str
end
end
unless method_defined? :start_with?
def start_with?(str)
self[0...str.size] == str
end
end
end
def netstat_m(filter = nil)
Hash[`netstat -m`.split($/).map { |line|
if line =~ /^([\d\/K]+) (.*) \(([\w\/+]+)\)$/
# 7891K/22385K/30276K bytes allocated to network (current/cache/total)
values, desc, names = $1, $2, $3
[desc, names.split('/').zip(values.split '/')] if filter.nil? or desc.escape == filter
elsif line =~ /^(\d+) (.*)$/
# 12327 requests for I/O initiated by sendfile
value, desc = $1, $2
[desc, [[ :value, value ]]] if filter.nil? or desc.escape == filter
end
}.compact]
Hash[`netstat -m`.split($/).map { |line|
if line =~ /^([\d\/K]+) (.*) \(([\w\/+]+)\)$/
# 7891K/22385K/30276K bytes allocated to network (current/cache/total)
values, desc, names = $1, $2, $3
[desc, names.split('/').zip(values.split '/')] if filter.nil? or desc.escape == filter
elsif line =~ /^(\d+) (.*)$/
# 12327 requests for I/O initiated by sendfile
value, desc = $1, $2
[desc, [[:value, value]]] if filter.nil? or desc.escape == filter
end
}.compact]
end
stat_name = File.basename($0, '.*').escape
@ -50,47 +55,47 @@ stat_name.slice! 0, PLUGIN_NAME.size if stat_name.start_with? PLUGIN_NAME
case ARGV.first
when 'autoconf'
puts `uname -s`.include?('FreeBSD') ? 'yes' : 'no'
puts `uname -s`.include?('FreeBSD') ? 'yes' : 'no'
when 'suggest'
puts netstat_m.keys.map(&:escape).join $/
puts netstat_m.keys.map(&:escape).join $/
when 'config'
data = netstat_m(stat_name)
if data.empty?
warn "no data for <#{stat_name}>. Try running with 'suggest'"
else
desc, values = data.first
stack = values.size > 1
first = true
puts <<CONFIG
graph_title Netstat: #{desc}
graph_category network
graph_vlabel current
graph_order #{values.map { |name, _| name.to_s.escape }.join ' '}
CONFIG
puts values.map { |name, _|
esc_name = name.to_s.escape
"#{esc_name}.draw " + if %w(total max).include? name
'LINE'
elsif stack
if first
first = false
'AREA'
else
'STACK'
end
else
'LINE2'
end + "\n#{esc_name}.label #{name}"
}.join $/
end
data = netstat_m(stat_name)
if data.empty?
warn "no data for <#{stat_name}>. Try running with 'suggest'"
else
desc, values = data.first
stack = values.size > 1
first = true
puts <<~CONFIG
graph_title Netstat: #{desc}
graph_category network
graph_vlabel current
graph_order #{values.map { |name, _| name.to_s.escape }.join ' '}
CONFIG
puts values.map { |name, _|
esc_name = name.to_s.escape
"#{esc_name}.draw " + if %w(total max).include? name
'LINE'
elsif stack
if first
first = false
'AREA'
else
'STACK'
end
else
'LINE2'
end + "\n#{esc_name}.label #{name}"
}.join $/
end
when nil # fetch
data = netstat_m(stat_name)
unless data.empty?
puts data.first.last.map { |name, value|
value = value.to_i * 1024 if value.end_with? 'K'
"#{name.to_s.escape}.value #{value}"
}.join $/
end
data = netstat_m(stat_name)
unless data.empty?
puts data.first.last.map { |name, value|
value = value.to_i * 1024 if value.end_with? 'K'
"#{name.to_s.escape}.value #{value}"
}.join $/
end
else
warn "unrecognized argument <#{ARGV.first}>"
warn "unrecognized argument <#{ARGV.first}>"
end

View File

@ -28,137 +28,138 @@ DEFAULT_CACHE = { :start => 0 }
$debug_mode = ARGV.first == 'debug'
if $debug_mode
log_info = DEFAULT_CACHE
log_info = DEFAULT_CACHE
else
begin
log_info = YAML.load IO.read(CACHE_FILE)
rescue
log_info = DEFAULT_CACHE
end
begin
log_info = YAML.load IO.read(CACHE_FILE)
rescue
log_info = DEFAULT_CACHE
end
if File.size(LOG_FILE) < log_info[:start]
# logrotate?
log_info = DEFAULT_CACHE
end
if File.size(LOG_FILE) < log_info[:start]
# logrotate?
log_info = DEFAULT_CACHE
end
end
if ARGV.first == 'reset'
log_info = { :start => File.size(LOG_FILE)-1 }
puts 'Log reset'
log_info = { :start => File.size(LOG_FILE) - 1 }
puts 'Log reset'
end
new_data = ''
File.open(LOG_FILE, 'rb') do |flog|
flog.seek(log_info[:start])
new_data = flog.read
flog.seek(log_info[:start])
new_data = flog.read
end
KNOWN_LOG_TYPES = [
# each element is an instance of Array. 1st item: error description, others: text to search log for
['EJAB-1482 Crash when waiting for item',
['wait_for_']],
['EJAB-1483 ODBC sup failure (wrong PID?)',
['ejabberd_odbc_sup']],
['EJAB-1483 ODBC sup wrong PID failure echo',
["mod_pubsub_odbc,'-unsubscribe"]],
['DNS failure',
['You should check your DNS configuration']],
['Database unavailable/too slow',
['Database was not available or too slow']],
['State machine terminated: timeout',
['State machine',
'terminating',
'Reason for',
'timeout']],
['The auth module returned an error',
['The authentication module',
'returned an error']],
['MySQL disconnected',
['mysql',
'Received unknown signal, exiting']],
['Connecting to MySQL: failed',
['mysql',
'Failed connecting to']],
['Timeout while running a hook',
['ejabberd_hooks',
'timeout']],
['SQL transaction restarts exceeded',
['SQL transaction restarts exceeded']],
['Unexpected info',
['nexpected info']],
['Other sql_cmd timeout',
['sql_cmd']],
['System limit hit: ports', # check with length(erlang:ports())., set in ejabberdctl config file
['system_limit',
'open_port']],
['Other system limit hit', # processes? check with erlang:system_info(process_count)., erlang:system_info(process_limit)., set in ejabberdctl cfg
['system_limit']],
['Generic server terminating',
['Generic server',
'terminating']],
['Mnesia table shrinked',
['shrinking table']],
['Admin access failed',
['Access of',
'failed with error']],
['MySQL sock timedout',
['mysql_',
': Socket',
'timedout']],
['Configuration error',
['{badrecord,config}']],
['Strange vCard error (vhost)',
['error found when trying to get the vCard']],
['Mnesia is overloaded',
['Mnesia is overloaded']],
['MySQL: init failed recv data',
['mysql_conn: init failed receiving data']],
['TCP Error',
['Failed TCP']]
# each element is an instance of Array. 1st item: error description, others: text to search log for
['EJAB-1482 Crash when waiting for item',
['wait_for_']],
['EJAB-1483 ODBC sup failure (wrong PID?)',
['ejabberd_odbc_sup']],
['EJAB-1483 ODBC sup wrong PID failure echo',
["mod_pubsub_odbc,'-unsubscribe"]],
['DNS failure',
['You should check your DNS configuration']],
['Database unavailable/too slow',
['Database was not available or too slow']],
['State machine terminated: timeout',
['State machine',
'terminating',
'Reason for',
'timeout']],
['The auth module returned an error',
['The authentication module',
'returned an error']],
['MySQL disconnected',
['mysql',
'Received unknown signal, exiting']],
['Connecting to MySQL: failed',
['mysql',
'Failed connecting to']],
['Timeout while running a hook',
['ejabberd_hooks',
'timeout']],
['SQL transaction restarts exceeded',
['SQL transaction restarts exceeded']],
['Unexpected info',
['nexpected info']],
['Other sql_cmd timeout',
['sql_cmd']],
['System limit hit: ports', # check with length(erlang:ports())., set in ejabberdctl config file
['system_limit',
'open_port']],
['Other system limit hit', # processes? check with erlang:system_info(process_count)., erlang:system_info(process_limit)., set in ejabberdctl cfg
['system_limit']],
['Generic server terminating',
['Generic server',
'terminating']],
['Mnesia table shrinked',
['shrinking table']],
['Admin access failed',
['Access of',
'failed with error']],
['MySQL sock timedout',
['mysql_',
': Socket',
'timedout']],
['Configuration error',
['{badrecord,config}']],
['Strange vCard error (vhost)',
['error found when trying to get the vCard']],
['Mnesia is overloaded',
['Mnesia is overloaded']],
['MySQL: init failed recv data',
['mysql_conn: init failed receiving data']],
['TCP Error',
['Failed TCP']]
]
def log_type(text)
KNOWN_LOG_TYPES.find_index { |entry|
entry[1].all? { |substr| text.include? substr }
}
KNOWN_LOG_TYPES.find_index { |entry|
entry[1].all? { |substr| text.include? substr }
}
end
new_data.split("\n=").each { |report|
next if report.empty?
report =~ /\A(\w+) REPORT==== (.*) ===\n(.*)\z/m
type, time, text = $1, $2, $3
next unless type and time and text
next if report.empty?
log_info[type] = (log_info[type] || 0) + 1
if sub_type = log_type(text)
log_info[sub_type] = (log_info[sub_type] || 0) + 1
elsif $debug_mode
warn "Unparsed log entry #{type}: #{text} at #{time}"
end
report =~ /\A(\w+) REPORT==== (.*) ===\n(.*)\z/m
type, time, text = $1, $2, $3
next unless type and time and text
log_info[type] = (log_info[type] || 0) + 1
if sub_type = log_type(text)
log_info[sub_type] = (log_info[sub_type] || 0) + 1
elsif $debug_mode
warn "Unparsed log entry #{type}: #{text} at #{time}"
end
}
log_info[:start] += new_data.size
File.open(CACHE_FILE, 'w') { |f| f.write log_info.to_yaml } unless $debug_mode
if ARGV.first == 'config'
puts <<CONFIG
graph_title Ejabberd Log
graph_vlabel total
graph_category chat
graph_args -l 0
CONFIG
puts <<~CONFIG
graph_title Ejabberd Log
graph_vlabel total
graph_category chat
graph_args -l 0
CONFIG
end
(KNOWN_LOG_TYPES + %w(ERROR WARNING INFO DEBUG)).each.with_index { |log_type, index|
label, index = if log_type.is_a? Array
[log_type.first, index]
else
[log_type, log_type]
end
if ARGV.first == 'config'
puts "T#{index}.label #{label}"
puts "T#{index}.draw LINE"
else
puts "T#{index}.value #{log_info[index] or 0}"
end
label, index = if log_type.is_a? Array
[log_type.first, index]
else
[log_type, log_type]
end
if ARGV.first == 'config'
puts "T#{index}.label #{label}"
puts "T#{index}.draw LINE"
else
puts "T#{index}.value #{log_info[index] or 0}"
end
}

View File

@ -1,37 +1,42 @@
#!/usr/bin/env ruby
# mongrel_memory - A munin plugin for OpenSolaris to monitor memory size of
# each individual mongrel process
# Copyright (C) 2009 Matthias Marschall - mm@agileweboperations.com
#
# Based on:
# mongrel_process_memory - A munin plugin to monitor memory size of
# each individual mongrel process
# Copyright (C) 2007 Ben VandenBos and Avvo, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Author: Ben VandenBos
# Contributors: Adam Jacob (<adam@hjksolutions.com>)
# Ryan Woodrum
# Matthias Marschall (mm@agileweboperations.com)
#
=begin
mongrel_memory - A munin plugin for OpenSolaris to monitor memory size of
each individual mongrel process
Copyright (C) 2009 Matthias Marschall - mm@agileweboperations.com
Based on:
mongrel_process_memory - A munin plugin to monitor memory size of
each individual mongrel process
Copyright (C) 2007 Ben VandenBos and Avvo, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author: Ben VandenBos
Contributors: Adam Jacob (<adam@hjksolutions.com>)
Ryan Woodrum
Matthias Marschall (mm@agileweboperations.com)
#%# family=auto
#%# capabilities=autoconf
=end
module Munin
class MongrelProcessMemory
def run
pid_port_map = get_pids()
port_list = Hash.new
@ -48,8 +53,8 @@ module Munin
pids += `pgrep ruby`.split("\n")
pids.each { |pid|
l = `pargs -l #{pid}`
l =~ /-p (\d+)/
h[pid] = $1 if $1
l =~ /-p (\d+)/
h[pid] = $1 if $1
}
h
end
@ -57,7 +62,6 @@ module Munin
def autoconf
get_pids().length > 0
end
end
end

View File

@ -1,36 +1,40 @@
#!/usr/bin/env ruby
#
# mongrel_process_memory - A munin plugin to monitor memory size of
# each individual mongrel process
# Copyright (C) 2007 Ben VandenBos and Avvo, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Author: Ben VandenBos
# Contributors: Adam Jacob (<adam@hjksolutions.com>)
# Ryan Woodrum
#
=begin
mongrel_process_memory - A munin plugin to monitor memory size of
each individual mongrel process
Copyright (C) 2007 Ben VandenBos and Avvo, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author: Ben VandenBos
Contributors: Adam Jacob (<adam@hjksolutions.com>)
Ryan Woodrum
#%# family=auto
#%# capabilities=autoconf
=end
module Munin
class MongrelProcessMemory
def run
h = get_pids()
ps_output = ""
#I have no doubt that this is a terrible way of doing this.
# I have no doubt that this is a terrible way of doing this.
h.each do |k, v|
ps_output = ps_output + `ps --no-heading l #{k}`
end
@ -59,8 +63,8 @@ module Munin
pids = `pgrep mongrel_rails`
pids.each { |p|
l = `ps #{p}`
l =~ /-p (\d+)/
h[p] = $1
l =~ /-p (\d+)/
h[p] = $1
}
h
end
@ -68,7 +72,6 @@ module Munin
def autoconf
pids.length > 0
end
end
end

View File

@ -18,8 +18,8 @@ require 'open-uri'
def get_conf
# Default values
conf = {:host => '127.0.0.1', :port => 8000,
:username => 'admin', :password => 'hackme' }
conf = { :host => '127.0.0.1', :port => 8000,
:username => 'admin', :password => 'hackme' }
conf.keys.each do |key|
env_key = sprintf('icecast_%s', key)
conf[key] = ENV[env_key] if ENV.has_key?(env_key)
@ -31,8 +31,8 @@ def get_data(conf)
begin
data = Hpricot(open(sprintf('http://%s:%s/admin/stats',
conf[:host], conf[:port]),
:http_basic_authentication=>[conf[:username],
conf[:password]]))
:http_basic_authentication => [conf[:username],
conf[:password]]))
rescue OpenURI::HTTPError
puts "Cannot connect: HTTP connection error"
exit 1
@ -43,7 +43,7 @@ end
def get_values(data)
vals = {}
[:sources, :clients].each do |key|
elem = data/key
elem = data / key
if elem.nil?
vals[key] = 0
else

View File

@ -8,12 +8,12 @@
require 'socket'
if ARGV[0] == 'config'
puts "graph_title Connected players"
puts "graph_vlabel players"
puts "players.label players"
puts "graph_info Number of players connected to Minecraft"
puts "graph_category games"
exit
puts "graph_title Connected players"
puts "graph_vlabel players"
puts "players.label players"
puts "graph_info Number of players connected to Minecraft"
puts "graph_category games"
exit
end
host = ENV['host']

View File

@ -1,25 +1,30 @@
#!/usr/bin/env ruby
#
# Plugin to monitor the number of connections blocked by moblock.
#
# Requirements:
#
# Moblock up and running with generated log files going to /var/log/moblock
#
# Parameters supported:
#
# config
# autoconf
#
# Configurable variables
#
# logfile - Override default moblock logfile
#
# Magic markers
#
=begin
Plugin to monitor the number of connections blocked by moblock.
Requirements:
Moblock up and running with generated log files going to /var/log/moblock
Parameters supported:
config
autoconf
Configurable variables
logfile - Override default moblock logfile
Magic markers
#%# family=auto
#%# capabilities=autoconf
=end
#
# Initialize vars
#
@ -54,7 +59,7 @@ end
#
# Grep moblock logs for stats
#
def fetch(debug=false)
def fetch(debug = false)
num_in = %x{cat #{$logfile} | grep --extended-regexp 'IN: ' | wc -l}
num_out = %x{cat #{$logfile} | grep --extended-regexp 'OUT: ' | wc -l}
num_total = num_in.to_i + num_out.to_i
@ -80,12 +85,12 @@ end
# Handle command line args
#
case ARGV.first
when 'config'
config
when 'debug'
fetch true
when 'autoconf'
autoconf
else
fetch
when 'config'
config
when 'debug'
fetch true
when 'autoconf'
autoconf
else
fetch
end

View File

@ -1,49 +1,54 @@
#!/usr/bin/env ruby
#
# Munin Plugin for MSSQL - transaction monitoring
#
# Author: Wilfred Chau <openapp.developer@gmail.com>
# Date: 2011-05-18
# Version: 1.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
# Prerequistes:
# 1) /etc/odbc.ini and /etc/freetds.conf
# 2) rubygems
# 3) ruby-dbi
#
# Usage:
# 1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
# 2) chmod to allow executable to others
# 3) create symbolic link in /etc/munin/plugins
# ln -s /usr/share/munin/plugins/mssql_transaction.rb /etc/munin/plugins/mssql_transaction.rb
#
# Parameters:
# autoconf
# config (required)
#
# Config variables:
# sqluser : mssql user who has view server state privilege
# sqlpass : password for the mssql user
# dsn : datasource name as defined in /etc/odbc.ini
# instance: instance to monitor
#
=begin
Munin Plugin for MSSQL - transaction monitoring
Author: Wilfred Chau <openapp.developer@gmail.com>
Date: 2011-05-18
Version: 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Prerequistes:
1) /etc/odbc.ini and /etc/freetds.conf
2) rubygems
3) ruby-dbi
Usage:
1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
2) chmod to allow executable to others
3) create symbolic link in /etc/munin/plugins
ln -s /usr/share/munin/plugins/mssql_transaction.rb /etc/munin/plugins/mssql_transaction.rb
Parameters:
autoconf
config (required)
Config variables:
sqluser : mssql user who has view server state privilege
sqlpass : password for the mssql user
dsn : datasource name as defined in /etc/odbc.ini
instance: instance to monitor
#%# family=auto
#%# capabilities=autoconf
=end
require 'rubygems'
require 'dbi'
@ -56,7 +61,7 @@ instance = 'AdventureWorks'
# Queries
#
#
dbh = DBI.connect("DBI:ODBC:#{dsn}",sqluser,sqlpass)
dbh = DBI.connect("DBI:ODBC:#{dsn}", sqluser, sqlpass)
instance_name_query = "SELECT distinct instance_name
FROM sys.dm_os_performance_counters
@ -69,10 +74,10 @@ transaction_query = "select cntr_value from sys.dm_os_performance_counters
and object_name = 'SQLServer:Databases'
and instance_name = ?"
all_instance_names = Array.new
all_instance_names = Array.new
sth = dbh.execute(instance_name_query)
sth.fetch do |row|
all_instance_names.push(row[0].strip)
all_instance_names.push(row[0].strip)
end
sth.finish
@ -80,33 +85,33 @@ sth.finish
# autoconf
#
if ARGV[0] == "autoconf"
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
#
# config definition
#
elsif ARGV[0] == "config"
puts "graph_args --base 1000 -r --lower-limit 0"
puts "graph_title MSSQL Transactions/s"
puts "graph_category db"
puts "graph_info This graph shows transactions/s"
puts "graph_vlabel transactions/s"
puts "graph_scale no"
puts "graph_period second"
puts "graph_args --base 1000 -r --lower-limit 0"
puts "graph_title MSSQL Transactions/s"
puts "graph_category db"
puts "graph_info This graph shows transactions/s"
puts "graph_vlabel transactions/s"
puts "graph_scale no"
puts "graph_period second"
all_instance_names.sort.each do |s|
puts "#{s}.label #{s}"
puts "#{s}.info INSTANCE: #{s}"
puts "#{s}.type DERIVE"
puts "#{s}.draw LINE1"
end
all_instance_names.sort.each do |s|
puts "#{s}.label #{s}"
puts "#{s}.info INSTANCE: #{s}"
puts "#{s}.type DERIVE"
puts "#{s}.draw LINE1"
end
exit 0
exit 0
end
#
@ -114,11 +119,11 @@ end
#
sth = dbh.prepare(transaction_query)
all_instance_names.sort.each do |k|
sth.execute(k)
sth.fetch do |row|
# since type is DERIVE, need to convert value to integer then to string
puts "#{k.to_s}.value #{row[0].to_i.to_s}"
end
sth.execute(k)
sth.fetch do |row|
# since type is DERIVE, need to convert value to integer then to string
puts "#{k.to_s}.value #{row[0].to_i.to_s}"
end
end
sth.finish
dbh.disconnect

View File

@ -1,48 +1,53 @@
#!/usr/bin/env ruby
#
# Munin Plugin for MSSQL - Buffer cache hit ratio monitoring
#
# Author: Wilfred Chau <openapp.developer@gmail.com>
# Date: 2011-05-19
# Version: 1.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
# Prerequistes:
# 1) /etc/odbc.ini and /etc/freetds.conf
# 2) rubygems
# 3) ruby-dbi
#
# Usage:
# 1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
# 2) chmod to allow executable to others
# 3) create symbolic link in /etc/munin/plugins
# ln -s /usr/share/munin/plugins/mssql_buffercachehitratio.rb /etc/munin/plugins/mssql_buffercachehitratio.rb
#
# Parameters:
# autoconf
# config (required)
#
# Config variables:
# sqluser : mssql user who has view server state privilege
# sqlpass : password for the mssql user
# dsn : datasource name as defined in /etc/odbc.ini
#
=begin
Munin Plugin for MSSQL - Buffer cache hit ratio monitoring
Author: Wilfred Chau <openapp.developer@gmail.com>
Date: 2011-05-19
Version: 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Prerequistes:
1) /etc/odbc.ini and /etc/freetds.conf
2) rubygems
3) ruby-dbi
Usage:
1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
2) chmod to allow executable to others
3) create symbolic link in /etc/munin/plugins
ln -s /usr/share/munin/plugins/mssql_buffercachehitratio.rb /etc/munin/plugins/mssql_buffercachehitratio.rb
Parameters:
autoconf
config (required)
Config variables:
sqluser : mssql user who has view server state privilege
sqlpass : password for the mssql user
dsn : datasource name as defined in /etc/odbc.ini
#%# family=auto
#%# capabilities=autoconf
=end
require 'rubygems'
require 'dbi'
@ -54,7 +59,7 @@ dsn = 'TESTSQL'
# Queries
#
#
dbh = DBI.connect("DBI:ODBC:#{dsn}",sqluser,sqlpass)
dbh = DBI.connect("DBI:ODBC:#{dsn}", sqluser, sqlpass)
buffercachehitratio_query = "select (a.cntr_value * 1.0 / b.cntr_value) * 100.0
from sys.dm_os_performance_counters a
@ -70,36 +75,36 @@ buffercachehitratio_query = "select (a.cntr_value * 1.0 / b.cntr_value) * 100.0
# autoconf
#
if ARGV[0] == "autoconf"
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
#
# config definition
#
elsif ARGV[0] == "config"
puts "graph_args --base 1000 -r --lower-limit 0"
puts "graph_title MSSQL Buffer Cache Hit Ratio "
puts "graph_category db"
puts "graph_info This graph shows Buffer Cache Hit Ratio"
puts "graph_vlabel %"
puts "graph_scale no"
puts "graph_period second"
puts "graph_args --base 1000 -r --lower-limit 0"
puts "graph_title MSSQL Buffer Cache Hit Ratio "
puts "graph_category db"
puts "graph_info This graph shows Buffer Cache Hit Ratio"
puts "graph_vlabel %"
puts "graph_scale no"
puts "graph_period second"
puts "bc_hitratio.label BufferCacheHitRatio"
puts "bc_hitratio.info BufferCacheHitRatio"
puts "bc_hitratio.type GAUGE"
puts "bc_hitratio.draw LINE1"
puts "bc_hitratio.label BufferCacheHitRatio"
puts "bc_hitratio.info BufferCacheHitRatio"
puts "bc_hitratio.type GAUGE"
puts "bc_hitratio.draw LINE1"
exit 0
exit 0
end
sth = dbh.execute(buffercachehitratio_query)
sth.fetch do |row|
puts "bc_hitratio.value #{row[0].strip.to_s}"
puts "bc_hitratio.value #{row[0].strip.to_s}"
end
sth.finish
dbh.disconnect

View File

@ -1,49 +1,54 @@
#!/usr/bin/env ruby
#
# Munin Plugin for MSSQL - Data file size monitoring
#
# Author: Wilfred Chau <openapp.developer@gmail.com>
# Date: 2011-05-19
# Version: 1.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
# Prerequistes:
# 1) /etc/odbc.ini and /etc/freetds.conf
# 2) rubygems
# 3) ruby-dbi
#
# Usage:
# 1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
# 2) chmod to allow executable to others
# 3) create symbolic link in /etc/munin/plugins
# ln -s /usr/share/munin/plugins/mssql_datafilesizes.rb /etc/munin/plugins/mssql_datafilesizes.rb
#
# Parameters:
# autoconf
# config (required)
#
# Config variables:
# sqluser : mssql user who has view server state privilege
# sqlpass : password for the mssql user
# dsn : datasource name as defined in /etc/odbc.ini
# instance: instance to monitor
#
=begin
Munin Plugin for MSSQL - Data file size monitoring
Author: Wilfred Chau <openapp.developer@gmail.com>
Date: 2011-05-19
Version: 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Prerequistes:
1) /etc/odbc.ini and /etc/freetds.conf
2) rubygems
3) ruby-dbi
Usage:
1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
2) chmod to allow executable to others
3) create symbolic link in /etc/munin/plugins
ln -s /usr/share/munin/plugins/mssql_datafilesizes.rb /etc/munin/plugins/mssql_datafilesizes.rb
Parameters:
autoconf
config (required)
Config variables:
sqluser : mssql user who has view server state privilege
sqlpass : password for the mssql user
dsn : datasource name as defined in /etc/odbc.ini
instance: instance to monitor
#%# family=auto
#%# capabilities=autoconf
=end
require 'rubygems'
require 'dbi'
@ -56,7 +61,7 @@ instance = 'AdventureWorks'
# Queries
#
#
dbh = DBI.connect("DBI:ODBC:#{dsn}",sqluser,sqlpass)
dbh = DBI.connect("DBI:ODBC:#{dsn}", sqluser, sqlpass)
instance_name_query = "SELECT distinct instance_name
FROM sys.dm_os_performance_counters
@ -67,10 +72,10 @@ transaction_query = "select cntr_value/1024.0 from sys.dm_os_performance_counter
and object_name = 'SQLServer:Databases'
and instance_name = ?"
all_instance_names = Array.new
all_instance_names = Array.new
sth = dbh.execute(instance_name_query)
sth.fetch do |row|
all_instance_names.push(row[0].strip)
all_instance_names.push(row[0].strip)
end
sth.finish
@ -78,33 +83,33 @@ sth.finish
# autoconf
#
if ARGV[0] == "autoconf"
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
#
# config definition
#
elsif ARGV[0] == "config"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title MSSQL DB File Sizes"
puts "graph_category db"
puts "graph_info This graph shows DB File Sizes (MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title MSSQL DB File Sizes"
puts "graph_category db"
puts "graph_info This graph shows DB File Sizes (MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
all_instance_names.sort.each do |s|
puts "#{s}.label #{s}"
puts "#{s}.info INSTANCE: #{s}"
puts "#{s}.type GAUGE"
puts "#{s}.draw LINE1"
end
all_instance_names.sort.each do |s|
puts "#{s}.label #{s}"
puts "#{s}.info INSTANCE: #{s}"
puts "#{s}.type GAUGE"
puts "#{s}.draw LINE1"
end
exit 0
exit 0
end
#
@ -112,10 +117,10 @@ end
#
sth = dbh.prepare(transaction_query)
all_instance_names.sort.each do |k|
sth.execute(k)
sth.fetch do |row|
puts "#{k.to_s}.value #{row[0].to_s}"
end
sth.execute(k)
sth.fetch do |row|
puts "#{k.to_s}.value #{row[0].to_s}"
end
end
sth.finish
dbh.disconnect

View File

@ -1,49 +1,54 @@
#!/usr/bin/env ruby
#
# Munin Plugin for MSSQL - log files monitoring
#
# Author: Wilfred Chau <openapp.developer@gmail.com>
# Date: 2011-05-19
# Version: 1.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
# Prerequistes:
# 1) /etc/odbc.ini and /etc/freetds.conf
# 2) rubygems
# 3) ruby-dbi
#
# Usage:
# 1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
# 2) chmod to allow executable to others
# 3) create symbolic link in /etc/munin/plugins
# ln -s /usr/share/munin/plugins/mssql_logfilesizes.rb /etc/munin/plugins/mssql_logfilesizes.rb
#
# Parameters:
# autoconf
# config (required)
#
# Config variables:
# sqluser : mssql user who has view server state privilege
# sqlpass : password for the mssql user
# dsn : datasource name as defined in /etc/odbc.ini
# instance: instance to monitor
#
=begin
Munin Plugin for MSSQL - log files monitoring
Author: Wilfred Chau <openapp.developer@gmail.com>
Date: 2011-05-19
Version: 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Prerequistes:
1) /etc/odbc.ini and /etc/freetds.conf
2) rubygems
3) ruby-dbi
Usage:
1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
2) chmod to allow executable to others
3) create symbolic link in /etc/munin/plugins
ln -s /usr/share/munin/plugins/mssql_logfilesizes.rb /etc/munin/plugins/mssql_logfilesizes.rb
Parameters:
autoconf
config (required)
Config variables:
sqluser : mssql user who has view server state privilege
sqlpass : password for the mssql user
dsn : datasource name as defined in /etc/odbc.ini
instance: instance to monitor
#%# family=auto
#%# capabilities=autoconf
=end
require 'rubygems'
require 'dbi'
@ -56,7 +61,7 @@ instance = 'AdventureWorks'
# Queries
#
#
dbh = DBI.connect("DBI:ODBC:#{dsn}",sqluser,sqlpass)
dbh = DBI.connect("DBI:ODBC:#{dsn}", sqluser, sqlpass)
instance_name_query = "SELECT distinct instance_name
FROM sys.dm_os_performance_counters
@ -67,10 +72,10 @@ logfilesize_query = "SELECT cntr_value/1024.0 from sys.dm_os_performance_counter
AND object_name = 'SQLServer:Databases'
AND instance_name = ?"
all_instance_names = Array.new
all_instance_names = Array.new
sth = dbh.execute(instance_name_query)
sth.fetch do |row|
all_instance_names.push(row[0].strip)
all_instance_names.push(row[0].strip)
end
sth.finish
@ -78,41 +83,41 @@ sth.finish
# autoconf
#
if ARGV[0] == "autoconf"
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
if all_instance_names.length > 1 && sqluser.length > 1 && sqlpass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
#
# config definition
#
elsif ARGV[0] == "config"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title MSSQL DB Log File Sizes"
puts "graph_category db"
puts "graph_info This graph shows DB Log File Sizes (MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title MSSQL DB Log File Sizes"
puts "graph_category db"
puts "graph_info This graph shows DB Log File Sizes (MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
all_instance_names.sort.each do |s|
puts "#{s}.label #{s}"
puts "#{s}.info INSTANCE: #{s}"
puts "#{s}.type GAUGE"
puts "#{s}.draw LINE1"
end
all_instance_names.sort.each do |s|
puts "#{s}.label #{s}"
puts "#{s}.info INSTANCE: #{s}"
puts "#{s}.type GAUGE"
puts "#{s}.draw LINE1"
end
exit 0
exit 0
end
sth = dbh.prepare(logfilesize_query)
all_instance_names.sort.each do |k|
sth.execute(k)
sth.fetch do |row|
puts "#{k.to_s}.value #{row[0].to_s}"
end
sth.execute(k)
sth.fetch do |row|
puts "#{k.to_s}.value #{row[0].to_s}"
end
end
sth.finish
dbh.disconnect

View File

@ -45,7 +45,7 @@ require 'net/http'
class TPAdslStats
def initialize(host, user, password)
Net::HTTP.start( host ) do |http|
Net::HTTP.start(host) do |http|
req = Net::HTTP::Get.new('/statsadsl.html')
req.basic_auth user, password
response = http.request(req)

View File

@ -1,22 +1,26 @@
#!/usr/bin/env ruby
# netstat_s revision 6 (Nov 2013)
#
# This plugin shows various statistics from 'netstat -s'
#
# Required privileges: none
#
# OS:
# Supposed: BSD, Linux (only a few items, see netstat_multi for more)
# Tested: FreeBSD: 8.2, 8.3, 9.1
# Linux : Debian 6 (kernel 2.6.32), Arch (kernel 3.11.6), CentOS 6
#
# Author: Artem Sheremet <dot.doom@gmail.com>
#
=begin
netstat_s revision 6 (Nov 2013)
This plugin shows various statistics from 'netstat -s'
Required privileges: none
OS:
Supposed: BSD, Linux (only a few items, see netstat_multi for more)
Tested: FreeBSD: 8.2, 8.3, 9.1
Linux : Debian 6 (kernel 2.6.32), Arch (kernel 3.11.6), CentOS 6
Author: Artem Sheremet <dot.doom@gmail.com>
#%# family=auto
#%# capabilities=autoconf suggest
=end
# original filename
PLUGIN_NAME = 'netstat_s_'
@ -24,348 +28,348 @@ $os = `uname -s`.strip.downcase.to_sym
$debug_mode = ARGV.first == 'debug'
class String
def escape
self.gsub /[^\w]/, '_'
end
def escape
self.gsub /[^\w]/, '_'
end
unless method_defined? :start_with?
def start_with?(str)
self[0...str.size] == str
end
end
unless method_defined? :start_with?
def start_with?(str)
self[0...str.size] == str
end
end
unless method_defined? :lines
def lines
self.split($/).to_enum
end
end
unless method_defined? :lines
def lines
self.split($/).to_enum
end
end
end
class Graph
def initialize(name, protocol, parse_expr)
@name, @protocol, @parse_expr = name, protocol, parse_expr
end
def initialize(name, protocol, parse_expr)
@name, @protocol, @parse_expr = name, protocol, parse_expr
end
def config
config_options = []
def config
config_options = []
# first, build a list of multigraphs (one graph per unit)
# Hash key is unit, and the value is array of labels
multigraphs = {}
@parse_expr.each { |expr, descr|
next unless descr # no label - skip this entry
descr.each { |entry|
labels_array = (multigraphs[entry[0]] ||= [])
labels_array.push [entry[1], entry[2]]
}
}
# first, build a list of multigraphs (one graph per unit)
# Hash key is unit, and the value is array of labels
multigraphs = {}
@parse_expr.each { |expr, descr|
next unless descr # no label - skip this entry
multigraphs.each_pair { |unit, labels_and_negatives|
# now just add options to the config
descr.each { |entry|
labels_array = (multigraphs[entry[0]] ||= [])
labels_array.push [entry[1], entry[2]]
}
}
config_options.concat [
"multigraph #{name(unit)}",
"graph_title Netstat: #{@protocol}: #{@name}#{" (#{unit})" if multigraphs.size > 1}",
"graph_category network",
"graph_order #{labels_and_negatives.map { |label, _negative| label.escape }.join(' ')}"
]
multigraphs.each_pair { |unit, labels_and_negatives|
# now just add options to the config
config_options.push "graph_args --base 1024" if unit == :bytes
has_negatives = false
config_options.concat [
"multigraph #{name(unit)}",
"graph_title Netstat: #{@protocol}: #{@name}#{" (#{unit})" if multigraphs.size > 1}",
"graph_category network",
"graph_order #{labels_and_negatives.map { |label, _negative| label.escape }.join(' ')}"
]
labels_and_negatives.each { |label, negative|
label_esc = label.escape
has_negatives = true unless negative == nil
config_options.push "graph_args --base 1024" if unit == :bytes
has_negatives = false
if negative == true
# the value has no opposite and is negative
config_options.concat [
"#{label_esc}.graph no",
"#{label_esc}_neg.type DERIVE",
"#{label_esc}_neg.min 0",
"#{label_esc}_neg.draw LINE",
"#{label_esc}_neg.label #{label}",
"#{label_esc}_neg.negative #{label_esc}"
]
else
config_options.concat [
"#{label_esc}.type DERIVE",
"#{label_esc}.min 0",
"#{label_esc}.draw LINE",
"#{label_esc}.label #{label}"
]
end
labels_and_negatives.each { |label, negative|
label_esc = label.escape
has_negatives = true unless negative == nil
if negative == false
# the value has no opposite and is positive
config_options.concat [
"#{label_esc}_neg.graph off",
"#{label_esc}.negative #{label_esc}_neg"
]
elsif negative
negative_esc = negative.escape
config_options.concat [
"#{label_esc}.negative #{negative_esc}",
"#{negative_esc}.graph no"
]
end
}
if negative == true
# the value has no opposite and is negative
config_options.concat [
"#{label_esc}.graph no",
"#{label_esc}_neg.type DERIVE",
"#{label_esc}_neg.min 0",
"#{label_esc}_neg.draw LINE",
"#{label_esc}_neg.label #{label}",
"#{label_esc}_neg.negative #{label_esc}"
]
else
config_options.concat [
"#{label_esc}.type DERIVE",
"#{label_esc}.min 0",
"#{label_esc}.draw LINE",
"#{label_esc}.label #{label}"
]
end
config_options.push "graph_vlabel per second#{" in (-) / out (+)" if has_negatives}"
}
if negative == false
# the value has no opposite and is positive
config_options.concat [
"#{label_esc}_neg.graph off",
"#{label_esc}.negative #{label_esc}_neg"
]
elsif negative
negative_esc = negative.escape
config_options.concat [
"#{label_esc}.negative #{negative_esc}",
"#{negative_esc}.graph no"
]
end
}
config_options
end
config_options.push "graph_vlabel per second#{" in (-) / out (+)" if has_negatives}"
}
def fetch(data)
output_data = []
config_options
end
# first build a set of multigraphs, one per unit.
# Hash key is unit, and the value is a hash of 'escaped label' => 'value'
multigraphs = {}
@parse_expr.each { |expr, descr|
next unless descr # no label - skip this entry
index = data.index { |line| line =~ expr }
if index
data.delete_at index
$~[1..-1].zip(descr).each { |value, info|
unit, label = info
(multigraphs[unit] ||= {})[label.escape] = value
}
else
warn "no line found for #{expr}, #{descr}" if $debug_mode
end
}
def fetch(data)
output_data = []
multigraphs.each_pair { |unit, values|
output_data.push "multigraph #{name(unit)}"
output_data += values.map { |label, value| "#{label}.value #{value}" }
}
# first build a set of multigraphs, one per unit.
# Hash key is unit, and the value is a hash of 'escaped label' => 'value'
multigraphs = {}
@parse_expr.each { |expr, descr|
next unless descr # no label - skip this entry
output_data
end
index = data.index { |line| line =~ expr }
if index
data.delete_at index
$~[1..-1].zip(descr).each { |value, info|
unit, label = info
(multigraphs[unit] ||= {})[label.escape] = value
}
else
warn "no line found for #{expr}, #{descr}" if $debug_mode
end
}
def name(unit)
"#{PLUGIN_NAME}#{@protocol}_#{@name.escape}_#{unit}"
end
multigraphs.each_pair { |unit, values|
output_data.push "multigraph #{name(unit)}"
output_data += values.map { |label, value| "#{label}.value #{value}" }
}
output_data
end
def name(unit)
"#{PLUGIN_NAME}#{@protocol}_#{@name.escape}_#{unit}"
end
end
def graphs_for(protocol)
case protocol
# Order of the graps in each section is important for parsing.
# At the same time, it is not important for munin, so we are OK placing it in parsing order here.
when 'tcp'
$os == :linux ? [
Graph.new('sent', protocol, [
# Description of the elements of arrays below:
# 0: regexp to parse the line
# 1: Array<Array[3]> for each matching group in the regular expression.
# 0: unit name
# 1: label
# 2 (optional): negative label
# It could be reasonable to add more elements as warning and critical values.
case protocol
# Order of the graps in each section is important for parsing.
# At the same time, it is not important for munin, so we are OK placing it in parsing order here.
when 'tcp'
$os == :linux ? [
Graph.new('sent', protocol, [
# Description of the elements of arrays below:
# 0: regexp to parse the line
# 1: Array<Array[3]> for each matching group in the regular expression.
# 0: unit name
# 1: label
# 2 (optional): negative label
# It could be reasonable to add more elements as warning and critical values.
[ /(\d+) segments send out$/, [ [ :segments, 'total' ] ] ],
[ /(\d+) segments retransmitted$/, [ [ :segments, 'retransmitted' ] ] ]
]),
[/(\d+) segments send out$/, [[:segments, 'total']]],
[/(\d+) segments retransmitted$/, [[:segments, 'retransmitted']]]
]),
Graph.new('received', protocol, [
[ /(\d+) segments received$/, [ [ :segments, 'total' ] ] ],
[ /(\d+) bad segments received.$/, [ [ :segments, 'bad' ] ] ]
]),
Graph.new('received', protocol, [
[/(\d+) segments received$/, [[:segments, 'total']]],
[/(\d+) bad segments received.$/, [[:segments, 'bad']]]
]),
Graph.new('connections', protocol, [
[ /(\d+) active connections openings$/, [ [ :connections, 'active openings' ] ] ],
[ /(\d+) passive connection openings$/, [ [ :connections, 'passive openings' ] ] ],
[ /(\d+) failed connection attempts$/, [ [ :connections, 'failed attempts' ] ] ],
[ /(\d+) connection resets received$/, [ [ :connections, 'RST received' ] ] ],
[ /(\d+) connections established$/, [ [ :connections, 'established' ] ] ],
[ /(\d+) resets sent$/, [ [ :connections, 'RST sent' ] ] ]
]),
Graph.new('connections', protocol, [
[/(\d+) active connections openings$/, [[:connections, 'active openings']]],
[/(\d+) passive connection openings$/, [[:connections, 'passive openings']]],
[/(\d+) failed connection attempts$/, [[:connections, 'failed attempts']]],
[/(\d+) connection resets received$/, [[:connections, 'RST received']]],
[/(\d+) connections established$/, [[:connections, 'established']]],
[/(\d+) resets sent$/, [[:connections, 'RST sent']]]
]),
Graph.new('timeouts', protocol, [
[ /(\d+) timeouts after SACK recovery$/, [ [ :segments, 'after SACK recovery' ] ] ],
[ /(\d+) other TCP timeouts$/, [ [ :segments, 'other TCP' ] ] ],
[ /(\d+) timeouts in loss state$/, [ [ :segments, 'in a loss state' ] ] ]
])
] : [
Graph.new('sent', protocol, [
[ /(\d+) packets sent$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) data packets \((\d+) bytes\)$/, [ [ :packets, 'data' ], [ :bytes, 'data' ] ] ],
[ /(\d+) data packets \((\d+) bytes\) retransmitted$/, [ [ :packets, 'retransmitted' ], [ :bytes, 'retransmitted' ] ] ],
[ /(\d+) data packets unnecessarily retransmitted$/, [ [ :packets, 'unnecessarily retransmitted' ] ] ],
[ /(\d+) resends initiated by MTU discovery$/, [ [ :packets, 'resends initiated by MTU discovery' ] ] ],
[ /(\d+) ack-only packets \((\d+) delayed\)$/, [ [ :packets, 'ack-only' ], [ :packets, 'ack-only delayed' ] ] ],
[ /(\d+) URG only packets$/, [ [ :packets, 'URG only' ] ] ],
[ /(\d+) window probe packets$/, [ [ :packets, 'window probe' ] ] ],
[ /(\d+) window update packets$/, [ [ :packets, 'window update' ] ] ],
[ /(\d+) control packets$/, [ [ :packets, 'control' ] ] ]
]),
Graph.new('timeouts', protocol, [
[/(\d+) timeouts after SACK recovery$/, [[:segments, 'after SACK recovery']]],
[/(\d+) other TCP timeouts$/, [[:segments, 'other TCP']]],
[/(\d+) timeouts in loss state$/, [[:segments, 'in a loss state']]]
])
] : [
Graph.new('sent', protocol, [
[/(\d+) packets sent$/, [[:packets, 'total']]],
[/(\d+) data packets \((\d+) bytes\)$/, [[:packets, 'data'], [:bytes, 'data']]],
[/(\d+) data packets \((\d+) bytes\) retransmitted$/, [[:packets, 'retransmitted'], [:bytes, 'retransmitted']]],
[/(\d+) data packets unnecessarily retransmitted$/, [[:packets, 'unnecessarily retransmitted']]],
[/(\d+) resends initiated by MTU discovery$/, [[:packets, 'resends initiated by MTU discovery']]],
[/(\d+) ack-only packets \((\d+) delayed\)$/, [[:packets, 'ack-only'], [:packets, 'ack-only delayed']]],
[/(\d+) URG only packets$/, [[:packets, 'URG only']]],
[/(\d+) window probe packets$/, [[:packets, 'window probe']]],
[/(\d+) window update packets$/, [[:packets, 'window update']]],
[/(\d+) control packets$/, [[:packets, 'control']]]
]),
Graph.new('received', protocol, [
[ /(\d+) packets received$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) acks \(for (\d+) bytes\)$/, [ [ :packets, 'acks' ], [ :bytes, 'acks' ] ] ],
[ /(\d+) duplicate acks$/, [ [ :packets, 'duplicate acks' ] ] ],
[ /(\d+) acks for unsent data$/, [ [ :packets, 'acks for unsent data' ] ] ],
[ /(\d+) packets \((\d+) bytes\) received in-sequence$/, [ [ :packets, 'in-sequence' ], [ :bytes, 'in-sequence' ] ] ],
[ /(\d+) completely duplicate packets \((\d+) bytes\)$/, [ [ :packets, 'completely duplicate' ], [ :bytes, 'completely duplicate' ] ] ],
[ /(\d+) old duplicate packets$/, [ [ :packets, 'old duplicate' ] ] ],
[ /(\d+) packets with some dup\. data \((\d+) bytes duped\)$/, [ [ :packets, 'some dup. data' ], [ :bytes, 'partial dups' ] ] ],
[ /(\d+) out-of-order packets \((\d+) bytes\)$/, [ [ :packets, 'out-of-order' ], [ :bytes, 'out-of-order' ] ] ],
[ /(\d+) packets \((\d+) bytes\) of data after window$/, [ [ :packets, 'data after window' ], [ :bytes, 'data after window' ] ] ],
[ /(\d+) window probes$/, [ [ :packets, 'window probes' ] ] ],
[ /(\d+) window update packets$/, [ [ :packets, 'window update' ] ] ],
[ /(\d+) packets received after close$/, [ [ :packets, 'after close' ] ] ],
[ /(\d+) discarded for bad checksums$/, [ [ :packets, 'bad checksums' ] ] ],
[ /(\d+) discarded for bad header offset fields?$/, [ [ :packets, 'bad header offset flds' ] ] ],
[ /(\d+) discarded because packet too short$/, [ [ :packets, 'too short' ] ] ],
[ /(\d+) discarded due to memory problems$/, [ [ :packets, 'discarded: memory problems' ] ] ],
[ /(\d+) ignored RSTs in the windows$/, [ [ :packets, 'ignored RSTs in windows' ] ] ],
[ /(\d+) segments updated rtt \(of (\d+) attempts\)$/, [ [ :packets, 'RTT: updated' ], [ :packets, 'RTT: attempts to update' ] ] ]
]),
Graph.new('received', protocol, [
[/(\d+) packets received$/, [[:packets, 'total']]],
[/(\d+) acks \(for (\d+) bytes\)$/, [[:packets, 'acks'], [:bytes, 'acks']]],
[/(\d+) duplicate acks$/, [[:packets, 'duplicate acks']]],
[/(\d+) acks for unsent data$/, [[:packets, 'acks for unsent data']]],
[/(\d+) packets \((\d+) bytes\) received in-sequence$/, [[:packets, 'in-sequence'], [:bytes, 'in-sequence']]],
[/(\d+) completely duplicate packets \((\d+) bytes\)$/, [[:packets, 'completely duplicate'], [:bytes, 'completely duplicate']]],
[/(\d+) old duplicate packets$/, [[:packets, 'old duplicate']]],
[/(\d+) packets with some dup\. data \((\d+) bytes duped\)$/, [[:packets, 'some dup. data'], [:bytes, 'partial dups']]],
[/(\d+) out-of-order packets \((\d+) bytes\)$/, [[:packets, 'out-of-order'], [:bytes, 'out-of-order']]],
[/(\d+) packets \((\d+) bytes\) of data after window$/, [[:packets, 'data after window'], [:bytes, 'data after window']]],
[/(\d+) window probes$/, [[:packets, 'window probes']]],
[/(\d+) window update packets$/, [[:packets, 'window update']]],
[/(\d+) packets received after close$/, [[:packets, 'after close']]],
[/(\d+) discarded for bad checksums$/, [[:packets, 'bad checksums']]],
[/(\d+) discarded for bad header offset fields?$/, [[:packets, 'bad header offset flds']]],
[/(\d+) discarded because packet too short$/, [[:packets, 'too short']]],
[/(\d+) discarded due to memory problems$/, [[:packets, 'discarded: memory problems']]],
[/(\d+) ignored RSTs in the windows$/, [[:packets, 'ignored RSTs in windows']]],
[/(\d+) segments updated rtt \(of (\d+) attempts\)$/, [[:packets, 'RTT: updated'], [:packets, 'RTT: attempts to update']]]
]),
Graph.new('connections', protocol, [
[ /(\d+) connection requests$/, [ [ :connections, 'requests' ] ] ],
[ /(\d+) connection accepts$/, [ [ :connections, 'accepts' ] ] ],
[ /(\d+) bad connection attempts$/, [ [ :connections, 'bad attempts' ] ] ],
[ /(\d+) listen queue overflows$/, [ [ :connections, 'listen queue overflows' ] ] ],
[ /(\d+) connections established \(including accepts\)$/, [ [ :connections, 'established' ] ] ],
[ /(\d+) connections closed \(including (\d+) drops\)$/, [ [ :connections, 'closed' ], [ :connections, 'dropped' ] ] ],
[ /(\d+) connections updated cached RTT on close$/, [ [ :connections, 'closed & upd cached RTT' ] ] ],
[ /(\d+) connections updated cached RTT variance on close$/, [ [ :connections, 'closed & upd cached RTT variance' ] ] ],
[ /(\d+) connections updated cached ssthresh on close$/, [ [ :connections, 'closed & upd cached ssthresh' ] ] ],
[ /(\d+) embryonic connections dropped$/, [ [ :connections, 'embryonic dropped' ] ] ]
]),
Graph.new('connections', protocol, [
[/(\d+) connection requests$/, [[:connections, 'requests']]],
[/(\d+) connection accepts$/, [[:connections, 'accepts']]],
[/(\d+) bad connection attempts$/, [[:connections, 'bad attempts']]],
[/(\d+) listen queue overflows$/, [[:connections, 'listen queue overflows']]],
[/(\d+) connections established \(including accepts\)$/, [[:connections, 'established']]],
[/(\d+) connections closed \(including (\d+) drops\)$/, [[:connections, 'closed'], [:connections, 'dropped']]],
[/(\d+) connections updated cached RTT on close$/, [[:connections, 'closed & upd cached RTT']]],
[/(\d+) connections updated cached RTT variance on close$/, [[:connections, 'closed & upd cached RTT variance']]],
[/(\d+) connections updated cached ssthresh on close$/, [[:connections, 'closed & upd cached ssthresh']]],
[/(\d+) embryonic connections dropped$/, [[:connections, 'embryonic dropped']]]
]),
Graph.new('timeouts', protocol, [
[ /(\d+) retransmit timeouts$/, [ [ :connections, 'retransmit' ] ] ],
[ /(\d+) connections dropped by rexmit timeout$/, [ [ :connections, 'retransmit: dropped' ] ] ],
[ /(\d+) persist timeouts$/, [ [ :connections, 'persist' ] ] ],
[ /(\d+) connections dropped by persist timeout$/, [ [ :connections, 'persist: dropped' ] ] ],
[ /(\d+) Connections \(fin_wait_2\) dropped because of timeout$/, [ [ :connections, 'fin_wait_2: dropped' ] ] ],
[ /(\d+) keepalive timeouts$/, [ [ :connections, 'keepalive' ] ] ],
[ /(\d+) keepalive probes sent$/, [ [ :connections, 'keepalive: probes sent' ] ] ],
[ /(\d+) connections dropped by keepalive$/, [ [ :connections, 'keepalive: dropped' ] ] ]
]),
Graph.new('timeouts', protocol, [
[/(\d+) retransmit timeouts$/, [[:connections, 'retransmit']]],
[/(\d+) connections dropped by rexmit timeout$/, [[:connections, 'retransmit: dropped']]],
[/(\d+) persist timeouts$/, [[:connections, 'persist']]],
[/(\d+) connections dropped by persist timeout$/, [[:connections, 'persist: dropped']]],
[/(\d+) Connections \(fin_wait_2\) dropped because of timeout$/, [[:connections, 'fin_wait_2: dropped']]],
[/(\d+) keepalive timeouts$/, [[:connections, 'keepalive']]],
[/(\d+) keepalive probes sent$/, [[:connections, 'keepalive: probes sent']]],
[/(\d+) connections dropped by keepalive$/, [[:connections, 'keepalive: dropped']]]
]),
Graph.new('correct predictions', protocol, [
[ /(\d+) correct ACK header predictions$/, [ [ :predictions, 'ACK header' ] ] ],
[ /(\d+) correct data packet header predictions$/, [ [ :predictions, 'data packet header' ] ] ]
]),
Graph.new('correct predictions', protocol, [
[/(\d+) correct ACK header predictions$/, [[:predictions, 'ACK header']]],
[/(\d+) correct data packet header predictions$/, [[:predictions, 'data packet header']]]
]),
Graph.new('SYN', protocol, [
[ /(\d+) syncache entries added$/, [ [ :entries, 'cache added' ] ] ],
[ /(\d+) cookies sent$/, [ [ :entries, 'cookies sent' ] ] ],
[ /(\d+) cookies received$/, [ [ :entries, 'cookies received' ] ] ],
[ /(\d+) retransmitted$/, [ [ :entries, 'retransmitted' ] ] ],
[ /(\d+) dupsyn$/, [ [ :entries, 'duplicates' ] ] ],
[ /(\d+) dropped$/, [ [ :entries, 'dropped' ] ] ],
[ /(\d+) completed$/, [ [ :entries, 'completed' ] ] ],
[ /(\d+) bucket overflow$/, [ [ :entries, 'bucket overflow' ] ] ],
[ /(\d+) cache overflow$/, [ [ :entries, 'cache overflow' ] ] ],
[ /(\d+) reset$/, [ [ :entries, 'reset' ] ] ],
[ /(\d+) stale$/, [ [ :entries, 'stale' ] ] ],
[ /(\d+) aborted$/, [ [ :entries, 'aborted' ] ] ],
[ /(\d+) badack$/, [ [ :entries, 'bad ACK' ] ] ],
[ /(\d+) unreach$/, [ [ :entries, 'unreachable' ] ] ],
[ /(\d+) zone failures$/, [ [ :entries, 'zone failures' ] ] ],
[ /(\d+) hostcache entries added$/, [ [ :entries, 'hostcache added' ] ] ],
[ /(\d+) bucket overflow$/, [ [ :entries, 'hostcache overflow' ] ] ]
]),
Graph.new('SYN', protocol, [
[/(\d+) syncache entries added$/, [[:entries, 'cache added']]],
[/(\d+) cookies sent$/, [[:entries, 'cookies sent']]],
[/(\d+) cookies received$/, [[:entries, 'cookies received']]],
[/(\d+) retransmitted$/, [[:entries, 'retransmitted']]],
[/(\d+) dupsyn$/, [[:entries, 'duplicates']]],
[/(\d+) dropped$/, [[:entries, 'dropped']]],
[/(\d+) completed$/, [[:entries, 'completed']]],
[/(\d+) bucket overflow$/, [[:entries, 'bucket overflow']]],
[/(\d+) cache overflow$/, [[:entries, 'cache overflow']]],
[/(\d+) reset$/, [[:entries, 'reset']]],
[/(\d+) stale$/, [[:entries, 'stale']]],
[/(\d+) aborted$/, [[:entries, 'aborted']]],
[/(\d+) badack$/, [[:entries, 'bad ACK']]],
[/(\d+) unreach$/, [[:entries, 'unreachable']]],
[/(\d+) zone failures$/, [[:entries, 'zone failures']]],
[/(\d+) hostcache entries added$/, [[:entries, 'hostcache added']]],
[/(\d+) bucket overflow$/, [[:entries, 'hostcache overflow']]]
]),
Graph.new('SACK', protocol, [
[ /(\d+) SACK recovery episodes$/, [ [ :packets, 'recovery episodes' ] ] ],
[ /(\d+) segment rexmits in SACK recovery episodes$/, [ [ :packets, 'segment rexmits' ] ] ],
[ /(\d+) byte rexmits in SACK recovery episodes$/, [ [ :bytes, 'bytes rexmitted' ] ] ],
[ /(\d+) SACK options \(SACK blocks\) received$/, [ [ :packets, 'options blocks rcvd' ] ] ],
[ /(\d+) SACK options \(SACK blocks\) sent$/, [ [ :packets, 'options blocks sent' ] ] ],
[ /(\d+) SACK scoreboard overflow$/, [ [ :packets, 'scoreboard overflow' ] ] ]
]),
Graph.new('SACK', protocol, [
[/(\d+) SACK recovery episodes$/, [[:packets, 'recovery episodes']]],
[/(\d+) segment rexmits in SACK recovery episodes$/, [[:packets, 'segment rexmits']]],
[/(\d+) byte rexmits in SACK recovery episodes$/, [[:bytes, 'bytes rexmitted']]],
[/(\d+) SACK options \(SACK blocks\) received$/, [[:packets, 'options blocks rcvd']]],
[/(\d+) SACK options \(SACK blocks\) sent$/, [[:packets, 'options blocks sent']]],
[/(\d+) SACK scoreboard overflow$/, [[:packets, 'scoreboard overflow']]]
]),
Graph.new('ECN', protocol, [
[ /(\d+) packets with ECN CE bit set$/, [ [ :packets, 'CE bit' ] ] ],
[ /(\d+) packets with ECN ECT\(0\) bit set$/, [ [ :packets, 'ECT(0) bit' ] ] ],
[ /(\d+) packets with ECN ECT\(1\) bit set$/, [ [ :packets, 'ECT(1) bit' ] ] ],
[ /(\d+) successful ECN handshakes$/, [ [ :packets, 'successful handshakes' ] ] ],
[ /(\d+) times ECN reduced the congestion window$/, [ [ :packets, 'congestion window reduced' ] ] ]
])
]
when 'udp'
$os == :linux ? [
] : [
Graph.new('received', protocol, [
[ /(\d+) datagrams received$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) with incomplete header$/, [ [ :packets, 'incomplete header' ] ] ],
[ /(\d+) with bad data length field$/, [ [ :packets, 'bad data length field' ] ] ],
[ /(\d+) with bad checksum$/, [ [ :packets, 'bad checksum' ] ] ],
[ /(\d+) with no checksum$/, [ [ :packets, 'no checksum' ] ] ],
[ /(\d+) dropped due to no socket$/, [ [ :packets, 'dropped: no socket' ] ] ],
[ /(\d+) broadcast\/multicast datagrams undelivered$/, [ [ :packets, '*cast undelivered' ] ] ],
[ /(\d+) dropped due to full socket buffers$/, [ [ :packets, 'dropped: no buffers' ] ] ],
[ /(\d+) not for hashed pcb$/, [ [ :packets, 'not for hashed pcb' ] ] ],
[ /(\d+) delivered$/, [ [ :packets, 'delivered' ] ] ]
]),
Graph.new('ECN', protocol, [
[/(\d+) packets with ECN CE bit set$/, [[:packets, 'CE bit']]],
[/(\d+) packets with ECN ECT\(0\) bit set$/, [[:packets, 'ECT(0) bit']]],
[/(\d+) packets with ECN ECT\(1\) bit set$/, [[:packets, 'ECT(1) bit']]],
[/(\d+) successful ECN handshakes$/, [[:packets, 'successful handshakes']]],
[/(\d+) times ECN reduced the congestion window$/, [[:packets, 'congestion window reduced']]]
])
]
when 'udp'
$os == :linux ? [] : [
Graph.new('received', protocol, [
[/(\d+) datagrams received$/, [[:packets, 'total']]],
[/(\d+) with incomplete header$/, [[:packets, 'incomplete header']]],
[/(\d+) with bad data length field$/, [[:packets, 'bad data length field']]],
[/(\d+) with bad checksum$/, [[:packets, 'bad checksum']]],
[/(\d+) with no checksum$/, [[:packets, 'no checksum']]],
[/(\d+) dropped due to no socket$/, [[:packets, 'dropped: no socket']]],
[/(\d+) broadcast\/multicast datagrams undelivered$/, [[:packets, '*cast undelivered']]],
[/(\d+) dropped due to full socket buffers$/, [[:packets, 'dropped: no buffers']]],
[/(\d+) not for hashed pcb$/, [[:packets, 'not for hashed pcb']]],
[/(\d+) delivered$/, [[:packets, 'delivered']]]
]),
Graph.new('sent', protocol, [
[ /(\d+) datagrams output$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) times multicast source filter matched$/, [ [ :packets, 'multicast src filter match' ] ] ]
])
]
when 'ip'
$os == :linux ? [
] : [
Graph.new('received', protocol, [
[ /(\d+) total packets received$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) bad header checksums$/, [ [ :packets, 'bad header checksum' ] ] ],
[ /(\d+) with size smaller than minimum$/, [ [ :packets, 'size smaller than min' ] ] ],
[ /(\d+) with data size < data length$/, [ [ :packets, 'data size < data length' ] ] ],
[ /(\d+) with ip length > max ip packet size$/, [ [ :packets, 'ip length > max ip packet sz' ] ] ],
[ /(\d+) with header length < data size$/, [ [ :packets, 'header length < data size' ] ] ],
[ /(\d+) with data length < header length$/, [ [ :packets, 'data length < header length' ] ] ],
[ /(\d+) with bad options$/, [ [ :packets, 'bad options' ] ] ],
[ /(\d+) with incorrect version number$/, [ [ :packets, 'incorrect version' ] ] ],
[ /(\d+) fragments? received$/, [ [ :packets, 'fragments' ] ] ],
[ /(\d+) fragments? dropped \(dup or out of space\)$/, [ [ :packets, 'frags dropped: dup/out of spc' ] ] ],
[ /(\d+) fragments? dropped after timeout$/, [ [ :packets, 'frags dropped: timeout' ] ] ],
[ /(\d+) packets? reassembled ok$/, [ [ :packets, 'reassembled ok' ] ] ],
[ /(\d+) packets? for this host$/, [ [ :packets, 'for this host' ] ] ],
[ /(\d+) packets? for unknown\/unsupported protocol$/, [ [ :packets, 'for unknown/unsup protocol' ] ] ],
[ /(\d+) packets? forwarded \((\d+) packets fast forwarded\)$/, [ [ :packets, 'forwarded' ], [ :packets, 'fast forwarded' ] ] ],
[ /(\d+) packets? not forwardable$/, [ [ :packets, 'not forwardable' ] ] ],
[ /(\d+) packets? received for unknown multicast group$/, [ [ :packets, 'unknown multicast grp' ] ] ]
]),
Graph.new('sent', protocol, [
[/(\d+) datagrams output$/, [[:packets, 'total']]],
[/(\d+) times multicast source filter matched$/, [[:packets, 'multicast src filter match']]]
])
]
when 'ip'
$os == :linux ? [] : [
Graph.new('received', protocol, [
[/(\d+) total packets received$/, [[:packets, 'total']]],
[/(\d+) bad header checksums$/, [[:packets, 'bad header checksum']]],
[/(\d+) with size smaller than minimum$/, [[:packets, 'size smaller than min']]],
[/(\d+) with data size < data length$/, [[:packets, 'data size < data length']]],
[/(\d+) with ip length > max ip packet size$/, [[:packets, 'ip length > max ip packet sz']]],
[/(\d+) with header length < data size$/, [[:packets, 'header length < data size']]],
[/(\d+) with data length < header length$/, [[:packets, 'data length < header length']]],
[/(\d+) with bad options$/, [[:packets, 'bad options']]],
[/(\d+) with incorrect version number$/, [[:packets, 'incorrect version']]],
[/(\d+) fragments? received$/, [[:packets, 'fragments']]],
[/(\d+) fragments? dropped \(dup or out of space\)$/, [[:packets, 'frags dropped: dup/out of spc']]],
[/(\d+) fragments? dropped after timeout$/, [[:packets, 'frags dropped: timeout']]],
[/(\d+) packets? reassembled ok$/, [[:packets, 'reassembled ok']]],
[/(\d+) packets? for this host$/, [[:packets, 'for this host']]],
[/(\d+) packets? for unknown\/unsupported protocol$/, [[:packets, 'for unknown/unsup protocol']]],
[/(\d+) packets? forwarded \((\d+) packets fast forwarded\)$/, [[:packets, 'forwarded'], [:packets, 'fast forwarded']]],
[/(\d+) packets? not forwardable$/, [[:packets, 'not forwardable']]],
[/(\d+) packets? received for unknown multicast group$/, [[:packets, 'unknown multicast grp']]]
]),
Graph.new('sent', protocol, [
[ /(\d+) packets? sent from this host$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) redirects? sent$/, [ [ :packets, 'redirect' ] ] ],
[ /(\d+) packets? sent with fabricated ip header$/, [ [ :packets, 'fabricated IP head' ] ] ],
[ /(\d+) output packets? dropped due to no bufs, etc\.$/, [ [ :packets, 'dropped: no bufs, etc' ] ] ],
[ /(\d+) output packets? discarded due to no route$/, [ [ :packets, 'discarded: no route' ] ] ],
[ /(\d+) output datagrams? fragmented$/, [ [ :packets, 'fragmented' ] ] ],
[ /(\d+) fragments? created$/, [ [ :packets, 'fragments created' ] ] ],
[ /(\d+) datagrams? that can't be fragmented$/, [ [ :packets, "can't be fragmented" ] ] ],
[ /(\d+) tunneling packets? that can't find gif$/, [ [ :packets, 'tunneling, gif not found' ] ] ],
[ /(\d+) datagrams? with bad address in header$/, [ [ :packets, 'bad address in header' ] ] ]
])
]
when 'arp'
$os == :linux ? [] : [
Graph.new('packets', protocol, [
# This is just a total, so ignore the value but keep regexp to avoid 'not parsed' warning.
[ /(\d+) ARP packets? received$/ ],
[ /(\d+) ARP requests? received$/, [ [ :packets, 'requests received' ] ] ],
[ /(\d+) ARP repl(?:y|ies) received$/, [ [ :packets, 'replies received' ] ] ],
[ /(\d+) ARP requests? sent$/, [ [ :packets, 'requests', 'requests received' ] ] ],
[ /(\d+) ARP repl(?:y|ies) sent$/, [ [ :packets, 'replies', 'replies received' ] ] ],
[ /(\d+) total packets? dropped due to no ARP entry$/, [ [ :packets, 'no entry' ] ] ]
]),
Graph.new('sent', protocol, [
[/(\d+) packets? sent from this host$/, [[:packets, 'total']]],
[/(\d+) redirects? sent$/, [[:packets, 'redirect']]],
[/(\d+) packets? sent with fabricated ip header$/, [[:packets, 'fabricated IP head']]],
[/(\d+) output packets? dropped due to no bufs, etc\.$/, [[:packets, 'dropped: no bufs, etc']]],
[/(\d+) output packets? discarded due to no route$/, [[:packets, 'discarded: no route']]],
[/(\d+) output datagrams? fragmented$/, [[:packets, 'fragmented']]],
[/(\d+) fragments? created$/, [[:packets, 'fragments created']]],
[/(\d+) datagrams? that can't be fragmented$/, [[:packets, "can't be fragmented"]]],
[/(\d+) tunneling packets? that can't find gif$/, [[:packets, 'tunneling, gif not found']]],
[/(\d+) datagrams? with bad address in header$/, [[:packets, 'bad address in header']]]
])
]
when 'arp'
$os == :linux ? [] : [
Graph.new('packets', protocol, [
# This is just a total, so ignore the value but keep regexp to avoid 'not parsed' warning.
[/(\d+) ARP packets? received$/],
[/(\d+) ARP requests? received$/, [[:packets, 'requests received']]],
[/(\d+) ARP repl(?:y|ies) received$/, [[:packets, 'replies received']]],
[/(\d+) ARP requests? sent$/, [[:packets, 'requests', 'requests received']]],
[/(\d+) ARP repl(?:y|ies) sent$/, [[:packets, 'replies', 'replies received']]],
[/(\d+) total packets? dropped due to no ARP entry$/, [[:packets, 'no entry']]]
]),
Graph.new('entries', protocol, [
[ /(\d+) ARP entrys? timed out$/, [ [ :entries, 'timed out' ] ] ],
[ /(\d+) Duplicate IPs seen$/, [ [ :entries, 'duplicate IPs seen' ] ] ]
])
]
end
Graph.new('entries', protocol, [
[/(\d+) ARP entrys? timed out$/, [[:entries, 'timed out']]],
[/(\d+) Duplicate IPs seen$/, [[:entries, 'duplicate IPs seen']]]
])
]
end
end
proto_name = File.basename($0, '.*').escape
@ -374,31 +378,31 @@ proto_name.slice! 0, PLUGIN_NAME.size if proto_name.start_with? PLUGIN_NAME
proto_name = 'tcp' if proto_name.empty?
def netstat_s(protocol)
if $os == :linux
%w(tcp udp).include?(protocol) ?
`netstat -s --#{protocol}` :
`netstat -s --raw`
else
`netstat -sp #{protocol}`
end.lines.reject { |line| line =~ /^\w+:/ }
if $os == :linux
%w(tcp udp).include?(protocol) ?
`netstat -s --#{protocol}` :
`netstat -s --raw`
else
`netstat -sp #{protocol}`
end.lines.reject { |line| line =~ /^\w+:/ }
end
case ARGV.first
when 'autoconf'
puts [:linux, :freebsd].include?($os) ? 'yes' : 'no'
puts [:linux, :freebsd].include?($os) ? 'yes' : 'no'
when 'suggest'
puts $os == :linux ? %w(tcp) : %w(tcp udp ip arp)
puts $os == :linux ? %w(tcp) : %w(tcp udp ip arp)
when 'config'
graphs_for(proto_name).each { |graph|
puts graph.config.join $/
}
graphs_for(proto_name).each { |graph|
puts graph.config.join $/
}
else
data = netstat_s(proto_name)
graphs_for(proto_name).each { |graph|
puts graph.fetch(data).join $/
}
data = netstat_s(proto_name)
graphs_for(proto_name).each { |graph|
puts graph.fetch(data).join $/
}
warn "not parsed:\n#{data.join}" unless data.empty? if $debug_mode
warn "not parsed:\n#{data.join}" unless data.empty? if $debug_mode
end
# awful performance when scrolling through those regexps above

View File

@ -1,54 +1,59 @@
#!/usr/bin/env ruby
#
# Munin Plugin for PGA memory components monitoring
#
# Author: Wilfred Chau <openapp.developer@gmail.com>
# Date: 2011-05-13
# Version: 1.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
# Prerequistes:
# 1) env.ORACLE_HOME set in munin-node
# 2) rubygems
# 3) oci8 - DBI gem for connecting to Oracle
# * instruction of installing oci8 is available here:
# http://ruby-oci8.rubyforge.org/en/InstallBinaryPackage.html
#
# Usage:
# 1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
# 2) chmod to allow executable to others
# 3) create symbolic link in /etc/munin/plugins
# ln -s /usr/share/munin/plugins/oracle_<sid>_pga.rb /etc/munin/plugins/oracle_<sid>_pga.rb
# ** replace <sid> with your oralce sid
#
# Parameters:
# autoconf
# config (required)
#
# Configurable variables:
# orauser : oracle user who has select privilege to query v$pgastat view
# orapass : password for the oracle user
# dbport : port used by the monitored instance (notice: numeric value)
# dbname : database to be monitored
# dbhost : host or ip address of db instance
#
#
=begin
Munin Plugin for PGA memory components monitoring
Author: Wilfred Chau <openapp.developer@gmail.com>
Date: 2011-05-13
Version: 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Prerequistes:
1) env.ORACLE_HOME set in munin-node
2) rubygems
3) oci8 - DBI gem for connecting to Oracle
* instruction of installing oci8 is available here:
http://ruby-oci8.rubyforge.org/en/InstallBinaryPackage.html
Usage:
1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
2) chmod to allow executable to others
3) create symbolic link in /etc/munin/plugins
ln -s /usr/share/munin/plugins/oracle_<sid>_pga.rb /etc/munin/plugins/oracle_<sid>_pga.rb
** replace <sid> with your oralce sid
Parameters:
autoconf
config (required)
Configurable variables:
orauser : oracle user who has select privilege to query v$pgastat view
orapass : password for the oracle user
dbport : port used by the monitored instance (notice: numeric value)
dbname : database to be monitored
dbhost : host or ip address of db instance
#%# family=auto
#%# capabilities=autoconf
=end
require 'rubygems'
require 'oci8'
@ -58,17 +63,16 @@ dbport = 1522
dbname = 'orcl'
dbhost = 'localhost'
tnsname = "(DESCRIPTION =
tnsname = "(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = #{dbhost})(PORT = #{dbport}))
(CONNECT_DATA = (SID = #{dbname})))"
def runQuery (name,query)
rows = $conn.exec(query)
puts "#{name}.value #{rows.fetch().to_s}"
rows.close
def runQuery(name, query)
rows = $conn.exec(query)
puts "#{name}.value #{rows.fetch().to_s}"
rows.close
end
#
# Queries
#
@ -78,45 +82,44 @@ pga_target_query = "SELECT TO_CHAR(ROUND(decode(unit,'bytes',(value)/(1024*1024)
pga_query = "SELECT TO_CHAR(ROUND(decode(unit,'bytes',(value)/(1024*1024),value),2)) pga
from V$PGASTAT where name = 'total PGA inuse'"
pga_components = { "pga_target" => pga_target_query,
"pga_in_use" => pga_query
}
pga_components = { "pga_target" => pga_target_query,
"pga_in_use" => pga_query }
#
# autoconf
#
if ARGV[0] == "autoconf"
if tnsname.length > 1 && orauser.length > 1 && orapass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
if tnsname.length > 1 && orauser.length > 1 && orapass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
#
# config definition
#
elsif ARGV[0] == "config"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title Oracle PGA from #{dbname}"
puts "graph_category db"
puts "graph_info This graph shows the PGA memory usage (in MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title Oracle PGA from #{dbname}"
puts "graph_category db"
puts "graph_info This graph shows the PGA memory usage (in MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
pga_components.keys.each do |p|
puts "#{p}.label #{p}"
puts "#{p}.info PGA: #{p}"
puts "#{p}.type GAUGE"
puts "#{p}.draw LINE1"
end
pga_components.keys.each do |p|
puts "#{p}.label #{p}"
puts "#{p}.info PGA: #{p}"
puts "#{p}.type GAUGE"
puts "#{p}.draw LINE1"
end
exit 0
exit 0
end
$conn = OCI8.new(orauser, orapass, tnsname)
pga_components.each do |pc, query|
runQuery(pc, query)
runQuery(pc, query)
end
$conn.logoff

View File

@ -1,53 +1,58 @@
#!/usr/bin/env ruby
#
# Munin Plugin for SGA memory components monitoring
#
# Author: Wilfred Chau <openapp.developer@gmail.com>
# Date: 2011-05-12
# Version: 1.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
# Prerequistes:
# 1) env.ORACLE_HOME set in munin-node
# 2) rubygems
# 3) oci8 - DBI gem for connecting to Oracle
# * instruction of installing oci8 is available here:
# http://ruby-oci8.rubyforge.org/en/InstallBinaryPackage.html
#
# Usage:
# 1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
# 2) chmod to allow executable to others
# 3) create symbolic link in /etc/munin/plugins
# ln -s /usr/share/munin/plugins/oracle_orcl_sga.rb /etc/munin/plugins/oracle_orcl_sga.rb
#
# Parameters:
# autoconf
# config (required)
#
# Configurable variables:
# orauser : oracle user who has select privilege to query v$sgastat view
# orapass : password for the oracle user
# dbport : port used by the monitored instance (notice: numeric value)
# dbname : database to be monitored
# dbhost : host or ip address of db instance
#
#
=begin
Munin Plugin for SGA memory components monitoring
Author: Wilfred Chau <openapp.developer@gmail.com>
Date: 2011-05-12
Version: 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Prerequistes:
1) env.ORACLE_HOME set in munin-node
2) rubygems
3) oci8 - DBI gem for connecting to Oracle
* instruction of installing oci8 is available here:
http://ruby-oci8.rubyforge.org/en/InstallBinaryPackage.html
Usage:
1) copy this script to the munin install plugins directory (e.g. /usr/share/munin/plugins)
2) chmod to allow executable to others
3) create symbolic link in /etc/munin/plugins
ln -s /usr/share/munin/plugins/oracle_orcl_sga.rb /etc/munin/plugins/oracle_orcl_sga.rb
Parameters:
autoconf
config (required)
Configurable variables:
orauser : oracle user who has select privilege to query v$sgastat view
orapass : password for the oracle user
dbport : port used by the monitored instance (notice: numeric value)
dbname : database to be monitored
dbhost : host or ip address of db instance
#%# family=auto
#%# capabilities=autoconf
=end
require 'rubygems'
require 'oci8'
@ -57,17 +62,16 @@ dbport = 1522
dbname = 'orcl'
dbhost = 'localhost'
tnsname = "(DESCRIPTION =
tnsname = "(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = #{dbhost})(PORT = #{dbport}))
(CONNECT_DATA = (SID = #{dbname})))"
def runQuery (name,query)
rows = $conn.exec(query)
puts "#{name}.value #{rows.fetch().to_s}"
rows.close
def runQuery(name, query)
rows = $conn.exec(query)
puts "#{name}.value #{rows.fetch().to_s}"
rows.close
end
#
# Queries
#
@ -98,56 +102,54 @@ log_buffer_query = "SELECT TO_CHAR(ROUND(SUM(decode(pool, NULL,
decode(name, 'log_buffer', (bytes)/(1024*1024),0),0)),2)) sga_lbuffer
from V$SGASTAT"
memory_components = { "fixed_area" => fixed_area_query,
memory_components = { "fixed_area" => fixed_area_query,
"buffer_cache" => buffer_cache_query,
"java_pool" => java_pool_query,
"large_pool" => large_pool_query,
"log_buffer" => log_buffer_query,
"shared_pool" => shared_pool_query
}
"java_pool" => java_pool_query,
"large_pool" => large_pool_query,
"log_buffer" => log_buffer_query,
"shared_pool" => shared_pool_query }
#
# autoconf
#
if ARGV[0] == "autoconf"
if tnsname.length > 1 && orauser.length > 1 && orapass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
if tnsname.length > 1 && orauser.length > 1 && orapass.length > 1
puts "yes"
else
puts "no"
puts "Usage: #{__FILE__} autoconf|conf"
end
exit 0
#
# config definition
#
elsif ARGV[0] == "config"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title Oracle SGA from #{dbname}"
puts "graph_category db"
puts "graph_info This graph shows the SGA memory usage (in MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
puts "graph_args --base 1024k -r --lower-limit 0"
puts "graph_title Oracle SGA from #{dbname}"
puts "graph_category db"
puts "graph_info This graph shows the SGA memory usage (in MB)"
puts "graph_vlabel MB"
puts "graph_scale no"
puts "graph_period second"
memory_components.keys.each do |m|
puts "#{m}.label #{m}"
puts "#{m}.info SGA: #{m}"
puts "#{m}.type GAUGE"
memory_components.keys.each do |m|
puts "#{m}.label #{m}"
puts "#{m}.info SGA: #{m}"
puts "#{m}.type GAUGE"
# make sure fixed_area is at the bottom of the stack
if ( m == 'fixed_area' )
puts "#{m}.draw AREA"
else
puts "#{m}.draw STACK"
end
end
# make sure fixed_area is at the bottom of the stack
if (m == 'fixed_area')
puts "#{m}.draw AREA"
else
puts "#{m}.draw STACK"
end
end
exit 0
exit 0
end
$conn = OCI8.new(orauser, orapass, tnsname)
memory_components.each do |mc, query|
runQuery(mc, query)
runQuery(mc, query)
end
$conn.logoff

View File

@ -14,18 +14,17 @@ require 'mysql'
require 'yaml'
class Grapher
def initialize(db_conf)
@db_conf = db_conf
end
def config
puts <<-END_CONFIG
graph_title Delayed_Jobs Queue Size
graph_args -l 0
graph_vlabel jobs to be run
jobs.label jobs
jobs.type GAUGE
puts <<~END_CONFIG
graph_title Delayed_Jobs Queue Size
graph_args -l 0
graph_vlabel jobs to be run
jobs.label jobs
jobs.type GAUGE
END_CONFIG
end
@ -39,7 +38,6 @@ jobs.type GAUGE
value = result.fetch_hash.values.first
puts "jobs.value #{value}"
end
end
if __FILE__ == $0

View File

@ -15,64 +15,62 @@
require 'rubygems'
require 'munin'
SERVICE = $0.split( '_' ).last
SERVICE = $0.split('_').last
SERVICE_F = '/etc/services'
PORT = /^[\d]+(\.[\d]+){0,1}$/ === SERVICE ? SERVICE : %x[grep #{SERVICE} #{SERVICE_F}].split( "\t\t" )[1].split( '/' )[0]
PORT = /^[\d]+(\.[\d]+){0,1}$/ === SERVICE ? SERVICE : %x[grep #{SERVICE} #{SERVICE_F}].split("\t\t")[1].split('/')[0]
class PortMonit < Munin::Plugin
graph_attributes "#{SERVICE} port usage, known as #{PORT}",
:category => 'network',
:info => 'This graph shows connection split by the state of the socket.',
:vlabel => 'Current connections'
:category => 'network',
:info => 'This graph shows connection split by the state of the socket.',
:vlabel => 'Current connections'
declare_field :ESTABLISHED,
:label => 'Established', :draw => :AREA,
:type => :GAUGE, :min => 0
declare_field :ESTABLISHED,
:label => 'Established', :draw => :AREA,
:type => :GAUGE, :min => 0
declare_field :CLOSE_WAIT,
:label => 'Waiting close', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :CLOSE_WAIT,
:label => 'Waiting close', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :TIME_WAIT,
:label => 'Waiting after close', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :TIME_WAIT,
:label => 'Waiting after close', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :CLOSING,
:label => 'Closing', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :CLOSING,
:label => 'Closing', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :LAST_ACK,
:label => 'Waiting for acknowledgement', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :LAST_ACK,
:label => 'Waiting for acknowledgement', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :FIN_WAIT_1,
:label => 'Socket closed, connection shutting down', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :FIN_WAIT_1,
:label => 'Socket closed, connection shutting down', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :FIN_WAIT_2,
:label => 'Connection closed, Socket still waiting', :draw => :STACK,
:type => :GAUGE, :min => 0
declare_field :FIN_WAIT_2,
:label => 'Connection closed, Socket still waiting', :draw => :STACK,
:type => :GAUGE, :min => 0
def retrieve_values
@_netstat = %x[netstat -n -P tcp | egrep "\.#{PORT} "].split("\n")
@_netstat = %x[netstat -n -P tcp | egrep "\.#{PORT} "].split( "\n" )
{ :ESTABLISHED => count( @_netstat, 'ESTABLISHED' ),
:CLOSE_WAIT => count( @_netstat, 'CLOSE_WAIT' ),
:CLOSING => count( @_netstat, 'CLOSING' ),
:LAST_ACK => count( @_netstat, 'LAST_ACK' ),
:FIN_WAIT_1 => count( @_netstat, 'FIN_WAIT_1' ),
:FIN_WAIT_2 => count( @_netstat, 'FIN_WAIT_2' ),
:TIME_WAIT => count( @_netstat, 'TIME_WAIT' ) }
{ :ESTABLISHED => count(@_netstat, 'ESTABLISHED'),
:CLOSE_WAIT => count(@_netstat, 'CLOSE_WAIT'),
:CLOSING => count(@_netstat, 'CLOSING'),
:LAST_ACK => count(@_netstat, 'LAST_ACK'),
:FIN_WAIT_1 => count(@_netstat, 'FIN_WAIT_1'),
:FIN_WAIT_2 => count(@_netstat, 'FIN_WAIT_2'),
:TIME_WAIT => count(@_netstat, 'TIME_WAIT') }
end
private
def count( source, regex )
def count(source, regex)
@_result = 0
source.each { |obj| @_result += 1 if obj.match( regex ) }
source.each { |obj| @_result += 1 if obj.match(regex) }
return @_result
end

View File

@ -24,10 +24,10 @@ passenger_rss = nil
`#{memory_stats_command}`.each_line do |line|
next unless /### Total private dirty RSS: (\d+\.\d+) MB/.match(line)
passenger_rss = $~[1] unless apache_rss.nil?
apache_rss ||= $~[1]
end
puts "apache_rss.value #{apache_rss}"
puts "passenger_rss.value #{passenger_rss}"

View File

@ -39,4 +39,3 @@ puts "max.value #{max}"
puts "count.value #{count}"
puts "active.value #{active}"
puts "queued.value #{queued.to_i}"

View File

@ -1,27 +1,27 @@
#!/usr/bin/env ruby
def output_config
puts <<-END
graph_category webserver
graph_title status
graph_vlabel count
graph_info This graph shows how much passenger process are working, available and how much queries are waiting.
max.label max processes
max.draw AREA
max.info Maximum processes allowed to run simultaneously.
sessions.label queued requests
sessions.draw LINE2
sessions.info Requests queued, waiting to be processed.
running.label running processes
running.draw LINE1
running.info The number of application instances that are currently alive.
active.label active processes
active.draw LINE1
active.info The number of application instances that are currently processing requests.
waiting.label waiting requests
waiting.draw LINE2
waiting.info Requests waiting to be queued.
END
puts <<~END
graph_category webserver
graph_title status
graph_vlabel count
graph_info This graph shows how much passenger process are working, available and how much queries are waiting.
max.label max processes
max.draw AREA
max.info Maximum processes allowed to run simultaneously.
sessions.label queued requests
sessions.draw LINE2
sessions.info Requests queued, waiting to be processed.
running.label running processes
running.draw LINE1
running.info The number of application instances that are currently alive.
active.label active processes
active.draw LINE1
active.info The number of application instances that are currently processing requests.
waiting.label waiting requests
waiting.draw LINE2
waiting.info Requests waiting to be queued.
END
exit 0
end

View File

@ -31,7 +31,7 @@ user = ENV['user'] || 'user'
pwd = ENV['password'] || 'password'
url = ENV['url'] || 'http://127.0.0.1/control.php'
if ARGV[0]=="config"
if ARGV[0] == "config"
print "EAccelerator Monitoring\n"
print "graph_title PHP Eaccelerator\n"
print "graph_category webserver\n"
@ -47,58 +47,56 @@ if ARGV[0]=="config"
exit
end
one_liners=0
three_liners=0
key=""
one_liners = 0
three_liners = 0
key = ""
open(url, :http_basic_authentication=>[user, pwd]) do |f|
open(url, :http_basic_authentication => [user, pwd]) do |f|
f.each do |line|
if three_liners>0
three_liners=three_liners+1
if three_liners > 0
three_liners = three_liners + 1
if three_liners==2
if three_liners == 2
print "Memoryusagepercentage.value "
end
if three_liners==3
if three_liners == 3
print "Memoryusage.value "
end
if three_liners==4
if three_liners == 4
print "Memorymax.value "
end
print line.gsub!(/[^0-9.]/s,"")
print line.gsub!(/[^0-9.]/s, "")
print "\n"
end
if one_liners>0
one_liners=one_liners+1
if one_liners > 0
one_liners = one_liners + 1
print "#{key}.value "
print line.gsub!(/[^0-9.]/s,"")
print line.gsub!(/[^0-9.]/s, "")
print "\n"
end
if one_liners>1
line=""
one_liners=0
if one_liners > 1
line = ""
one_liners = 0
end
if three_liners>3
line=""
three_liners=0
if three_liners > 3
line = ""
three_liners = 0
end
if line =~ /Memory usage/
key=line.gsub!(/(<[^>]*>)|\n|\t| /s,"")
three_liners=three_liners+1
key = line.gsub!(/(<[^>]*>)|\n|\t| /s, "")
three_liners = three_liners + 1
end
if line =~ /<td class="e">Free memory/ || line =~ /<td class="e">Cached scripts/ || line =~ /<td class="e">Removed scripts/ || line =~ /<td class="e">Cached keys/
key=line.gsub!(/(<[^>]*>)|\n|\t| /s,"")
one_liners=one_liners+1
if line =~ /<td class="e">Free memory/ || line =~ /<td class="e">Cached scripts/ || line =~ /<td class="e">Removed scripts/ || line =~ /<td class="e">Cached keys/
key = line.gsub!(/(<[^>]*>)|\n|\t| /s, "")
one_liners = one_liners + 1
end
end
end

View File

@ -1,51 +1,56 @@
#!/usr/bin/env ruby
# munin plugin to retrieve connection statistics from the web admin interface
# on a Linksys AG241v2 ADSL modem
# Makes use of the http://modemaddress/ADSLCStatus.htm page
#This plugin has only been tested on a Debian testing system
=begin
# This modem also has some basic SNMP support so you can configure it
# as per the instructions on the munin wiki
# http://munin.projects.linpro.no/wiki/Using_SNMP_plugins
# By default the SNMP server is disabled, you can enable it in the web admin
# You will need to set up the "virtual node" configuration as detailed
# for snmp plugins
munin plugin to retrieve connection statistics from the web admin interface
on a Linksys AG241v2 ADSL modem
Makes use of the http://modemaddress/ADSLCStatus.htm page
# Plugin will require some configuration in /etc/munin/plugin-conf.d/ag241_MODEMADDRESS
# e.g.
# [ag241_vocume.stargate_*]
# env.user admin
# env.pass password
# #env.port 80
This plugin has only been tested on a Debian testing system
# Once you have the above config set you will need to symlink the plugin to
# /etc/munin/plugins/ag241_MODEMADDRESS_syncrate
# /etc/munin/plugins/ag241_MODEMADDRESS_attenutation
# /etc/munin/plugins/ag241_MODEMADDRESS_noise
# now restart munin-node.
# hopefully in 20-30mins you will have some nice graphs
This modem also has some basic SNMP support so you can configure it
as per the instructions on the munin wiki
http://munin.projects.linpro.no/wiki/Using_SNMP_plugins
By default the SNMP server is disabled, you can enable it in the web admin
You will need to set up the "virtual node" configuration as detailed
for snmp plugins
Plugin will require some configuration in /etc/munin/plugin-conf.d/ag241_MODEMADDRESS
e.g.
[ag241_vocume.stargate_*]
env.user admin
env.pass password
#env.port 80
#Some magical munin foo...
Once you have the above config set you will need to symlink the plugin to
/etc/munin/plugins/ag241_MODEMADDRESS_syncrate
/etc/munin/plugins/ag241_MODEMADDRESS_attenutation
/etc/munin/plugins/ag241_MODEMADDRESS_noise
now restart munin-node.
hopefully in 20-30mins you will have some nice graphs
Some magical munin foo...
#%# family=manual
#%# capabilities=
=end
# Require this module, it is part of the standard ruby lib AFAIK
require 'net/http'
#default parameters
# default parameters
host = nil
port = ENV['port'] || 80
user = ENV['user'] || 'admin'
pass = ENV['pass'] || 'forhax' #don't remember what the default admin password was
pass = ENV['pass'] || 'forhax' # don't remember what the default admin password was
stat = nil
# Check executable "name" for parameter count
params = $0.split('_')
if params.size != 3
puts "Incorrect number of parameters"
exit 1
puts "Incorrect number of parameters"
exit 1
end
# first param after the plugin name is the host to query
@ -54,79 +59,79 @@ host = params[1]
stat = params[2]
unless ENV['debug'].nil?
puts "user = "+ user
puts "pass = "+ pass
puts "host = "+ host
puts "port = "+ port
puts "stat = "+ stat
puts "user = " + user
puts "pass = " + pass
puts "host = " + host
puts "port = " + port
puts "stat = " + stat
end
# Dump the graph configuration data
if ARGV[0] == 'config'
puts 'host_name ' + host
puts 'graph_category network'
puts 'host_name ' + host
puts 'graph_category network'
case stat
when 'syncrate'
puts 'graph_info This graph shows the ADSL line sync rate.'
puts 'graph_title ADSL line sync rate'
puts 'graph_vlabel connection rate bits / second'
puts 'graph_args --base 1000 -l 0 '
when 'attenuation'
puts 'graph_info This graph shows the ADSL line attenuation.'
puts 'graph_title ADSL line attenuation'
puts 'graph_vlabel attenuation dB'
when 'margin','noise'
puts 'graph_info This graph shows the ADSL SNR margin.'
puts 'graph_title ADSL line SNR margin'
puts 'graph_vlabel noise margin dB'
end
puts 'down.label downstream'
puts 'up.label upstream'
exit 0
case stat
when 'syncrate'
puts 'graph_info This graph shows the ADSL line sync rate.'
puts 'graph_title ADSL line sync rate'
puts 'graph_vlabel connection rate bits / second'
puts 'graph_args --base 1000 -l 0 '
when 'attenuation'
puts 'graph_info This graph shows the ADSL line attenuation.'
puts 'graph_title ADSL line attenuation'
puts 'graph_vlabel attenuation dB'
when 'margin', 'noise'
puts 'graph_info This graph shows the ADSL SNR margin.'
puts 'graph_title ADSL line SNR margin'
puts 'graph_vlabel noise margin dB'
end
puts 'down.label downstream'
puts 'up.label upstream'
exit 0
end
# Connect to the webadmin
http = Net::HTTP.start(host,port)
http = Net::HTTP.start(host, port)
req = Net::HTTP::Get.new('/ADSLCStatus.htm')
# send the login info
req.basic_auth user, pass
response = http.request(req)
s = response.body
#Make sure we got the page successfully
# Make sure we got the page successfully
if response.code != '200'
puts "Getting web page failed:"
case response.code
when '401'
puts 'Probably because the username and password are incorrect'
#Looks like the modem response with 200 when you try to access a page that does not exist >_>
#when '404'
# puts 'Looks like the page this plugin needs isn\'t available...'
# puts 'Check your modem make/model/version'
end
puts s
exit 1
puts "Getting web page failed:"
case response.code
when '401'
puts 'Probably because the username and password are incorrect'
# Looks like the modem response with 200 when you try to access a page that does not exist >_>
# when '404'
# puts 'Looks like the page this plugin needs isn\'t available...'
# puts 'Check your modem make/model/version'
end
puts s
exit 1
end
# Apply voodoo regex to the result HTML to get the data we want.
case stat
when 'syncrate'
a = s.scan(/.*share\.curstate.*\n.*share\.downstr[^0-9]*([0-9]+).*share\.upstr[^0-9]*([0-9]+).*$/)
b,c = a[0]
puts 'down.value '+ (b.to_i*1000).to_s + "\n" + 'up.value '+ (c.to_i*1000).to_s
exit 0
when 'attenuation'
a = s.scan(/.*share\.lineatt.*\n.*share\.down[^0-9]*([0-9]+).*share\.up[^0-9]*([0-9]+).*$/)
b,c = a[0]
puts 'down.value '+ (b.to_i).to_s + "\n" + 'up.value '+ (c.to_i).to_s
exit 0
when 'margin','noise'
a = s.scan(/.*share\.noise.*\n.*share\.down[^0-9]*([0-9]+).*share\.up[^0-9]*([0-9]+).*$/)
b,c = a[0]
puts 'down.value '+ (b.to_i).to_s + "\n" + 'up.value '+ (c.to_i).to_s
exit 0
else
puts 'Statistic ' + stat.to_s + ' not known, would you like me to fabricate it for you?'
exit 1
when 'syncrate'
a = s.scan(/.*share\.curstate.*\n.*share\.downstr[^0-9]*([0-9]+).*share\.upstr[^0-9]*([0-9]+).*$/)
b, c = a[0]
puts 'down.value ' + (b.to_i * 1000).to_s + "\n" + 'up.value ' + (c.to_i * 1000).to_s
exit 0
when 'attenuation'
a = s.scan(/.*share\.lineatt.*\n.*share\.down[^0-9]*([0-9]+).*share\.up[^0-9]*([0-9]+).*$/)
b, c = a[0]
puts 'down.value ' + (b.to_i).to_s + "\n" + 'up.value ' + (c.to_i).to_s
exit 0
when 'margin', 'noise'
a = s.scan(/.*share\.noise.*\n.*share\.down[^0-9]*([0-9]+).*share\.up[^0-9]*([0-9]+).*$/)
b, c = a[0]
puts 'down.value ' + (b.to_i).to_s + "\n" + 'up.value ' + (c.to_i).to_s
exit 0
else
puts 'Statistic ' + stat.to_s + ' not known, would you like me to fabricate it for you?'
exit 1
end

View File

@ -31,7 +31,6 @@ require 'mechanize'
require 'digest/md5'
require 'nokogiri'
def output
nics = Hash.new
nics["LAN"] = Hash.new
@ -80,7 +79,7 @@ def output
j = 0
doc = Nokogiri::XML(clients_xml.to_s)
doc.xpath('//assoc').each do |assoc|
j+=1
j += 1
end
puts "wifi_assoc.value " + j.to_s
@ -89,7 +88,7 @@ def output
j = 0
doc = Nokogiri::XML(clients_xml.to_s)
doc.xpath('//client').each do |client|
j+=1
j += 1
end
puts "dhcp_clients.value " + j.to_s
@ -98,31 +97,31 @@ def output
clients_xml = agent.get("#{router_path}/wan_connection_status.xml").body
doc = Nokogiri::XML(clients_xml.to_s)
uptime = doc.children.search('wan_interface_up_time_0')[0].text
puts "uptime.value " + sprintf( "%.2f", (Float(uptime)/86400) )
puts "uptime.value " + sprintf("%.2f", (Float(uptime) / 86400))
# graph overall interface packets transferred per interval
puts "multigraph if_packets"
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "#{i}_recv.value " + nics[i]["packets_received"]
puts "#{i}_send.value " + nics[i]["packets_sent"]
end
# graph overall interface dropped packets per interval
puts "multigraph if_drop"
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "#{i}_recv.value " + nics[i]["rx_dropped"]
puts "#{i}_send.value " + nics[i]["tx_dropped"]
end
# graph overall interface collisions & errors per interval
puts "multigraph if_collerr"
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "#{i}_coll.value " + nics[i]["tx_collisions"]
puts "#{i}_err.value " + nics[i]["rx_errors"]
end
# graph stats for each interface
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "multigraph if_packets.#{i}"
puts "send.value " + nics[i]["packets_sent"]
puts "recv.value " + nics[i]["packets_received"]
@ -135,7 +134,6 @@ def output
end
end
def config
# build the configuration for graphs
puts "multigraph if_packets"
@ -143,7 +141,7 @@ def config
puts 'graph_category network'
puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "#{i}_recv.type DERIVE"
puts "#{i}_recv.graph no"
puts "#{i}_recv.min 0"
@ -158,7 +156,7 @@ def config
puts 'graph_category network'
puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
puts 'graph_vlabel packets / ${graph_period}'
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "#{i}_recv.type DERIVE"
puts "#{i}_recv.graph no"
puts "#{i}_recv.min 0"
@ -173,7 +171,7 @@ def config
puts 'graph_category network'
puts 'graph_order LAN_coll LAN_err WAN_coll WAN_err WLAN_coll WLAN_coll'
puts 'graph_vlabel packets / ${graph_period}'
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "#{i}_coll.label #{i} collisions"
puts "#{i}_coll.type DERIVE"
puts "#{i}_coll.min 0"
@ -201,7 +199,7 @@ def config
puts 'uptime.label uptime'
puts 'uptime.draw AREA'
for i in [ "LAN", "WAN", "WLAN" ] do
for i in ["LAN", "WAN", "WLAN"] do
puts "multigraph if_packets.#{i}"
puts "graph_title D-Link DIR-655 #{i} traffic"
puts 'graph_category network'
@ -244,7 +242,6 @@ def config
end
end
# main
if ARGV.length == 1 and ARGV[0] == 'config'
config()

View File

@ -89,6 +89,7 @@ when "config"
if not is_vb_valid(vb, subchannel)
next
end
puts "#{field_name(unit, vb, letter)}.label #{label(unit, vb)}"
end
end
@ -96,7 +97,6 @@ when "config"
exit 0
end
units.each do |unit|
SNMP::Manager.open(:Host => unit,
:Community => community,
@ -105,6 +105,7 @@ units.each do |unit|
if not is_vb_valid(vb, subchannel)
next
end
puts "#{field_name(unit, vb, letter)}.value #{vb.value.to_f / 100}"
end
end

View File

@ -1,50 +1,56 @@
#!/usr/bin/env ruby
# Plugin to monitor the number of invalid access to sshd per country
#
# Require read permissions for SYSLOG
# ref) ls -l /var/log/secure
# Require geoip rubygem
# ref) http://geoip.rubyforge.org/
# Require GeoIP-database for searching ip or host for the country
# ref) http://www.maxmind.com/app/geoip_country
#
# Parameters:
# config (required)
# autoconf (optional - used by munin-config)
#
# $Log$
# Revision 1.0 2010/12/25 11:56:12 hirata yoshiyuki
# released.
#
# Magick markers (optional):
=begin
Plugin to monitor the number of invalid access to sshd per country
Require read permissions for SYSLOG
ref) ls -l /var/log/secure
Require geoip rubygem
ref) http://geoip.rubyforge.org/
Require GeoIP-database for searching ip or host for the country
ref) http://www.maxmind.com/app/geoip_country
Parameters:
config (required)
autoconf (optional - used by munin-config)
$Log$
Revision 1.0 2010/12/25 11:56:12 hirata yoshiyuki
released.
Magick markers (optional):
#%# family=auto
#%# capabilities=autoconf
#
# config example for /etc/munin/plugin-conf.d/munin-node
#[sshd_invalid_countries_ruby]
#user root
#group root
#env.logfile /var/log/secure
#env.geoip /home/you/GeoIP.dat
#env.loadpath /usr/local/lib/ruby/gems/1.9.1/gems/geoip-0.8.8/lib/
config example for /etc/munin/plugin-conf.d/munin-node
[sshd_invalid_countries_ruby]
user root
group root
env.logfile /var/log/secure
env.geoip /home/you/GeoIP.dat
env.loadpath /usr/local/lib/ruby/gems/1.9.1/gems/geoip-0.8.8/lib/
=end
require (ENV['loadpath'] || '') + 'geoip'
SYSLOG = ENV['syslog'] || '/var/log/secure'
GEOIP_DB = ENV['geoip'] || '/var/www/conf/bbs/GeoIP.dat'
AWK_CMD = 'awk \'/sshd\[.*Did not receive identification string/{print $12} ' +
'/sshd\[.*Failed password for (root|ROOT)/{print $11} ' +
'/sshd\[.*Invalid user/{print $10}a\' < ' + SYSLOG
'/sshd\[.*Failed password for (root|ROOT)/{print $11} ' +
'/sshd\[.*Invalid user/{print $10}a\' < ' + SYSLOG
def getInvalids
c={}
c = {}
wholeips = `#{AWK_CMD}`.split("\n")
uniqueips = wholeips.inject({}) do |hash, key|
hash.include?(key) ? hash[key] += 1 : hash[key] = 1;
hash
end
geoip = GeoIP.new(GEOIP_DB)
uniqueips.each do |ip,cnt|
uniqueips.each do |ip, cnt|
begin
country = geoip.country(ip)[5]
c[country] = c[country] ? c[country] + cnt : cnt
@ -52,7 +58,7 @@ def getInvalids
c['Unknown'] = c['Unknown'] ? c['Unknown'] + cnt : cnt
end
end
c = c.to_a.sort {|a,b| a[0] <=> b[0]}
c = c.to_a.sort { |a, b| a[0] <=> b[0] }
c
end
@ -73,8 +79,8 @@ when 'config'
puts 'graph_vlabel number of invalid access per country'
puts 'graph_category security'
puts 'graph_info This graph shows the countries of invalid access to sshd.'
getInvalids.each {|k,v| puts k + '.label ' + k}
getInvalids.each { |k, v| puts k + '.label ' + k }
exit 0
else
getInvalids.each {|k,v| puts k + '.value ' + v.to_s}
getInvalids.each { |k, v| puts k + '.value ' + v.to_s }
end

View File

@ -1,50 +1,55 @@
#!/usr/bin/env ruby
# thin_memory - A munin plugin for Linux to monitor memory size of each individual thin process
#
# For Linux ONLY !
# DOES NOT WORK on OSX, Solaris or BSD.
# only linux, because this script relies on proc filesystem
#
# Original author:
# Frederico de Souza Araujo - fred.the.master@gmail.com
# http://www.frederico-araujo.com
#
# Usurper:
# Adam Michel - elfurbe@furbism.com
# http://www.furbism.com
#
# Originally based on:
# thin_process_memory -
# A munin plugin to monitor memory size of
# each individual thin process
# by Ben VandenBos and Avvo, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
=begin
thin_memory - A munin plugin for Linux to monitor memory size of each individual thin process
For Linux ONLY !
DOES NOT WORK on OSX, Solaris or BSD.
only linux, because this script relies on proc filesystem
Original author:
Frederico de Souza Araujo - fred.the.master@gmail.com
http://www.frederico-araujo.com
Usurper:
Adam Michel - elfurbe@furbism.com
http://www.furbism.com
Originally based on:
thin_process_memory -
A munin plugin to monitor memory size of
each individual thin process
by Ben VandenBos and Avvo, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#%# family=auto
#%# capabilities=autoconf
=end
module Munin
class ThinProcessMemory
# run main method
def run
instances = get_pids()
instances.each do |instance|
pid, port = instance.split("|")
rss = (pid_rss(pid).to_i)/1024
rss = (pid_rss(pid).to_i) / 1024
puts "thin_#{port}.value #{rss}"
end
end
@ -67,7 +72,6 @@ module Munin
def autoconf
get_pids().length > 0
end
end
end

View File

@ -1,45 +1,50 @@
#!/usr/bin/env ruby
# thin_threads -
# A munin plugin for Linux to monitor how many threads per thin process
#
# For Linux ONLY !
# DOES NOT WORK on OSX, Solaris or BSD.
# only linux, because this script relies on proc filesystem
#
# Original author:
# Frederico de Souza Araujo - fred.the.master@gmail.com
# http://www.frederico-araujo.com
#
# Usurper:
# Adam Michel - elfurbe@furbism.com
# http://www.furbism.com
#
# Originally based on:
# thin_process_memory -
# A munin plugin to monitor memory size of
# each individual thin process
# by Ben VandenBos and Avvo, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
=begin
thin_threads -
A munin plugin for Linux to monitor how many threads per thin process
For Linux ONLY !
DOES NOT WORK on OSX, Solaris or BSD.
only linux, because this script relies on proc filesystem
Original author:
Frederico de Souza Araujo - fred.the.master@gmail.com
http://www.frederico-araujo.com
Usurper:
Adam Michel - elfurbe@furbism.com
http://www.furbism.com
Originally based on:
thin_process_memory -
A munin plugin to monitor memory size of
each individual thin process
by Ben VandenBos and Avvo, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#%# family=auto
#%# capabilities=autoconf
=end
module Munin
class ThinThreads
def run
instances = get_pids()
instances.each do |instance|
@ -71,7 +76,6 @@ module Munin
def autoconf
get_pids().length > 0
end
end
end

View File

@ -1,47 +1,52 @@
#!/usr/bin/env ruby
# thin_peak_memory -
# A munin plugin for Linux to monitor the maximum memory size
# that an each individual thin process has reached
#
# For Linux ONLY !
# DOES NOT WORK on OSX, Solaris or BSD.
# only linux, because this script relies on proc filesystem
#
# Author:
# Frederico de Souza Araujo - fred.the.master@gmail.com
# http://www.frederico-araujo.com
#
# Based on:
# thin_process_memory -
# A munin plugin to monitor memory size of
# each individual thin process
# by Ben VandenBos and Avvo, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#
=begin
thin_peak_memory -
A munin plugin for Linux to monitor the maximum memory size
that an each individual thin process has reached
For Linux ONLY !
DOES NOT WORK on OSX, Solaris or BSD.
only linux, because this script relies on proc filesystem
Author:
Frederico de Souza Araujo - fred.the.master@gmail.com
http://www.frederico-araujo.com
Based on:
thin_process_memory -
A munin plugin to monitor memory size of
each individual thin process
by Ben VandenBos and Avvo, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#%# family=auto
#%# capabilities=autoconf
=end
module Munin
class ThinPeakMemory
def run
instances = get_pids()
instances.each do |instance|
pid, port = instance.split("|")
hwm = (pid_hwm(pid).to_i)/1024
hwm = (pid_hwm(pid).to_i) / 1024
puts "thin_#{port}.value #{hwm}"
end
end
@ -69,7 +74,6 @@ module Munin
def autoconf
get_pids().length > 0
end
end
end

View File

@ -32,7 +32,8 @@ module Munin
chunks = line.strip.split(/\s+/, 5)
pid, pcmd = chunks[0], chunks[4]
next if pid !~ /\A\d+\z/ or pcmd !~ /worker/
result << pid.to_i
result << pid.to_i
end
result
end
@ -48,7 +49,7 @@ module Munin
end
def memory_usage
result = { :master => {master_pid => nil}, :worker => {} }
result = { :master => { master_pid => nil }, :worker => {} }
ps_output = `ps auxw | grep unicorn`
ps_output.split("\n").each do |line|
chunks = line.strip.split(/\s+/, 11)

View File

@ -32,7 +32,8 @@ module Munin
chunks = line.strip.split(/\s+/, 5)
pid, pcmd = chunks[0], chunks[4]
next if pid !~ /\A\d+\z/ or pcmd !~ /worker/
result << pid.to_i
result << pid.to_i
end
result
end