mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-21 18:41:03 +00:00
updated shorewall-accounting_ to v1.3
* renamed plugin file from "shorewall_accounting" to "shorewall-accounting_" * CAUTION: rename your symlinks and plugin config section! * added optional SHOREWALL_BIN environment variable * improved labels for rules (don't mask dots)
This commit is contained in:
parent
ea382ede4e
commit
265e39e038
1 changed files with 59 additions and 28 deletions
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# shorewall_accounting v1.2
|
# shorewall_accounting v1.3
|
||||||
#
|
#
|
||||||
# A munin plugin for tracking traffic as recorded by shorewall accounting rules.
|
# A munin plugin for tracking traffic as recorded by shorewall accounting rules.
|
||||||
# See "man shorewall-accounting" for all possible accounting rules.
|
# See "man shorewall-accounting" for all possible accounting rules.
|
||||||
|
@ -7,31 +7,44 @@
|
||||||
# See http://atlee.ca/blog/2006/01/20/munin-shorewall/ for a description of
|
# See http://atlee.ca/blog/2006/01/20/munin-shorewall/ for a description of
|
||||||
# the original script by Chris AtLee.
|
# the original script by Chris AtLee.
|
||||||
#
|
#
|
||||||
# Copyright 2010 Lars Kruse <devel@sumpralle.de>
|
# Copyright 2010-2012 Lars Kruse <devel@sumpralle.de>
|
||||||
# Copyright 2006 Chris AtLee <chris@atlee.ca>
|
# Copyright 2006 Chris AtLee <chris@atlee.ca>
|
||||||
#
|
#
|
||||||
# Original publication: http://atlee.ca/blog/2006/01/20/munin-shorewall/
|
# Original publication: http://atlee.ca/blog/2006/01/20/munin-shorewall/
|
||||||
# Released under the GPL v3
|
# Released under the GPL v3 or later
|
||||||
#
|
#
|
||||||
# You can use symlinks of this script according to the following pattern:
|
# You can use symlinks of this script according to the following pattern:
|
||||||
# shorewall_accounting_prot: use only rules with a specific protocol
|
# shorewall-accounting_prot: use only rules with a specific protocol
|
||||||
# shorewall_accounting_in: use only rules with a specific input interface
|
# shorewall-accounting_in: use only rules with a specific input interface
|
||||||
# shorewall_accounting_out: use only rules with a specific output interface
|
# shorewall-accounting_out: use only rules with a specific output interface
|
||||||
# shorewall_accounting_source: use only rules with a specific source IP
|
# shorewall-accounting_source: use only rules with a specific source IP
|
||||||
# shorewall_accounting_destination: use only rules with a specific destination IP
|
# shorewall-accounting_destination: use only rules with a specific destination IP
|
||||||
# shorewall_accounting_details: use only rules with specific details (e.g. a port)
|
# shorewall-accounting_details: use only rules with specific details (e.g. a port)
|
||||||
#
|
#
|
||||||
# Here "specific" means: non-default (e.g. a protocol was specified).
|
# Here "specific" means: non-default (e.g. a protocol was specified).
|
||||||
# Combinations are allowed:
|
# Combinations are allowed:
|
||||||
# shorewall_accounting_prot_in_source: use only rules with a specific protocol, input interface and source IP
|
# shorewall-accounting_prot_in_source: use only rules with a specific protocol, input interface and source IP
|
||||||
#
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# SHOREWALL_BIN - defaults to /sbin/shorewall
|
||||||
|
#
|
||||||
|
# Changelog:
|
||||||
|
# v1.3 - 2012/04/02
|
||||||
|
# * renamed plugin file from "shorewall_accounting" to "shorewall-accounting_"
|
||||||
|
# * CAUTION: rename your symlinks and plugin config section!
|
||||||
|
# * added optional SHOREWALL_BIN environment variable
|
||||||
|
# * improved labels for rules (don't mask dots)
|
||||||
|
#
|
||||||
|
#%# family=auto
|
||||||
|
#%# capabilities=autoconf
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import commands
|
import commands
|
||||||
import re
|
import re
|
||||||
|
|
||||||
PLUGIN_BASE_NAME = "shorewall_accounting"
|
PLUGIN_BASE_NAME = "shorewall-accounting"
|
||||||
|
SHOREWALL_BIN = os.environ.get("SHOREWALL_BIN", "/sbin/shorewall")
|
||||||
ACCOUNTING_LINE_EXP = re.compile(r"^\s*\d+\s+(\d+)\s+(?P<prot>\w+)\s+(?P<opt>[\w-]+)\s+(?P<in>[\w*]+)\s+(?P<out>[\w*]+)\s+(?P<source>[\w./+-]+)\s+(?P<destination>[\w./+-]+)\s*(?P<details>.*)\s*$")
|
ACCOUNTING_LINE_EXP = re.compile(r"^\s*\d+\s+(\d+)\s+(?P<prot>\w+)\s+(?P<opt>[\w-]+)\s+(?P<in>[\w*]+)\s+(?P<out>[\w*]+)\s+(?P<source>[\w./+-]+)\s+(?P<destination>[\w./+-]+)\s*(?P<details>.*)\s*$")
|
||||||
KEY_ORDER = ["prot", "in", "out", "source", "destination", "details"]
|
KEY_ORDER = ["prot", "in", "out", "source", "destination", "details"]
|
||||||
FILTER_PATTERNS = {
|
FILTER_PATTERNS = {
|
||||||
|
@ -52,7 +65,7 @@ REPLACE_PATTERNS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_accounting_rule_fieldname(regdict):
|
def get_accounting_rule_fieldname_and_label(regdict):
|
||||||
items = []
|
items = []
|
||||||
# filter and clean all requested keys
|
# filter and clean all requested keys
|
||||||
for key in KEY_ORDER:
|
for key in KEY_ORDER:
|
||||||
|
@ -64,8 +77,10 @@ def get_accounting_rule_fieldname(regdict):
|
||||||
result = "_".join(items)
|
result = "_".join(items)
|
||||||
# clean the fieldname: http://munin-monitoring.org/wiki/notes_on_datasource_names
|
# clean the fieldname: http://munin-monitoring.org/wiki/notes_on_datasource_names
|
||||||
result = re.sub(r"^[^A-Za-z_]", "_", result)
|
result = re.sub(r"^[^A-Za-z_]", "_", result)
|
||||||
result = re.sub(r"[^A-Za-z0-9_]", "_", result)
|
fieldname = re.sub(r"[^A-Za-z0-9_]", "_", result)
|
||||||
return result
|
# keep dots (for IP addresses)
|
||||||
|
label = re.sub(r"[^A-Za-z0-9_\.]", "_", result)
|
||||||
|
return fieldname, label
|
||||||
|
|
||||||
def is_wanted(regdict, filter_list):
|
def is_wanted(regdict, filter_list):
|
||||||
for item in filter_list:
|
for item in filter_list:
|
||||||
|
@ -78,9 +93,11 @@ def is_wanted(regdict, filter_list):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_bytes_by_chain(filter_list):
|
def get_bytes_by_chain(filter_list):
|
||||||
status, output = commands.getstatusoutput("shorewall -x show accounting")
|
status, output = commands.getstatusoutput("'%s' -x show accounting" \
|
||||||
|
% SHOREWALL_BIN)
|
||||||
if status != 0:
|
if status != 0:
|
||||||
raise OSError("Error running command (%s)[%i]: %s" % (trafficCmd, status, output))
|
raise OSError("Error running command (%s)[%i]: %s" % (SHOREWALL_BIN,
|
||||||
|
status, output))
|
||||||
chains = {}
|
chains = {}
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
m = ACCOUNTING_LINE_EXP.match(line)
|
m = ACCOUNTING_LINE_EXP.match(line)
|
||||||
|
@ -88,20 +105,22 @@ def get_bytes_by_chain(filter_list):
|
||||||
# check if this line was filtered
|
# check if this line was filtered
|
||||||
if not is_wanted(m.groupdict(), filter_list):
|
if not is_wanted(m.groupdict(), filter_list):
|
||||||
continue
|
continue
|
||||||
target = get_accounting_rule_fieldname(m.groupdict())
|
fieldname, label = get_accounting_rule_fieldname_and_label(m.groupdict())
|
||||||
bytes = int(m.group(1))
|
bytes = int(m.group(1))
|
||||||
if target in chains:
|
if fieldname in chains:
|
||||||
chains[target] += bytes
|
chains[fieldname][1] += bytes
|
||||||
else:
|
else:
|
||||||
chains[target] = bytes
|
chains[fieldname] = [label, bytes]
|
||||||
retval = []
|
retval = []
|
||||||
names = chains.keys()
|
names = chains.keys()
|
||||||
names.sort()
|
names.sort()
|
||||||
for name in names:
|
for name in names:
|
||||||
retval.append((name, chains[name]))
|
retval.append((name, chains[name][0], chains[name][1]))
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
|
# extract the filters from the symlink's name
|
||||||
|
# (e.g. "shorewall-accounting_in_out_details" -> in, out, details)
|
||||||
call_name = os.path.basename(sys.argv[0])
|
call_name = os.path.basename(sys.argv[0])
|
||||||
if call_name.startswith(PLUGIN_BASE_NAME):
|
if call_name.startswith(PLUGIN_BASE_NAME):
|
||||||
suffix = call_name[len(PLUGIN_BASE_NAME):]
|
suffix = call_name[len(PLUGIN_BASE_NAME):]
|
||||||
|
@ -113,19 +132,31 @@ else:
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
if sys.argv[1] == "autoconf":
|
if sys.argv[1] == "autoconf":
|
||||||
print "yes"
|
status, output = commands.getstatusoutput("'%s' -x show accounting" \
|
||||||
sys.exit(0)
|
% SHOREWALL_BIN)
|
||||||
|
if (status != 0) or not output:
|
||||||
|
print "no"
|
||||||
|
else:
|
||||||
|
print "yes"
|
||||||
elif sys.argv[1] == "config":
|
elif sys.argv[1] == "config":
|
||||||
print "graph_title Shorewall accounting"
|
if not filter_list:
|
||||||
|
title_addon = "all"
|
||||||
|
else:
|
||||||
|
title_addon = " / ".join(filter_list)
|
||||||
|
print "graph_title Shorewall accounting: %s" % title_addon
|
||||||
print "graph_category network"
|
print "graph_category network"
|
||||||
print "graph_vlabel bits per ${graph_period}"
|
print "graph_vlabel bits per ${graph_period}"
|
||||||
for chain, bytes in get_bytes_by_chain(filter_list):
|
for chain, label, bytes in get_bytes_by_chain(filter_list):
|
||||||
|
label = " ".join([item for item in label.split("_")
|
||||||
|
if not item.lower().startswith("all")])
|
||||||
|
if not label:
|
||||||
|
label = "all"
|
||||||
print "%s.min 0" % chain
|
print "%s.min 0" % chain
|
||||||
print "%s.type DERIVE" % chain
|
print "%s.type DERIVE" % chain
|
||||||
print "%s.label %s" % (chain, chain)
|
print "%s.label %s" % (chain, label)
|
||||||
print "%s.cdef %s,8,*" % (chain, chain)
|
print "%s.cdef %s,8,*" % (chain, chain)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
for chain, bytes in get_bytes_by_chain(filter_list):
|
for chain, label, bytes in get_bytes_by_chain(filter_list):
|
||||||
print "%s.value %i" % (chain, bytes)
|
print "%s.value %i" % (chain, bytes)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue