Révision a345d90e
Initial version
| plugins/other/shorewall-accounting | ||
|---|---|---|
| 1 |
#!/usr/bin/python |
|
| 2 |
# shorewall_accounting v1.1 |
|
| 3 |
# |
|
| 4 |
# A munin plugin for tracking traffic as recorded by shorewall accounting rules. |
|
| 5 |
# See "man shorewall-accounting" for all possible accounting rules. |
|
| 6 |
# Basically this plugin examines the output of "shorewall -x show accounting". |
|
| 7 |
# See http://atlee.ca/blog/2006/01/20/munin-shorewall/ for a description of |
|
| 8 |
# the original script by Chris AtLee. |
|
| 9 |
# |
|
| 10 |
# Copyright 2010 Lars Kruse <devel@sumpralle.de> |
|
| 11 |
# Copyright 2006 Chris AtLee <chris@atlee.ca> |
|
| 12 |
# |
|
| 13 |
# Original publication: http://atlee.ca/blog/2006/01/20/munin-shorewall/ |
|
| 14 |
# Released under the GPL v3 |
|
| 15 |
|
|
| 16 |
import sys |
|
| 17 |
import commands |
|
| 18 |
import re |
|
| 19 |
|
|
| 20 |
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*$") |
|
| 21 |
KEY_ORDER = ["prot", "in", "out", "source", "destination", "details"] |
|
| 22 |
REPLACE_PATTERNS = {"prot": ("^all$", "allProt"),
|
|
| 23 |
"in": (r"^\*$", "allIn"), |
|
| 24 |
"out": (r"^\*$", "allOut"), |
|
| 25 |
"source": (r"^0\.0\.0\.0/0", "allSrc"), |
|
| 26 |
"destination": (r"^0\.0\.0\.0/0", "allDst"), |
|
| 27 |
"details": (r"^multiport\s+", ""), |
|
| 28 |
} |
|
| 29 |
|
|
| 30 |
|
|
| 31 |
def get_accounting_rule_fieldname(regdict): |
|
| 32 |
items = [] |
|
| 33 |
# filter and clean all requested keys |
|
| 34 |
for key in KEY_ORDER: |
|
| 35 |
raw = regdict[key] |
|
| 36 |
pattern, replacement = REPLACE_PATTERNS[key] |
|
| 37 |
value = re.sub(pattern, replacement, raw).strip() |
|
| 38 |
if value: |
|
| 39 |
items.append(value) |
|
| 40 |
result = "_".join(items) |
|
| 41 |
# clean the fieldname: http://munin-monitoring.org/wiki/notes_on_datasource_names |
|
| 42 |
result = re.sub(r"^[^A-Za-z_]", "_", result) |
|
| 43 |
result = re.sub(r"[^A-Za-z0-9_]", "_", result) |
|
| 44 |
return result |
|
| 45 |
|
|
| 46 |
def get_bytes_by_chain(): |
|
| 47 |
status, output = commands.getstatusoutput("shorewall -x show accounting")
|
|
| 48 |
if status != 0: |
|
| 49 |
raise OSError("Error running command (%s)[%i]: %s" % (trafficCmd, status, output))
|
|
| 50 |
chains = {}
|
|
| 51 |
for line in output.splitlines(): |
|
| 52 |
m = ACCOUNTING_LINE_EXP.match(line) |
|
| 53 |
if m is not None: |
|
| 54 |
target = get_accounting_rule_fieldname(m.groupdict()) |
|
| 55 |
bytes = int(m.group(1)) |
|
| 56 |
if target in chains: |
|
| 57 |
chains[target] += bytes |
|
| 58 |
else: |
|
| 59 |
chains[target] = bytes |
|
| 60 |
retval = [] |
|
| 61 |
names = chains.keys() |
|
| 62 |
names.sort() |
|
| 63 |
for name in names: |
|
| 64 |
retval.append((name, chains[name])) |
|
| 65 |
return retval |
|
| 66 |
|
|
| 67 |
if len(sys.argv) > 1: |
|
| 68 |
if sys.argv[1] == "autoconf": |
|
| 69 |
print "yes" |
|
| 70 |
sys.exit(0) |
|
| 71 |
elif sys.argv[1] == "config": |
|
| 72 |
print "graph_title Shorewall accounting" |
|
| 73 |
print "graph_category network" |
|
| 74 |
print "graph_vlabel bits per ${graph_period}"
|
|
| 75 |
for chain, bytes in get_bytes_by_chain(): |
|
| 76 |
print "%s.min 0" % chain |
|
| 77 |
print "%s.type DERIVE" % chain |
|
| 78 |
print "%s.label %s" % (chain, chain) |
|
| 79 |
print "%s.cdef %s,8,*" % (chain, chain) |
|
| 80 |
sys.exit(0) |
|
| 81 |
|
|
| 82 |
for chain, bytes in get_bytes_by_chain(): |
|
| 83 |
print "%s.value %i" % (chain, bytes) |
|
| 84 |
|
|
Formats disponibles : Unified diff