1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-24 18:07:20 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Dave Fennell 2013-02-22 17:12:49 +00:00
commit cdda2d6bf2
65 changed files with 3666 additions and 159 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.*.swp

View file

@ -1,2 +1,4 @@
Please **don't** put screenshots of your plugins here.
Put them right next to your plugins.
The `t-shirt/` subdir contains a t-shirt vector gfx.

View file

@ -0,0 +1,7 @@
# T-Shirt subproject
Some t-shirts
![logo-horizontal-tshirt-black-modified.svg](logo-horizontal-tshirt-black-modified.svg "logo-horizontal-tshirt-black-modified.svg")
![logo-shirt-black.svg](logo-shirt-black.svg "logo-shirt-black.svg")
![logo-horizontal-tshirt-black.svg](logo-horizontal-tshirt-black.svg "logo-horizontal-tshirt-black.svg")

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="577.81pt"
height="151pt"
id="svg1487"
style="display:inline">
<defs
id="defs3" />
<g
id="layer2"
style="display:inline">
<text
x="20.50548"
y="237.45724"
id="text3189"
xml:space="preserve"
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"><tspan
x="20.50548"
y="237.45724"
id="tspan3191">www.munin-monitoring.org</tspan></text>
</g>
<g
id="layer1"
style="display:inline">
<path
d="m 186.28371,0 26.02771,0 34.79055,99.10784 0.53278,0 L 282.16221,0 l 26.29472,0 0,187.1699 -27.09096,0 0,-113.82421 -0.53279,0 -26.82398,80.44291 -13.54474,0 -26.56164,-80.44291 -0.53318,0 0,113.82421 -27.09056,0 0,-187.1699"
id="path1495"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
d="m 424.00186,145.1112 c 0,24.4486 -19.65331,43.6388 -43.82268,43.6388 -24.16977,0 -43.82772,-19.1902 -43.82772,-43.6388 l 0,-145.1112 27.09445,0 0,142.484 c 0,13.1438 7.17067,19.4529 16.73211,19.4529 9.55796,0 16.73211,-6.3091 16.73211,-19.4529 l 0,-142.484 27.09096,0 0,145.1112"
id="path1497"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
d="m 450.83049,0 26.02422,0 40.90418,112.77324 0.52931,0 0,-112.77324 27.09482,0 0,187.1699 -25.49919,0 -41.43693,-112.51062 -0.52931,0 0,112.51062 -27.09057,0 0,-187.1699"
id="path1499"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
d="m 573.00328,187.1699 27.09483,0 0,-187.1699 -27.09483,0 0,187.1699 z"
id="path1501"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
d="m 627.72224,0 26.03234,0 40.89918,112.77324 0.53318,0 0,-112.77324 27.08708,0 0,187.1699 -25.49535,0 -41.43617,-112.51062 -0.53317,0 0,112.51062 -27.08709,0 0,-187.1699"
id="path1503"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
d="m 157.17279,167.28866 0,-0.71001 -1.395,0 -1.16301,0.91401 0,-0.50801 -1.39401,0 0,-3.86206 -1.16101,0 0,-3.55605 -0.698,0 0,-0.71101 -1.16301,0 0,4.47107 -1.625,0 0,3.45505 -1.74402,0 0,-1.06902 -0.928,0.40801 -1.278,0.55901 -0.93,0 0,1.62502 -1.85902,0 0,-1.31802 0,-2.03503 0,-2.44003 -1.394,0 0,-1.01602 -1.39601,0 0,-4.57407 -1.39301,0 0,4.57407 -0.69701,0.305 0,5.33608 -1.27699,0 -1.27801,0.56101 -1.39601,0 -1.16201,-0.508 -2.09101,0 0,-1.22102 -1.396,0 0,1.93203 -1.16001,0 0,1.32002 -0.93301,0 0,0.86301 -2.08701,0 0.004,0.002 0,-0.56001 -0.934,0 0,-7.31711 -0.92801,0 0,-4.98007 -0.582,-0.25401 0,-3.30305 -1.046,0 0,7.82612 -0.93101,0 0,7.92812 -0.92601,0 0,0.66001 -1.15899,0 0,-0.66001 -0.93402,0 0,-4.16806 -0.697,0 0,-4.87908 -0.697,0 0,-15.44323 -0.46501,0 0,-7.21311 -1.162,0 0,9.85215 -0.92901,0 0,20.0213 -0.698,0.30701 0,1.52302 -0.927,0 0,-1.42402 -0.466,0 0,-2.64004 -1.16201,0 0,-1.62703 -0.931,0 0,3.04905 -0.69501,0 0,0.81201 -0.93001,0 0,-1.52302 -1.161,0 0,1.72602 -1.62701,0 0,1.72703 -1.39401,0 0,-4.67407 -0.583,-0.254 0,-5.02908 -1.74,0 0,4.16606 -1.163815,0.50801 0,5.84309 -0.693904,0 0,-17.53126 0,-8.23213 -0.699003,0 0,-10.05515 -0.696704,0 0,8.53113 -0.930905,0 0,17.78327 -0.695803,0 0,0.91601 -0.696804,0 0,4.67407 0,2.64304 -0.930905,0 0,-2.54104 -1.160905,0 0,-3.86206 0,-7.92512 -1.394807,0 0,-10.46715 -0.580804,-0.25401 0,6.6541 -1.742908,0 0,4.16607 0,7.72511 -0.698003,0 0,2.23604 -0.929005,0.407 0,3.96206 0,1.17002 -1.157905,0 0,-5.64009 -0.700004,0 0,-10.06315 0,-5.18107 -0.698003,0 0,12.19518 -1.159907,0 0,6.5041 -0.695803,0.306 0,-1.32202 -1.627909,0 0,0.81301 -0.930004,0 0,1.82803 -0.696703,0 0,-1.93003 -0.930905,0 0,-1.72802 -1.160906,0 0,0.91601 -0.350902,-0.155 0,1.47502 -0.986805,0.43201 0,1.09301 -1.130806,0.49401 0,-1.71403 -1.482907,0 0,-1.21901 -0.699003,0 0,-1.62703 -1.392807,0 0,-1.62702 -0.698004,0 0,-2.64104 -1.160906,0 0,-5.89409 -1.161905,0 0,7.72211 -1.161906,0 0,2.44004 -0.928905,0.40601 0,3.04904 -0.696803,0 0,1.06802 -0.926705,0 0,-6.04709 -0.700004,-0.30601 0,-6.19709 -1.161905,0 0,-6.6081 -0.698904,0 0,-17.04125 -1.160906,0 0,14.19521 -0.699003,0 0,10.77416 -0.929005,0 0,0.81201 -0.928904,0 0,4.47307 -1.393807,0 0,5.38508 0,0.56001 -1.159907,0 0,-0.96502 -1.164805,0 0,-0.81401 -1.160907,0 0,-2.03303 -1.626007,0 0,-10.06115 -1.162806,0 0,-12.60119 -1.393807,0 0,10.67016 -0.930005,0 0,-1.82803 -1.160806,0 0,-9.24913 -0.582802,-0.25301 0,-5.91509 -1.044006,0 0,8.20213 -1.161805,0 0,9.34714 -0.930005,0 0,6.6081 -0.928905,0 0,5.89408 -0.465802,0 0,-2.33803 -1.394807,0 0,3.04904 -1.627009,0 0,-1.83002 -1.160805,0 0,3.45705 -1.393807,0 0,-2.33804 -1.393807,0 0,0.91402 -1.161906,0 0,1.42402 -1.161906,0 0,0.66001 -1.391807,0 0,-1.77903 -1.629908,0 0,1.77903 -2.08791,0 0,-0.76301 -1.164807,0 0,0.76301 -2.08791,0 0,-0.86501 -0.933804,0 0,-1.32002 -1.160907,0 0,-1.93203 -1.394806,0 0,1.22102"
id="path1493"
style="fill:none;stroke:#33ff00;stroke-width:5.6692915;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
<path
d="m 20.6738,186.09538 0,-49.07278"
id="path1505"
style="fill:none;stroke:#ffffff;stroke-width:5.6692915;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 20.673816,85.401045 0,-84.98218412 137.380864,0 0,185.67650912"
id="path1507"
style="fill:none;stroke:#ffffff;stroke-width:5.6692915;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 20.685718,186.08346 136.899462,0"
id="path1506"
style="fill:none;stroke:#ffffff;stroke-width:5.6692915;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
<g
id="layer5"
style="display:inline">
<path
d="m 150.98661,4.673964 c -8.02702,2.00604 -16.1875,10.499999 -16.1875,10.499999 l -0.0312,-4.96875 -10.8125,8.1875 2.1875,-6.09375 -4.3125,2.90625 c -5.24602,3.110051 -11.1875,4.34375 -11.1875,4.34375 -9.00608,0.558 -21.875002,11.4375 -21.875002,11.4375 1.564,-4.02906 0.4375,-12.34375 0.4375,-12.34375 -7.924821,15.51224 -23.024691,22.49399 -25.187501,23.375 -2.16799,0.878021 -13.53705,6.0811 -23.875,15.53125 -10.33087,9.441138 -13.625,25.25 -13.625,25.25 -0.8269,2.963051 -8.51748,7.918427 -12.0625,12.562497 -1.62181,2.12104 -10.7282498,13.50404 -13.9062498,27.40625 -2.69091,11.80218 0.71875,23.1875 0.71875,23.1875 1e-5,0 0.60302,4.29486 3.875,-3.40625 l 1.34375,-0.28125 c -2e-5,0 -1.64796,3.60201 -0.625,3.25 1.02196,-0.34801 6.8766698,-6.67817 11.6874998,-12.03125 4.81403,-5.35908 21.23212,-18.51374 36,-19.46875 3e-5,1e-5 10.01237,-3.80809 17.4375,2 -10e-6,0 4.90181,6.06651 12.46875,5.3125 0,0 0.893591,-0.23478 3.312501,1.40625 l -0.15625,-3.15625 c -2e-5,0 8.69196,5.10506 17.812502,1.5 l -1.59375,-2.28125 c 2e-5,0 1.63572,-2.4293 6.46875,0.84375 l 0.28125,-2.125 c -1e-5,0 8.58898,4.55425 13,4.40625 l -1.21875,-3.875 c -1e-5,0 9.11495,-1.28774 18.125,-1.84375 -3e-5,1e-5 11.21896,-2.40088 18.625,5.78125 L 157.95536,4.986464 c -2.43202,3.644049 -8.53125,3.65625 -8.53125,3.65625 l 1.5625,-3.96875 z m -2.15625,11.781249 c 0.30768,-0.0019 0.59984,0.0032 0.90625,0.03125 0.61239,30.71488 0.19406,61.437788 0.34375,92.156247 -4.43767,-0.86814 -9.03202,-0.89682 -13.53125,-0.40625 -6.00069,1.63687 -12.43999,0.74844 -18.46875,2.25 -1.93045,2.93308 -3.79544,-0.0504 -6.03125,-0.90625 -5.19701,-0.65769 -12.400042,-0.0109 -15.468752,4.78125 -5.04423,0.0604 -11.05987,-6.69356 -16.000001,-1.84375 -3.45199,-0.50355 -6.65879,-4.85355 -10.4375,-6.09375 -15.2541,-4.13316 -31.47762,1.75445 -44.3125,10.03125 -7.08338,4.20124 -12.83599,9.99487 -17.9687498,16.21875 -0.52947,-12.30318 6.2764598,-25.89958 15.4999998,-34.84375 6.19405,-4.60439 10.81446,-11.100291 12.75,-18.718747 4.14068,-16.616159 20.84858,-24.344848 34.71875,-31.75 2.37116,-0.17373 5.98042,-5.949259 7.21875,-2.21875 4.82953,3.168169 9.366091,-3.210088 13.062501,-5.5625 6.33872,-6.698589 14.589632,-10.711729 23.343752,-13.125 1.85901,2.640213 5.98596,4.36193 9.25,2.21875 2.71412,-2.249268 1.69963,0.682747 2.09375,2.78125 0.3559,7.492393 5.29921,-2.088697 8.09375,-3.90625 4.67065,-3.574764 7.46396,-10.786316 14,-11.0625 0.30661,-0.02032 0.62982,-0.02932 0.9375,-0.03125 z"
id="path2397"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="38.004967"
inkscape:export-xdpi="38.004967"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
sodipodi:docname="logo-horizontal-tshirt-black.svg"
inkscape:version="0.47 r22583"
sodipodi:version="0.32"
id="svg1487"
height="151pt"
width="577.81pt"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
style="display:inline">
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 94.375 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="722.26251 : 94.375 : 1"
inkscape:persp3d-origin="361.13126 : 62.916667 : 1"
id="perspective2459" />
<inkscape:perspective
id="perspective3555"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
inkscape:window-y="0"
inkscape:window-x="-1"
inkscape:window-height="756"
inkscape:window-width="1280"
inkscape:guide-bbox="true"
showguides="true"
inkscape:current-layer="layer5"
inkscape:document-units="px"
inkscape:cy="65.030992"
inkscape:cx="360.8944"
inkscape:zoom="1.2438444"
inkscape:pageshadow="2"
inkscape:pageopacity="1"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#000000"
id="base"
showgrid="false"
inkscape:window-maximized="1" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="URL"
style="display:inline">
<text
xml:space="preserve"
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
x="20.50548"
y="237.45724"
id="text3189"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3191"
x="20.50548"
y="237.45724">www.munin-monitoring.org</tspan></text>
</g>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Logo"
style="display:inline">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 186.28371,0 26.02771,0 34.79055,99.10784 0.53278,0 L 282.16221,0 l 26.29472,0 0,187.1699 -27.09096,0 0,-113.82421 -0.53279,0 -26.82398,80.44291 -13.54474,0 -26.56164,-80.44291 -0.53318,0 0,113.82421 -27.09056,0 0,-187.1699"
id="path1495"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 424.00186,145.1112 c 0,24.4486 -19.65331,43.6388 -43.82268,43.6388 -24.16977,0 -43.82772,-19.1902 -43.82772,-43.6388 l 0,-145.1112 27.09445,0 0,142.484 c 0,13.1438 7.17067,19.4529 16.73211,19.4529 9.55796,0 16.73211,-6.3091 16.73211,-19.4529 l 0,-142.484 27.09096,0 0,145.1112"
id="path1497"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 450.83049,0 26.02422,0 40.90418,112.77324 0.52931,0 0,-112.77324 27.09482,0 0,187.1699 -25.49919,0 -41.43693,-112.51062 -0.52931,0 0,112.51062 -27.09057,0 0,-187.1699"
id="path1499"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 573.00328,187.1699 27.09483,0 0,-187.1699 -27.09483,0 0,187.1699 z"
id="path1501"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 627.72224,0 26.03234,0 40.89918,112.77324 0.53318,0 0,-112.77324 27.08708,0 0,187.1699 -25.49535,0 -41.43617,-112.51062 -0.53317,0 0,112.51062 -27.08709,0 0,-187.1699"
id="path1503"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
id="path1493"
d="m 157.17279,167.28866 0,-0.71001 -1.395,0 -1.16301,0.91401 0,-0.50801 -1.39401,0 0,-3.86206 -1.16101,0 0,-3.55605 -0.698,0 0,-0.71101 -1.16301,0 0,4.47107 -1.625,0 0,3.45505 -1.74402,0 0,-1.06902 -0.928,0.40801 -1.278,0.55901 -0.93,0 0,1.62502 -1.85902,0 0,-1.31802 0,-2.03503 0,-2.44003 -1.394,0 0,-1.01602 -1.39601,0 0,-4.57407 -1.39301,0 0,4.57407 -0.69701,0.305 0,5.33608 -1.27699,0 -1.27801,0.56101 -1.39601,0 -1.16201,-0.508 -2.09101,0 0,-1.22102 -1.396,0 0,1.93203 -1.16001,0 0,1.32002 -0.93301,0 0,0.86301 -2.08701,0 0.004,0.002 0,-0.56001 -0.934,0 0,-7.31711 -0.92801,0 0,-4.98007 -0.582,-0.25401 0,-3.30305 -1.046,0 0,7.82612 -0.93101,0 0,7.92812 -0.92601,0 0,0.66001 -1.15899,0 0,-0.66001 -0.93402,0 0,-4.16806 -0.697,0 0,-4.87908 -0.697,0 0,-15.44323 -0.46501,0 0,-7.21311 -1.162,0 0,9.85215 -0.92901,0 0,20.0213 -0.698,0.30701 0,1.52302 -0.927,0 0,-1.42402 -0.466,0 0,-2.64004 -1.16201,0 0,-1.62703 -0.931,0 0,3.04905 -0.69501,0 0,0.81201 -0.93001,0 0,-1.52302 -1.161,0 0,1.72602 -1.62701,0 0,1.72703 -1.39401,0 0,-4.67407 -0.583,-0.254 0,-5.02908 -1.74,0 0,4.16606 -1.163815,0.50801 0,5.84309 -0.693904,0 0,-17.53126 0,-8.23213 -0.699003,0 0,-10.05515 -0.696704,0 0,8.53113 -0.930905,0 0,17.78327 -0.695803,0 0,0.91601 -0.696804,0 0,4.67407 0,2.64304 -0.930905,0 0,-2.54104 -1.160905,0 0,-3.86206 0,-7.92512 -1.394807,0 0,-10.46715 -0.580804,-0.25401 0,6.6541 -1.742908,0 0,4.16607 0,7.72511 -0.698003,0 0,2.23604 -0.929005,0.407 0,3.96206 0,1.17002 -1.157905,0 0,-5.64009 -0.700004,0 0,-10.06315 0,-5.18107 -0.698003,0 0,12.19518 -1.159907,0 0,6.5041 -0.695803,0.306 0,-1.32202 -1.627909,0 0,0.81301 -0.930004,0 0,1.82803 -0.696703,0 0,-1.93003 -0.930905,0 0,-1.72802 -1.160906,0 0,0.91601 -0.350902,-0.155 0,1.47502 -0.986805,0.43201 0,1.09301 -1.130806,0.49401 0,-1.71403 -1.482907,0 0,-1.21901 -0.699003,0 0,-1.62703 -1.392807,0 0,-1.62702 -0.698004,0 0,-2.64104 -1.160906,0 0,-5.89409 -1.161905,0 0,7.72211 -1.161906,0 0,2.44004 -0.928905,0.40601 0,3.04904 -0.696803,0 0,1.06802 -0.926705,0 0,-6.04709 -0.700004,-0.30601 0,-6.19709 -1.161905,0 0,-6.6081 -0.698904,0 0,-17.04125 -1.160906,0 0,14.19521 -0.699003,0 0,10.77416 -0.929005,0 0,0.81201 -0.928904,0 0,4.47307 -1.393807,0 0,5.38508 0,0.56001 -1.159907,0 0,-0.96502 -1.164805,0 0,-0.81401 -1.160907,0 0,-2.03303 -1.626007,0 0,-10.06115 -1.162806,0 0,-12.60119 -1.393807,0 0,10.67016 -0.930005,0 0,-1.82803 -1.160806,0 0,-9.24913 -0.582802,-0.25301 0,-5.91509 -1.044006,0 0,8.20213 -1.161805,0 0,9.34714 -0.930005,0 0,6.6081 -0.928905,0 0,5.89408 -0.465802,0 0,-2.33803 -1.394807,0 0,3.04904 -1.627009,0 0,-1.83002 -1.160805,0 0,3.45705 -1.393807,0 0,-2.33804 -1.393807,0 0,0.91402 -1.161906,0 0,1.42402 -1.161906,0 0,0.66001 -1.391807,0 0,-1.77903 -1.629908,0 0,1.77903 -2.08791,0 0,-0.76301 -1.164807,0 0,0.76301 -2.08791,0 0,-0.86501 -0.933804,0 0,-1.32002 -1.160907,0 0,-1.93203 -1.394806,0 0,1.22102"
style="fill:none;stroke:#33ff00;stroke-width:1.50116241;stroke-linecap:round;stroke-linejoin:round"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:none;stroke:#ffffff;stroke-width:1.50116313;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 20.6738,186.09538 0,-49.07278"
id="path1505"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:none;stroke:#ffffff;stroke-width:1.50117779;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 20.673816,85.401045 0,-84.98218412 137.380864,0 0,185.67650912"
id="path1507"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
<path
style="fill:none;stroke:#ffffff;stroke-width:1.52499998;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 20.685718,186.08346 136.899462,0"
id="path1506"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
</g>
<g
inkscape:groupmode="layer"
id="layer5"
inkscape:label="Raven"
style="display:inline">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
d="m 150.98661,4.673964 c -8.02702,2.00604 -16.1875,10.499999 -16.1875,10.499999 l -0.0312,-4.96875 -10.8125,8.1875 2.1875,-6.09375 -4.3125,2.90625 c -5.24602,3.110051 -11.1875,4.34375 -11.1875,4.34375 -9.00608,0.558 -21.875002,11.4375 -21.875002,11.4375 1.564,-4.02906 0.4375,-12.34375 0.4375,-12.34375 -7.924821,15.51224 -23.024691,22.49399 -25.187501,23.375 -2.16799,0.878021 -13.53705,6.0811 -23.875,15.53125 -10.33087,9.441138 -13.625,25.25 -13.625,25.25 -0.8269,2.963051 -8.51748,7.918427 -12.0625,12.562497 -1.62181,2.12104 -10.7282498,13.50404 -13.9062498,27.40625 -2.69091,11.80218 0.71875,23.1875 0.71875,23.1875 1e-5,0 0.60302,4.29486 3.875,-3.40625 l 1.34375,-0.28125 c -2e-5,0 -1.64796,3.60201 -0.625,3.25 1.02196,-0.34801 6.8766698,-6.67817 11.6874998,-12.03125 4.81403,-5.35908 21.23212,-18.51374 36,-19.46875 3e-5,1e-5 10.01237,-3.80809 17.4375,2 -10e-6,0 4.90181,6.06651 12.46875,5.3125 0,0 0.893591,-0.23478 3.312501,1.40625 l -0.15625,-3.15625 c -2e-5,0 8.69196,5.10506 17.812502,1.5 l -1.59375,-2.28125 c 2e-5,0 1.63572,-2.4293 6.46875,0.84375 l 0.28125,-2.125 c -1e-5,0 8.58898,4.55425 13,4.40625 l -1.21875,-3.875 c -1e-5,0 9.11495,-1.28774 18.125,-1.84375 -3e-5,1e-5 11.21896,-2.40088 18.625,5.78125 L 157.95536,4.986464 c -2.43202,3.644049 -8.53125,3.65625 -8.53125,3.65625 l 1.5625,-3.96875 z m -2.15625,11.781249 c 0.30768,-0.0019 0.59984,0.0032 0.90625,0.03125 0.61239,30.71488 0.19406,61.437788 0.34375,92.156247 -4.43767,-0.86814 -9.03202,-0.89682 -13.53125,-0.40625 -6.00069,1.63687 -12.43999,0.74844 -18.46875,2.25 -1.93045,2.93308 -3.79544,-0.0504 -6.03125,-0.90625 -5.19701,-0.65769 -12.400042,-0.0109 -15.468752,4.78125 -5.04423,0.0604 -11.05987,-6.69356 -16.000001,-1.84375 -3.45199,-0.50355 -6.65879,-4.85355 -10.4375,-6.09375 -15.2541,-4.13316 -31.47762,1.75445 -44.3125,10.03125 -7.08338,4.20124 -12.83599,9.99487 -17.9687498,16.21875 -0.52947,-12.30318 6.2764598,-25.89958 15.4999998,-34.84375 6.19405,-4.60439 10.81446,-11.100291 12.75,-18.718747 4.14068,-16.616159 20.84858,-24.344848 34.71875,-31.75 2.37116,-0.17373 5.98042,-5.949259 7.21875,-2.21875 4.82953,3.168169 9.366091,-3.210088 13.062501,-5.5625 6.33872,-6.698589 14.589632,-10.711729 23.343752,-13.125 1.85901,2.640213 5.98596,4.36193 9.25,2.21875 2.71412,-2.249268 1.69963,0.682747 2.09375,2.78125 0.3559,7.492393 5.29921,-2.088697 8.09375,-3.90625 4.67065,-3.574764 7.46396,-10.786316 14,-11.0625 0.30661,-0.02032 0.62982,-0.02932 0.9375,-0.03125 z"
id="path2397"
inkscape:export-filename="/home/dest/munin-propaganda/munin-logo.png"
inkscape:export-xdpi="105.81"
inkscape:export-ydpi="105.81" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="1088.0355"
height="1502.6995"
id="svg3212">
<defs
id="defs3214" />
<g
transform="translate(237.31866,49.651983)"
id="layer1">
<path
d="m 725.62855,915.82496 0,-4.08958 -8.03508,0 -6.69882,5.2646 0,-2.92608 -8.02935,0 0,-22.24509 -6.68732,0 0,-20.4825 -4.0204,0 0,-4.09535 -6.69884,0 0,25.75293 -9.35983,0 0,19.90075 -10.04539,0 0,-6.15745 -5.34517,2.35009 -7.36116,3.21984 -5.35672,0 0,9.35996 -10.70776,0 0,-7.59167 0,-11.72157 0,-14.05433 -8.02931,0 0,-5.85218 -8.04088,0 0,-26.34619 -8.02359,0 0,26.34619 -4.01473,1.75677 0,30.7353 -7.35533,0 -7.36121,3.23136 -8.04088,0 -6.69306,-2.92603 -12.04401,0 0,-7.03295 -8.04083,0 0,11.1283 -6.68154,0 0,7.60319 -5.37404,0 0,4.97085 -12.02097,0 0.023,0.0115 0,-3.2256 -5.37976,0 0,-42.14584 -5.34524,0 0,-28.68471 -3.35226,-1.46307 0,-19.02525 -6.02487,0 0,45.07768 -5.36252,0 0,45.6652 -5.33372,0 0,3.80159 -6.67566,0 0,-3.80159 -5.37987,0 0,-24.00762 -4.01466,0 0,-28.10302 -4.01465,0 0,-88.95148 -2.6784,0 0,-41.54681 -6.69302,0 0,56.74741 -5.351,0 0,115.32072 -4.02041,1.76835 0,8.77245 -5.33944,0 0,-8.20222 -2.6841,0 0,-15.20637 -6.69308,0 0,-9.37153 -5.36245,0 0,17.56222 -4.0032,0 0,4.6771 -5.35676,0 0,-8.77244 -6.68725,0 0,9.9417 -9.37142,0 0,9.94753 -8.02936,0 0,-26.92219 -3.35802,-1.46301 0,-28.96701 -10.02222,0 0,23.9961 -6.70347,2.92608 0,33.65563 -3.99682,0 0,-100.97833 0,-47.41626 -4.02617,0 0,-57.91668 -4.01297,0 0,49.13847 -5.36192,0 0,102.42989 -4.00774,0 0,5.27612 -4.01352,0 0,26.92219 0,15.22365 -5.36192,0 0,-14.63614 -6.68672,0 0,-22.24509 0,-45.64791 -8.03394,0 0,-60.28975 -3.34537,-1.46308 0,38.32697 -10.03899,0 0,23.99615 0,44.49587 -4.02042,0 0,12.87937 -5.35097,2.34428 0,22.82108 0,6.7392 -6.66942,0 0,-32.48637 -4.03196,0 0,-57.96275 0,-29.84245 -4.02044,0 0,70.24303 -6.68093,0 0,37.46298 -4.00777,1.76253 0,-7.6147 -9.37661,0 0,4.68285 -5.35681,0 0,10.52928 -4.01283,0 0,-11.11679 -5.36194,0 0,-9.95322 -6.68664,0 0,5.27612 -2.0213,-0.89278 0,8.49597 -5.6838,2.48833 0,6.29564 -6.51339,2.84544 0,-9.87264 -8.54133,0 0,-7.02138 -4.02633,0 0,-9.37153 -8.02224,0 0,-9.37148 -4.02055,0 0,-15.21213 -6.68663,0 0,-33.94937 -6.69242,0 0,44.47859 -6.69263,0 0,14.05439 -5.35037,2.33858 0,17.56217 -4.01348,0 0,6.15169 -5.33775,0 0,-34.83065 -4.03189,-1.76258 0,-35.69463 -6.69242,0 0,-38.06201 -4.02568,0 0,-98.15592 -6.68664,0 0,81.76301 -4.02632,0 0,62.0581 -5.35081,0 0,4.6771 -5.35059,0 0,25.76445 -8.02803,0 0,31.01753 0,3.2256 -6.68106,0 0,-5.55842 -6.70912,0 0,-4.68862 -6.68664,0 0,-11.71005 -9.36578,0 0,-57.95124 -6.69755,0 0,-72.58161 -8.02825,0 0,61.45907 -5.3568,0 0,-10.52927 -6.685987,0 0,-53.27408 -3.35691,-1.45731 0,-34.07034 -6.01337,0 0,47.24346 -6.69199,0 0,53.83861 -5.35658,0 0,38.062 -5.35038,0 0,33.94933 -2.68301,0 0,-13.46683 -8.03402,0 0,17.56217 -9.37135,0 0,-10.54073 -6.68621,0 0,19.91227 -8.02829,0 0,-13.46688 -8.028,0 0,5.26466 -6.6926,0 0,8.20222 -6.6924,0 0,3.80159 -8.0166998,0 0,-10.24704 -9.3881,0 0,10.24704 -12.0260002,0 0,-4.39486 -6.7094,0 0,4.39486 -12.0261,0 0,-4.98237 -5.3786,0 0,-7.60319 -6.6866,0 0,-11.1283 -8.0341,0 0,7.03295"
id="path1493"
style="fill:none;stroke:#33ff00;stroke-width:8.64561272;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline" />
<path
d="m -60.592257,1024.1498 0,-282.65436"
id="path1505"
style="fill:none;stroke:#ffffff;stroke-width:8.64655209;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline" />
<path
d="m -60.592057,444.16036 0,-489.489025 791.300197,0 0,1069.478465"
id="path1507"
style="fill:none;stroke:#ffffff;stroke-width:8.64663601;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline" />
<path
d="m -60.523557,1024.0812 788.527427,0"
id="path1506"
style="fill:none;stroke:#ffffff;stroke-width:8.78384972;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline" />
<path
d="m 689.99675,-20.819665 c -46.23484,11.5546003 -93.23842,60.4789 -93.23842,60.4789 l -0.17999,-28.6195 -62.27892,47.1592 12.59978,-35.0994 -24.83959,16.7397 c -30.21656,17.9136 -64.43889,25.0196 -64.43889,25.0196 -51.87414,3.214 -125.99786,65.878905 -125.99786,65.878905 9.00849,-23.207 2.51996,-71.098805 2.51996,-71.098805 -45.64619,89.348975 -132.61996,129.563175 -145.07755,134.637715 -12.48735,5.0573 -77.97203,35.02652 -137.517647,89.45846 -59.5046798,54.38002 -78.47868,145.43751 -78.47868,145.43751 -4.7628,17.06688 -49.0599,45.60937 -69.4787,72.35876 -9.341603,12.21697 -61.793703,77.78193 -80.098703,157.85729 -15.4995,67.9794 4.1398,133.55772 4.1398,133.55772 3e-4,0 3.4735,24.73797 22.3198,-19.61966 l 7.7398,-1.61998 c 0,0 -9.4921,20.74723 -3.6,18.71968 5.8864,-2.0045 39.6091,-38.4656 67.318803,-69.29881 27.7284,-30.86778 122.29508,-106.63733 207.356557,-112.1381 2.1e-4,7e-5 57.67036,-21.93421 100.43826,11.51982 0,0 28.23397,34.9425 71.81881,30.59947 0,0 5.14701,-1.35231 19.07968,8.09987 l -0.89998,-18.17969 c -1.1e-4,0 50.06484,29.40464 102.59826,8.63985 l -9.17984,-13.13978 c 1.1e-4,0 9.42159,-13.99253 37.25936,4.85992 l 1.61997,-12.23979 c -6e-5,0 49.47169,26.23203 74.87873,25.37957 l -7.01988,-22.31963 c -7e-5,0 52.50122,-7.41724 104.39821,-10.6198 -1.8e-4,4e-5 64.62011,-13.82884 107.27818,33.29942 L 730.13605,-19.019765 C 716.12787,1.9696353 680.99689,2.0399353 680.99689,2.0399353 l 8.99986,-22.8596003 z m -12.4198,67.8588 c 1.77221,-0.0111 3.45504,0.0186 5.21993,0.18 3.5273,176.914695 1.11776,353.875625 1.97997,530.810925 -25.56055,-5.0004 -52.02355,-5.16559 -77.93867,-2.33995 -34.5634,9.42821 -71.65313,4.31093 -106.3782,12.95978 -11.1192,16.89424 -21.86134,-0.29053 -34.7394,-5.21992 -29.93426,-3.78822 -71.42301,-0.0627 -89.09849,27.53953 -29.05427,0.34789 -63.70375,-38.55424 -92.15842,-10.61981 -19.88323,-2.90041 -38.35397,-27.95598 -60.11888,-35.0994 -87.86226,-23.8066 -181.308087,10.10546 -255.235847,57.779 -40.7995,24.19873 -73.933903,57.56947 -103.498103,93.41841 -3.0496,-70.86511 36.151703,-149.17904 89.278403,-200.69657 35.6771002,-26.52085 62.2903,-63.93659 73.4388,-107.81814 23.8498,-95.70745 120.085707,-140.22394 199.976467,-182.87689 13.65765,-1.00065 34.44671,-34.26712 41.57941,-12.77977 27.81761,18.24834 53.94775,-18.48979 75.2387,-32.03945 36.51041,-38.58321 84.03485,-61.69854 134.45771,-75.59874 10.70772,15.2074 34.47856,25.1243 53.2791,12.7798 15.63306,-12.9556 9.7897,3.9326 12.05979,16.01974 2.04996,43.15544 30.52294,-12.03064 46.61921,-22.49964 26.90247,-20.590305 42.99168,-62.128105 80.63862,-63.718905 1.76604,-0.117 3.62769,-0.1689 5.3999,-0.18 z"
id="path2397"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
<path
d="m -237.30925,1069.897 52.83458,0 70.6226,201.1826 1.08151,0 70.08854,-201.1826 53.376604,0 0,379.943 -54.992924,0 0,-231.0559 -1.08153,0 -54.45096,163.294 -27.49496,0 -53.91844,-163.294 -1.08231,0 0,231.0559 -54.99212,0 0,-379.943"
id="path1495"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
<path
d="m 245.24343,1364.4635 c 0,49.6291 -39.89496,88.584 -88.95724,88.584 -49.0631,0 -88.967476,-38.9549 -88.967476,-88.584 l 0,-294.5665 54.999976,0 0,289.2335 c 0,26.681 14.55602,39.4881 33.96511,39.4881 19.40205,0 33.96518,-12.8071 33.96518,-39.4881 l 0,-289.2335 54.99288,0 0,294.5665"
id="path1497"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
<path
d="m 299.70383,1069.897 52.82752,0 83.03286,228.9225 1.07444,0 0,-228.9225 55.00074,0 0,379.943 -51.76169,0 -84.11434,-228.3895 -1.07444,0 0,228.3895 -54.99213,0 0,-379.943"
id="path1499"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
<path
d="m 547.70678,1449.84 55.00074,0 0,-379.943 -55.00074,0 0,379.943 z"
id="path1501"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
<path
d="m 658.78276,1069.897 52.84399,0 83.02271,228.9225 1.08237,0 0,-228.9225 54.98502,0 0,379.943 -51.75395,0 -84.11275,-228.3895 -1.08231,0 0,228.3895 -54.98508,0 0,-379.943"
id="path1503"
style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

378
plugins/asterisk/asterisk Executable file
View file

@ -0,0 +1,378 @@
#!/usr/bin/perl -w
# -*- cperl -*-
=head1 NAME
asterisk - Multigraph-capable plugin to monitor Asterisk
=head1 NOTES
This plugin will produce multiple graphs showing:
- total number of active channels (replaces asterisk_channels),
together with breakdown of specific channel types (replaces
asterisk_channelstypes);
- the number of messages in all voicemail boxes (replaces
asterisk_voicemail);
- the number of active MeetMe conferences and users connected to them
(replace asterisk_meetme and asterisk_meetmeusers, respectively);
- the number of active channels for a given codec, for both SIP and
IAX2 channels (replaces asterisk_sipchannels and asterisk_codecs).
=head1 CONFIGURATION
The following configuration parameters are used by this plugin
[asterisk]
env.host - hostname to connect to
env.port - port number to connect to
env.username - username used for authentication
env.secret - secret used for authentication
env.channels - The channel types to look for
env.codecsx - List of codec IDs (hexadecimal values)
env.codecs - List of codecs names, matching codecsx order
The "username" and "secret" parameters are mandatory, and have no
defaults.
=head2 DEFAULT CONFIGURATION
[asterisk]
env.host 127.0.0.1
env.port 5038
env.channels Zap IAX2 SIP
env.codecsx 0x2 0x4 0x8
env.codecs gsm ulaw alaw
=head2 WILDCARD CONFIGURATION
It's possible to use the plugin in a virtual-node capacity, in which
case the host configuration will default to the hostname following the
underscore:
[asterisk_someserver]
env.host someserver
env.port 5038
=head1 AUTHOR
Copyright (C) 2005-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
Copyright (C) 2012 Diego Elio Pettenò <flameeyes@flameeyes.eu>
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=cut
use strict;
use Munin::Plugin;
use IO::Socket;
sub asterisk_command {
my ($socket, $command) = @_;
my $line, my $reply;
$socket->print("Action: command\nCommand: $command\n\n");
# Response: (Error|Follows|???)
$line = $socket->getline;
if ($line ne "Response: Follows\r\n") {
while ( $line = $socket->getline and $line ne "\r\n" ) {}
return undef;
}
# Privilege: Command
$line = $socket->getline;
# Until we get the --END COMMAND-- marker, it's the command's output.
while ( $line = $socket->getline and $line ne "--END COMMAND--\r\n" ) {
$reply .= $line;
}
# And then wait for the empty line that says we're done
while ( $line = $socket->getline and $line ne "\r\n" ) {}
return $reply;
}
$0 =~ /asterisk(?:_(.+))$/;
my $hostname = $1;
my $peeraddr = $ENV{'host'} || $hostname || '127.0.0.1';
my $peerport = $ENV{'port'} || '5038';
my $username = $ENV{'username'};
my $secret = $ENV{'secret'};
my @CHANNELS = exists $ENV{'channels'} ? split ' ',$ENV{'channels'} : qw(Zap IAX2 SIP);
my @CODECS = exists $ENV{'codecs'} ? split ' ',$ENV{'codecs'} : qw(gsm ulaw alaw);
my @CODECSX = exists $ENV{'codecsx'} ? split ' ',$ENV{'codecsx'} : qw(0x2 0x4 0x8);
my $line, my $error;
my $socket = new IO::Socket::INET(PeerAddr => $peeraddr,
PeerPort => $peerport,
Proto => 'tcp')
or $error = "Could not create socket: $!";
if ( $socket ) {
# This will consume the "Asterisk Call Manager" welcome line.
$socket->getline;
$socket->print("Action: login\nUsername: $username\nSecret: $secret\nEvents: off\n\n");
my $response_status = $socket->getline;
if ( $response_status ne "Response: Success\r\n" ) {
my $response_message = $socket->getline;
$response_message =~ s/Message: (.*)\r\n/$1/;
$error = "Asterisk authentication error: " . $response_message;
}
while ( $line = $socket->getline and $line ne "\r\n" ) {}
}
if ( $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
if ( $error ) {
print "no ($error)\n";
} else {
print "yes\n";
}
exit 0;
} elsif ( $ARGV[0] and $ARGV[0] eq 'config' ) {
print "host_name $hostname" if $hostname;
print <<END;
multigraph asterisk_channels
graph_title Asterisk active channels
graph_args --base 1000 -l 0
graph_vlabel channels
graph_category asterisk
total.label channels
END
foreach my $channel (@CHANNELS) {
print <<END;
$channel.draw AREASTACK
$channel.label $channel channels
END
}
print <<END;
multigraph asterisk_voicemail
graph_title Asterisk voicemail messages
graph_args --base 1000 -l 0
graph_vlabel messages
graph_category asterisk
messages.label Total messages
END
print <<END;
multigraph asterisk_meetme
graph_title Asterisk meetme statistics
graph_args --base 1000 -l 0
graph_category asterisk
users.label Connected users
conferences.label Active conferences
END
print <<END;
multigraph asterisk_codecs
graphs_title Asterisk channels per codec
graph_args --base 1000 -l 0
graph_vlabel channels
graph_category asterisk
END
foreach my $codec (@CODECS) {
print <<END;
$codec.draw AREASTACK
$codec.label $codec channels
END
}
print <<END;
other.draw AREASTACK
other.label Other known codecs
unknwon.draw AREASTACK
unknown.label Unknown codec
END
unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) {
exit 0;
}
}
# if we arrive here and we don't have a socket, it's time to exit.
die $error if $error;
my $channels_response = asterisk_command($socket, "core show channels");
#Channel Location State Application(Data)
#Zap/pseudo-198641660 s@frompstn:1 Rsrvd (None)
#Zap/1-1 4@frompstn:1 Up MeetMe(5500)
#2 active channels
#1 active call
my $voicemail_response = asterisk_command($socket, "voicemail show users");
#Context Mbox User Zone NewMsg
#default 1234 Example Mailbox 1
#other 1234 Company2 User 0
#2 voicemail users configured.
my $meetme_response = asterisk_command($socket, "meetme list");
#Conf Num Parties Marked Activity Creation
#5500 0001 N/A 00:00:03 Static
#* Total number of MeetMe users: 1
my $sipchannels_response = asterisk_command($socket, "sip show channels");
#Peer User/ANR Call ID Seq (Tx/Rx) Format
#192.168.1.135 yann 6902112b3e0 00101/00002 g729
#1 active SIP channel(s)
my $iaxchannels_response = asterisk_command($socket, "iax2 show channels");
#Channel Peer Username ID (Lo/Rem) Seq (Tx/Rx) Lag Jitter JitBuf Format
#IAX2/rodolphe@rodolp 10.8.53.6 rodolphe 00003/01287 00006/00004 00000ms 0148ms 0000ms gsm
#1 active IAX channel(s)
# After all the data is fetched we can proceed to process it, the
# connection can be closed as we don't need any more data.
$socket->close();
my $active_channels = 'U';
$active_channels = $1 if $channels_response =~ /\n([0-9]+) active channels/;
print <<END;
multigraph asterisk_channels
total.value $active_channels
END
my @channels_list = split(/\r\n/, $channels_response) if $channels_response;
foreach my $channel (@CHANNELS) {
print "$channel.value ";
print $channels_response ? scalar(grep(/^$channel\//, @channels_list)) : "U";
print "\n";
}
print "\nmultigraph asterisk_voicemail\n";
if ( !$voicemail_response or $voicemail_response =~ /no voicemail users/ ) {
print "total.value U\n";
} else {
my $messages = 0;
foreach my $line (split(/\r\n/, $voicemail_response)) {
next unless $line =~ / ([0-9]+)$/;
$messages += $1;
}
print "total.value $messages\n";
}
print "\nmultigraph asterisk_meetme\n";
if ( !$meetme_response ) {
print <<END;
users.value U
conferences.value U
END
} else {
if ( $meetme_response =~ /No active/ ) {
print <<END;
users.value 0
conferences.value 0
END
} else {
my @meetme_list = split(/\r\n/, $meetme_response);
my $users = pop(@meetme_list);
$users =~ s/^Total number of MeetMe users: ([0-9]+)$/$1/;
print "users.value $users\n";
print "conferences.value " . (scalar(@meetme_list)-1) . "\n";
}
}
print "\nmultigraph asterisk_codecs\n";
if ( !$sipchannels_response and !$iaxchannels_response ) {
foreach my $codec (@CODECS) {
print "$codec.value U\n";
}
print <<END;
other.value U
unknown.valeu U
END
} else {
my @results;
my ($i, $start, $unknown, $other)=(0,0,0,0);
foreach my $codec (@CODECS) {
$results[$i] = 0;
$i++;
}
# split the channels' listing and drop header and footnotes
my @sipchannels = $sipchannels_response ? split(/\r\n/, $sipchannels_response) : ();
pop(@sipchannels); shift(@sipchannels);
my @iaxchannels = $iaxchannels_response ? split(/\r\n/, $iaxchannels_response) : ();
pop(@iaxchannels); shift(@iaxchannels);
foreach my $sipchan (@sipchannels) {
my $found = 0;
my @fields = split ' ', $sipchan;
if ($fields[4] eq '0x0') {
$unknown += 1;
next;
}
foreach my $codec (@CODECSX) {
if ($fields[4] eq "$codec") {
$results[$i] = $results[$i] + 1;
$found = 1;
last;
}
$i++;
}
if (! $found) {
$other += 1;
print STDERR "CODEC: SIP other format $fields[4]\n" if $Munin::Plugin::DEBUG;
}
}
foreach my $iaxchan (@iaxchannels) {
my $found = 0;
my @fields = split ' ', $iaxchan;
if ($fields[8] eq '0x0') {
$unknown += 1;
next;
}
foreach my $codec (@CODECSX) {
if ($fields[8] eq "$codec") {
$results[$i] = $results[$i] + 1;
$found = 1;
last;
}
$i++;
}
if (! $found) {
$other += 1;
print STDERR "CODEC: IAX2 other format: $fields[8]\n" if $Munin::Plugin::DEBUG;
}
}
$i = 0;
foreach my $codec (@CODECS) {
print "$codec.value $results[$i]\n";
$i++;
}
print "other.value $other\n";
print "unknown.value $unknown\n";
}

37
plugins/db2/db2_cnx Executable file
View file

@ -0,0 +1,37 @@
#! /bin/sh
# (c) 2012 - Steve Schnepp - LGPL
# XXX - coded hastily
# Source the DB2 profile
. /home/db2inst1/sqllib/db2profile
echo "graph_title Number of connections"
echo "graph_category DB2"
echo "graph_args -l 0"
db2 list application | tail +5 | awk ' /^[A-Z]/ { print $1 }' | sort | uniq -c > $HOME/run/$(basename $0).txt
# Get users list
touch $HOME/run/$(basename $0).users
awk '{ print $2 }' $HOME/run/$(basename $0).txt | cat $HOME/run/$(basename $0).users - | sort -ru > $HOME/run/$(basename $0).users.tmp
mv $HOME/run/$(basename $0).users.tmp $HOME/run/$(basename $0).users
# Emit config
if [ "$1" = "config" ]
then
awk ' { print $1 ".label " $1 "\n" $1 ".draw AREASTACK" }' $HOME/run/$(basename $0).users
fi
# Emit values
for i in $( cat $HOME/run/$(basename $0).users )
do
TMPLINE=$(awk -v i=$i '($2 == i) { print }' $HOME/run/$(basename $0).txt)
if [ -z "$TMPLINE" ]
then
echo "$i.value 0"
else
echo "$TMPLINE" | awk ' { print $2 ".value " $1 }'
fi
done

View file

@ -180,7 +180,7 @@ case $name in
totalMemGpu=`echo "$totalMemGpus" | sed -n $(( $nGpusCounter + 1 ))p`
usedMemGpu=`echo "$usedMemGpus" | sed -n $(( $nGpusCounter + 1 ))p`
percentMemUsed=$(( $usedMemGpu * 100 / $totalMemGpu ))
valueGpus="${valueGpus}${percentMemUsed}\n"
valueGpus="${valueGpus}${percentMemUsed}"
: $(( nGpusCounter = $nGpusCounter + 1 ))
done
;;

View file

@ -10,7 +10,12 @@
=head1 CONFIGURATION
[http_request_time]
env.url http://127.0.0.1/1 http://127.0.0.1/2 http://127.0.0.1/3
env.url1 http://127.0.0.1/1
env.url2 http://127.0.0.1/2
env.url3 http://www.example.com
env.url3_name some_munin_internal_name
env.url3_label Some random page on our website
env.url3_proxy http://firewall:3128
=head1 MAGIC MARKERS
@ -41,7 +46,6 @@ sub clean {
return $surl;
};
if (! eval "require LWP::UserAgent;")
{
$ret = "LWP::UserAgent not found";
@ -50,12 +54,19 @@ if (! eval "require LWP::UserAgent;")
}
}
my $URL = $ENV{'url'}?$ENV{'url'}:"http://127.0.0.1/";
my %URLS;
foreach $_ (split(/ /,$URL)){
$URLS{$_}={
url=>$_,
surl=>clean($_),
for (my $i = 1; $ENV{"url$i"}; $i++)
{
my $url = $ENV{"url$i"};
my $proxy = $ENV{"url${i}_proxy"};
my $name = $ENV{"url${i}_name"} || clean($url);
my $label = $ENV{"url${i}_label"} || $url;
$URLS{$name}={
url=>$url,
proxy=>$proxy,
label=>$label,
time=>'U'
};
}
@ -94,50 +105,67 @@ if ( defined $ARGV[0] and $ARGV[0] eq "config" )
print "graph_category other\n";
my @go;
foreach my $url (values %URLS) {
print "$$url{'surl'}.label $$url{'url'}\n";
print "$$url{'surl'}.info The response time of a single request\n";
print "$$url{'surl'}.min 0\n";
print "$$url{'surl'}.draw LINE1\n";
push(@go,$$url{'surl'});
foreach my $name (keys %URLS) {
my $url = $URLS{$name};
print "$name.label $$url{'label'}\n";
print "$name.info The response time of a single request\n";
print "$name.min 0\n";
print "$name.draw LINE1\n";
push(@go, $name);
}
# multigraphs
foreach my $url (values %URLS) {
print "\nmultigraph http_request_time.$$url{'surl'}\n";
foreach my $name (keys %URLS) {
my $url = $URLS{$name};
print "\nmultigraph http_request_time.$name\n";
print "graph_title $$url{'url'}\n";
print "graph_args --base 1000\n";
print "graph_vlabel response time in ms\n";
print "graph_category other\n";
print "$$url{'surl'}.label $$url{'url'}\n";
print "$$url{'surl'}.info The response time of a single request\n";
print "$$url{'surl'}.min 0\n";
print "$$url{'surl'}.draw LINE1\n";
print "$name.label $$url{'label'}\n";
print "$name.info The response time of a single request\n";
print "$name.min 0\n";
print "$name.draw LINE1\n";
}
exit 0;
}
my $ua = LWP::UserAgent->new(timeout => 15);
foreach my $name (keys %URLS) {
my $url = $URLS{$name};
foreach my $url (values %URLS) {
my $t1=[gettimeofday];
if ($url->{proxy}) {
$ua->proxy(['http', 'ftp'], $url->{proxy});
}
else {
$ua->proxy(['http', 'ftp'], undef);
}
# warm up
my $response = $ua->request(HTTP::Request->new('GET',$$url{'url'}));
# timed run
my $t1=[gettimeofday];
$response = $ua->request(HTTP::Request->new('GET',$$url{'url'}));
my $t2=[gettimeofday];
if ($response->is_success) {
$$url{'time'}=sprintf("%d",tv_interval($t1,$t2)*1000);
};
};
print("multigraph http_request_time\n");
foreach my $url (values %URLS) {
print("$$url{'surl'}.value $$url{'time'}\n");
}
foreach my $url (values %URLS) {
print("\nmultigraph http_request_time.$$url{'surl'}\n");
print("$$url{'surl'}.value $$url{'time'}\n");
foreach my $name (keys %URLS) {
my $url = $URLS{$name};
print("$name.value $$url{'time'}\n");
}
foreach my $name (keys %URLS) {
my $url = $URLS{$name};
print("\nmultigraph http_request_time.$name\n");
print("$name.value $$url{'time'}\n");
}
# vim:syntax=perl

View file

@ -2,7 +2,11 @@
#
# Plugin to show amount of smtp-connections per hour
#
# Contributed by Håkon Nessjøen <lunatic@cpan.org>
# Contributed by Håkon Nessjøen <lunatic@cpan.org>
#
# Modified by Massimiliano Cianelli <massimiliano@cianelli.eu>
# 2013-02-02 - Added support for Greylist and simscan Virus\Spam detect
# Added LOGPATH env var
#
# Magic markers - optional - used by installation scripts and
# munin-config:
@ -10,6 +14,9 @@
#%# family=manual
#%# capabilities=autoconf
# get: env.logpath
LOGPATH=${logpath:-/var/log/qmail/qmail-smtpd/}
if [ "$1" = "autoconf" ]; then
echo yes
exit 0
@ -17,26 +24,41 @@ fi
if [ "$1" = "config" ]; then
echo 'graph_title Qmail SMTP connections'
echo 'graph_args --base 1000 -l 0 '
echo 'graph_vlabel connections/hour'
echo 'graph_category Mail'
echo 'graph_order rbl accepted total'
echo 'rbl.label RBL rejected connections'
echo 'rbl.min 0'
echo 'rbl.draw AREA'
echo 'accepted.label Accepted connections'
echo 'accepted.min 0'
echo 'accepted.draw STACK'
echo 'total.label Total connections'
echo 'total.min 0'
echo 'total.draw LINE1'
echo 'graph_title Qmail SMTP connections'
echo 'graph_args --base 1000 -l 0 '
echo 'graph_vlabel connections/hour'
echo 'graph_category mail'
echo 'graph_order rbl greylisted accepted simscan_spam simscan_virus total'
echo 'rbl.label RBL rejected connections'
echo 'rbl.min 0'
echo 'rbl.draw AREA'
echo 'greylisted.label Greylisted connections'
echo 'greylisted.min 0'
echo 'greylisted.draw STACK'
echo 'accepted.label Accepted connections'
echo 'accepted.min 0'
echo 'accepted.draw STACK'
echo 'simscan_spam.label Rejected SPAM'
echo 'simscan_spam.min 0'
echo 'simscan_spam.draw STACK'
echo 'simscan_virus.label Rejected VIRUS'
echo 'simscan_virus.min 0'
echo 'simscan_virus.draw STACK'
echo 'total.label Total connections'
echo 'total.min 0'
echo 'total.draw LINE1'
exit 0
fi
rbl=`cat /var/log/qmail/smtpd/@* /var/log/qmail/smtpd/current | grep -c rblsmtp`
accepted=`cat /var/log/qmail/smtpd/@* /var/log/qmail/smtpd/current | grep -c 'tcpserver: ok'`
rbl=`cat $LOGPATH/@* $LOGPATH/current | grep -c rblsmtp`
accepted=`cat $LOGPATH/@* $LOGPATH/current | grep -c 'tcpserver: ok'`
greylisted=`cat $LOGPATH/@* $LOGPATH/current | grep -ce "jgreylist\[[[:digit:]]\+\]: .\+\: GREY"`
simscan_spam=`cat $LOGPATH/@* $LOGPATH/current | grep -ce "simscan:\[[[:digit:]]\+\]:SPAM"`
simscan_virus=`cat $LOGPATH/@* $LOGPATH/current | grep -ce "simscan:\[[[:digit:]]\+\]:VIRUS"`
echo -n "rbl.value " && ( echo $rbl || echo U )
echo -n "accepted.value " && ( echo $accepted || echo U )
echo "total.value $[$rbl + $accepted]"
echo -n "greylisted.value " && ( echo $greylisted || echo U )
echo -n "simscan_spam.value " && ( echo $simscan_spam || echo U )
echo -n "simscan_virus.value " && ( echo $simscan_virus || echo U )
echo "total.value $(expr $rbl + $accepted + $greylisted)"

80
plugins/mysql/mysql_size_ondisk Executable file
View file

@ -0,0 +1,80 @@
#!/bin/bash
#
INFO=\
"mysql_size_ondisk - Munin plugin that reports the size of the files and
directories in /var/lib/mysql, biggest to smallest.
To correctly count InnoDB tables you should have innodb_file_per_table enabled
in MySQL (good practise anyway), otherwise all InnoDB tables will be counted into
ibdataX.
This plugin must be run as the user mysql, to do that append the following
to your /etc/munin/plugins/plugin-conf.d/munin-node:
[mysql_size_ondisk]
user mysql
This plugin gives you similar information as mysql_size_all. A difference
is that mysql_size_ondisk is much faster (0.4 seconds vs 14 seconds, on a server
with 170 databases, 26 GB total). Also note that mysql_size_all gives you the net
data size, mysql_size_ondisk gives you the gross storage space used, which may be
much more than your actual data."
#
# License: GPLv2 or later
#
# v1.0, 27.01.2012 Jakob Unterwurzacher <j.unterwurzacher@web-tech.at>
#%# family=auto
#%# capabilities=autoconf
set -eu
DIR=/var/lib/mysql
function clean {
# First character must not be a number
a=${1/#[0-9]/_}
# Other characters must be alphanumeric
b=${a//[^a-zA-Z0-9]/_}
echo $b
}
if [ "${1:-}" = "autoconf" ]
then
if du -sb $DIR &> /dev/null
then
echo "yes"
exit 0
else
echo "no"
exit 1
fi
elif [ "${1:-}" = "config" ]
then
echo "graph_title MySQL on-disk database size"
echo "graph_category mysql"
# graph_info cannot have newlines - replace by <br> which will be rendered to newlines in
# the web interface.
echo "graph_info ${INFO//$'\n'/<br>}"
echo "graph_args --base 1024 --lower-limit 0"
echo "graph_vlabel Bytes"
cd $DIR
du -sb * | sort -nr | while read s i
do
i=`clean $i`
echo "$i.label $i"
echo "$i.type GAUGE"
echo "$i.draw AREASTACK"
done
exit 0
elif [ "${1:-}" = "" ]
then
cd $DIR
du -sb * | sort -nr | while read s i
do
i=`clean $i`
echo "$i.value $s"
done
exit 0
else
echo "Unknown argument"
exit 1
fi

59
plugins/network/if1sec_ Executable file
View file

@ -0,0 +1,59 @@
#! /bin/sh
pluginfull="$0" # full name of plugin
plugin="${0##*/}" # name of plugin
pidfile="$MUNIN_PLUGSTATE/munin.$plugin.pid"
cache="$MUNIN_PLUGSTATE/munin.$plugin.value"
IFACE="${0##*/if1sec_}" # interface
if [ ! -r "/sys/class/net/$IFACE/statistics/tx_bytes" ]
then
echo "# Unknown Interface : $IFACE"
exit 1
fi
if [ "$1" = "acquire" ]
then
(
while sleep 1
do
echo $(
date +%s
cat /sys/class/net/$IFACE/statistics/tx_bytes
cat /sys/class/net/$IFACE/statistics/rx_bytes
)
done | awk "{
print \"${IFACE}_tx.value \" \$1 \":\" \$2;
print \"${IFACE}_rx.value \" \$1 \":\" \$3;
system(\"\");
}" >> $cache
) &
echo $! > $pidfile
exit 0
fi
if [ "$1" = "config" ]
then
cat <<EOF
graph_title Interface 1sec stats for ${IFACE}
graph_category 1sec::network
graph_data_size custom 1d, 10s for 1w, 1m for 1t, 5m for 1y
graph_vlabel Bytes
update_rate 1
${IFACE}_tx.label ${IFACE} TX bytes
${IFACE}_tx.type DERIVE
${IFACE}_tx.min 0
${IFACE}_rx.label ${IFACE} RX bytes
${IFACE}_rx.type DERIVE
${IFACE}_rx.min 0
EOF
exit 0
fi
# values
cat ${cache}
> ${cache}
exit 0

0
plugins/network/netatalk Normal file → Executable file
View file

View file

@ -164,6 +164,12 @@ for (my $host_i = 0; $host_i < @host_addrs; ++$host_i) {
my $h_norm_name = clean_fieldname($h_cur_name);
if ($config_mode) {
print "$h_norm_name.min 0\n$h_norm_name.label $h_cur_name\n$h_norm_name.draw LINE2\n";
my ( $warning, $critical ) =
get_thresholds($h_norm_name);
printf "%s.warning %s\n", $h_norm_name, $warning
if $warning;
printf "%s.critical %s\n", $h_norm_name, $critical
if $critical;
} else {
my $pid = $fork ? fork() : -1;
if ($pid <= 0) {

View file

@ -16,6 +16,8 @@
# tc - Override default program
# ignore_queue<n> - Queue with handle <n> not be plotted
# label_name<n> - Queue with handle <n> as defined label
# update_rate - Custom update_rate, to be used with async
# graph_data_size - Custom graph_data_size, to be used with async & custom update_rate
#
# Magic markers:
#%# family=manual
@ -100,6 +102,8 @@ if ( exists $ARGV[0] and $ARGV[0] eq 'config' ) {
print "graph_vlabel bits per \${graph_period}\n";
print "graph_category network\n";
print "graph_info This graph shows the QoS queue of the $IFACE network interface.\n";
print "update_rate $ENV{update_rate}\n" if $ENV{update_rate};
print "graph_data_size $ENV{graph_data_size}\n" if $ENV{graph_data_size};
print "graph_order ";
foreach my $key (sort by_handle keys %queues) {
$haschild = 0;

View file

@ -22,6 +22,8 @@ If trouble reading files, use:
=item 2012.09.20: Initial version by Arturo Borrero Gonzalez <aborrero@cica.es>
=item 2013.01.12: Added percentage graphing by Michiel Holtkamp <michiel@supermind.nl>
=back
=head1 LICENSE
@ -39,6 +41,7 @@ GPLv2
if [ "$1" == "config" ]
then
cat <<'EOF'
multigraph traffic
graph_title Throughput by IP protocol
graph_vlabel bits per ${graph_period}
graph_category network
@ -55,6 +58,32 @@ total.label Total bps
total.min 0
total.type DERIVE
total.draw LINE1
EOF
# Adapted from http://munin-monitoring.org/wiki/PercentGraphHowto
cat <<'EOF'
multigraph traffic_percent
graph_scale no
graph_title Throughput of IP protocols by percentage
graph_vlabel Percentage
graph_order IPv4=traffic.IPv4 IPv6=traffic.IPv6 total=traffic.total IPv4_percent=traffic.total IPv6_percent=traffic.total total_percent=traffic.total
graph_category network
graph_args --upper-limit 100 -l 0 -r
IPv4.label no
IPv6.label no
total.label no
total_percent.label no
IPv4.graph no
IPv6.graph no
total.graph no
total_percent.graph no
total_percent.cdef total,0.0000001,+
IPv4_percent.label IPv4
IPv4_percent.cdef IPv4,total_percent,/,100,*
IPv4_percent.draw AREASTACK
IPv6_percent.label IPv6
IPv6_percent.cdef IPv6,total_percent,/,100,*
IPv6_percent.draw AREASTACK
EOF
exit 0
fi

128
plugins/network/traffic_ipt Executable file
View file

@ -0,0 +1,128 @@
#!/bin/bash
# -*- bash -*-
: << =cut
=head1 NAME
traffic - Plugin to monitor the traffic (throughput) by IP protocols.
=head1 CONFIGURATION
To make this plugin work, you need to add rules to your firewall.
They are empty rules, we only use them to count traffic, not do anything
with them. To make this plugin work correctly, these rules have to
in the beginning of the chain(s), or else traffic that matches rules
above will not be counted (you can use this to your advantage of course).
The rules can be added with:
iptables -I INPUT
iptables -I OUTPUT
ip6tables -I INPUT
ip6tables -I OUTPUT
If trouble reading output, use:
[traffic_ipt]
user root
=head1 AUTHORS
=over
=item 2012.09.20: Initial version by Arturo Borrero Gonzalez <aborrero@cica.es>
=item 2013.01.12: Added percentage graphing by Michiel Holtkamp <michiel@supermind.nl>
=item 2013.02.03: Converted to use iptables/ip6tables by Michiel Holtkamp <michiel@supermind.nl>
=back
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=cut
if [ "$1" == "config" ]
then
cat <<'EOF'
multigraph traffic_ipt
graph_title Throughput by IP protocol
graph_vlabel bits per ${graph_period}
graph_category network
graph_args --base 1000 --upper-limit 100 -l 0
IPv4.label IPv4 bps
IPv4.min 0
IPv4.type DERIVE
IPv4.draw AREA
IPv6.label IPv6 bps
IPv6.min 0
IPv6.type DERIVE
IPv6.draw STACK
total.label Total bps
total.min 0
total.type DERIVE
total.draw LINE1
EOF
# Adapted from http://munin-monitoring.org/wiki/PercentGraphHowto
cat <<'EOF'
multigraph traffic_ipt_percent
graph_scale no
graph_title Throughput of IP protocols by percentage
graph_vlabel Percentage
graph_order IPv4=traffic_ipt.IPv4 IPv6=traffic_ipt.IPv6 total=traffic_ipt.total IPv4_percent=traffic_ipt.total IPv6_percent=traffic_ipt.total total_percent=traffic_ipt.total
graph_category network
graph_args --upper-limit 100 -l 0 -r
IPv4.label no
IPv6.label no
total.label no
total_percent.label no
IPv4.graph no
IPv6.graph no
total.graph no
total_percent.graph no
total_percent.cdef total,0.0000001,+
IPv4_percent.label IPv4
IPv4_percent.cdef IPv4,total_percent,/,100,*
IPv4_percent.draw AREASTACK
IPv6_percent.label IPv6
IPv6_percent.cdef IPv6,total_percent,/,100,*
IPv6_percent.draw AREASTACK
EOF
exit 0
fi
ipv4=0
ipv6=0
IPv4_bytes=$(iptables -L -n -v -x | egrep '^\W+[0-9]+\W+[0-9]+\W+all\W+--\W+\*\W+\*\W+0.0.0.0/0\W+0.0.0.0/0\W+$' | while read pkts bytes rest; do echo $bytes; done)
if [ -z "$IPv4_bytes" ];
then
echo "W: Unable to read rule from iptables, please add rules" >&2
else
ipv4=$(echo $IPv4_bytes | sed -e 's/ / + /' | bc -l)
fi
IPv6_bytes=$(ip6tables -L -n -v -x | egrep '^\W+[0-9]+\W+[0-9]+\W+all\W+\*\W+\*\W+::/0\W+::/0\W+$' | while read pkts bytes rest; do echo $bytes; done)
if [ -z "$IPv6_bytes" ];
then
echo "W: Unable to read rule from ip6tables, please add rules" >&2
else
ipv6=$(echo $IPv6_bytes | sed -e 's/ / + /' | bc -l)
fi
echo "IPv4.value $ipv4"
echo "IPv6.value $ipv6"
echo "total.value $( echo $ipv4 + $ipv6 | bc )"
exit 0

View file

@ -56,6 +56,7 @@ def main():
'transactions': ("Transactions", "Transactions",
('confirmed', 'waiting')),
'block_age': ("Last Block Age", "Seconds"),
'difficulty': ("Difficulty", ""),
}
labels = request_labels[request_var]
if len(labels) < 3:

48
plugins/qpid/qpid_bytedepth Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# Plugin to monitor Apache Qpid
# - graphs the number of outstanding bytes on queue(s) specified in config
#
# Parameters understood:
#
# queues (required) - space separated list of queues to display (regex allowed)
#
# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk)
#
# Licence: GPLv2
#
import re
import sys
import os
from qmf.console import Session
if not "queues" in os.environ:
print >> sys.stderr, "Missing env.queues in config"
sys.exit(-1)
output_queue = []
sess = Session()
broker = sess.addBroker()
queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker")
for q in queues:
for match in os.environ["queues"].split(" "):
if re.match(match, q.name):
output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name))
if len(sys.argv) > 1 and sys.argv[1] == "config":
print "graph_category Qpid";
print "graph_title Queue byte depth";
print "graph_vlabel bytes"
for queue in output_queue:
print "%s.label %s" % (queue, queue)
print "%s.min 0" % queue
print "%s.type GAUGE" % queue
else:
for q in queues:
qname = re.sub('[^a-zA-Z0-9_]', '_', q.name)
if qname in output_queue:
print "%s.value %u" % (qname, q.byteDepth)
sess.delBroker(broker)

48
plugins/qpid/qpid_discardsring Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# Plugin to monitor Apache Qpid
# - graphs the number of messages discarded from queue(s) specified in config
#
# Parameters understood:
#
# queues (required) - space separated list of queues to display (regex allowed)
#
# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk)
#
# Licence: GPLv2
#
import re
import sys
import os
from qmf.console import Session
if not "queues" in os.environ:
print >> sys.stderr, "Missing env.queues in config"
sys.exit(-1)
output_queue = []
sess = Session()
broker = sess.addBroker()
queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker")
for q in queues:
for match in os.environ["queues"].split(" "):
if re.match(match, q.name):
output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name))
if len(sys.argv) > 1 and sys.argv[1] == "config":
print "graph_category Qpid";
print "graph_title Ring queue discard rate";
print "graph_vlabel messages/second";
for queue in output_queue:
print "%s.label %s" % (queue, queue)
print "%s.min 0" % queue
print "%s.type COUNTER" % queue
else:
for q in queues:
qname = re.sub('[^a-zA-Z0-9_]', '_', q.name)
if qname in output_queue:
print "%s.value %u" % (qname, q.discardsRing)
sess.delBroker(broker)

48
plugins/qpid/qpid_enqueuebytes Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# Plugin to monitor Apache Qpid
# - graph ingest rate (bytes/sec) of queue(s) specified in config
#
# Parameters understood:
#
# queues (required) - space separated list of queues to display (regex allowed)
#
# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk)
#
# Licence: GPLv2
#
import re
import sys
import os
from qmf.console import Session
if not "queues" in os.environ:
print >> sys.stderr, "Missing env.queues in config"
sys.exit(-1)
output_queue = []
sess = Session()
broker = sess.addBroker()
queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker")
for q in queues:
for match in os.environ["queues"].split(" "):
if re.match(match, q.name):
output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name))
if len(sys.argv) > 1 and sys.argv[1] == "config":
print "graph_category Qpid";
print "graph_title Enqueue data rate";
print "graph_vlabel bytes/second"
for queue in output_queue:
print "%s.label %s" % (queue, queue)
print "%s.min 0" % queue
print "%s.type COUNTER" % queue
else:
for q in queues:
qname = re.sub('[^a-zA-Z0-9_]', '_', q.name)
if qname in output_queue:
print "%s.value %u" % (qname, q.byteTotalEnqueues)
sess.delBroker(broker)

48
plugins/qpid/qpid_enqueuecount Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# Plugin to monitor Apache Qpid
# - graphs ingest rate (messages/sec) of queue(s) specified in config
#
# Parameters understood:
#
# queues (required) - space separated list of queues to display (regex allowed)
#
# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk)
#
# Licence: GPLv2
#
import re
import sys
import os
from qmf.console import Session
if not "queues" in os.environ:
print >> sys.stderr, "Missing env.queues in config"
sys.exit(-1)
output_queue = []
sess = Session()
broker = sess.addBroker()
queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker")
for q in queues:
for match in os.environ["queues"].split(" "):
if re.match(match, q.name):
output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name))
if len(sys.argv) > 1 and sys.argv[1] == "config":
print "graph_category Qpid";
print "graph_title Enqueue message rate";
print "graph_vlabel messages/second"
for queue in output_queue:
print "%s.label %s" % (queue, queue)
print "%s.min 0" % queue
print "%s.type COUNTER" % queue
else:
for q in queues:
qname = re.sub('[^a-zA-Z0-9_]', '_', q.name)
if qname in output_queue:
print "%s.value %u" % (qname, q.msgTotalEnqueues)
sess.delBroker(broker)

48
plugins/qpid/qpid_msgdepth Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# Plugin to monitor Apache Qpid
# - graphs the number of outstanding messages on queue(s) specified in config
#
# Parameters understood:
#
# queues (required) - space separated list of queues to display (regex allowed)
#
# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk)
#
# Licence: GPLv2
#
import re
import sys
import os
from qmf.console import Session
if not "queues" in os.environ:
print >> sys.stderr, "Missing env.queues in config"
sys.exit(-1)
output_queue = []
sess = Session()
broker = sess.addBroker()
queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker")
for q in queues:
for match in os.environ["queues"].split(" "):
if re.match(match, q.name):
output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name))
if len(sys.argv) > 1 and sys.argv[1] == "config":
print "graph_category Qpid";
print "graph_title Queue message depth";
print "graph_vlabel messages"
for queue in output_queue:
print "%s.label %s" % (queue, queue)
print "%s.min 0" % queue
print "%s.type GAUGE" % queue
else:
for q in queues:
qname = re.sub('[^a-zA-Z0-9_]', '_', q.name)
if qname in output_queue:
print "%s.value %u" % (qname, q.msgDepth)
sess.delBroker(broker)

View file

@ -27,6 +27,11 @@ file:
env.user monitor
env.pass passw0rd
To create an account just for monitoring the ESXi, add a user to the host,
make it a member of the 'root' group, and give it the 'No access' role.
That will allow the account to connect via WBEM, but not via any of the
management tools.
In the event that not all sensor types are desired, the plugin can be limited
to a subset of the types available:

View file

@ -17,10 +17,29 @@ When used for the local host, the plugin should be linked as
non-wildcard plugin, i.e., 'freeipmi', whereas when used to monitor a
foreign host it should be, e.g., 'freeipmi_192.168.0.253'.
=head1 DEPENDENCIES
The plugin requires FreeIPMI 1.1.5 or later to fetch the information.
Limits set on thresholds are available when using FreeIPMI 1.2.0 or
later.
=head1 AUTHOR
Diego Elio Pettenò <flameeyes@flameeyes.eu>.
With help and suggestions of:
Bart ten Brinke <info@retrosync.com>
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 LICENSE
GPLv2
@ -42,12 +61,15 @@ my $IPMISENSORS = $ENV{'ipmisensors'} || 'ipmi-sensors';
$0 =~ /freeipmi(?:_(.+))$/;
my $hostname = $1;
$IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Voltage --output-sensor-thresholds";
my $help_output = `$IPMISENSORS --help`;
$IPMISENSORS .= " --output-sensor-thresholds" if $help_output =~ /--output-sensor-thresholds/;
$IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Voltage";
$IPMISENSORS .= " --hostname=$hostname" if defined($hostname);
$IPMISENSORS .= " --username=$ENV{IPMI_USERNAME}" if defined($ENV{IPMI_USERNAME});
$IPMISENSORS .= " --password=$ENV{IPMI_PASSWORD}" if defined($ENV{IPMI_PASSWORD});
my $output=`$IPMISENSORS --output-sensor-thresholds 2>/dev/null`;
my $output=`$IPMISENSORS 2>/dev/null`;
my $retval=$?;
if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
@ -109,11 +131,11 @@ foreach my $line (@data) {
value => $dataline[3],
label => $dataline[1]
);
$sensor{lwarn} = $dataline[7] ne "N/A" ? $dataline[7] : '';
$sensor{hwarn} = $dataline[8] ne "N/A" ? $dataline[8] : '';
$sensor{lwarn} = (defined($dataline[7]) and $dataline[7] ne "N/A") ? $dataline[7] : '';
$sensor{hwarn} = (defined($dataline[8]) and $dataline[8] ne "N/A") ? $dataline[8] : '';
$sensor{lcrit} = $dataline[6] ne "N/A" ? $dataline[6] : '';
$sensor{hcrit} = $dataline[9] ne "N/A" ? $dataline[9] : '';
$sensor{lcrit} = (defined($dataline[6]) and $dataline[6] ne "N/A") ? $dataline[6] : '';
$sensor{hcrit} = (defined($dataline[9]) and $dataline[9] ne "N/A") ? $dataline[9] : '';
my $type;
if ( $dataline[2] eq "Temperature" ) {
@ -158,7 +180,7 @@ END
}
}
unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) {
unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) {
exit 0;
}
}

View file

@ -173,7 +173,7 @@ END
}
}
unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) {
unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) {
exit 0;
}
}

View file

@ -0,0 +1,69 @@
#!/usr/bin/perl
#
# Munin plugins for Sick-Beard
#
# Copyright (C) 2012 - Blauwbek
# Copyright (C) 2012 - Thiago
#
# Sick-Beard : http://sickbeard.com/
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
#
# Requires: JSON::Any
# LWP::UserAgent
#
# Configuration example
# [sickbeard*]
# env.host http://host:port/
# env.api apikey
#
use strict;
use JSON::Any;
use LWP::UserAgent;
#defines
my $HOST = exists $ENV{'host'} ? $ENV{'host'} : "http://localhost:8081/";
my $API = exists $ENV{'api'} ? $ENV{'api'} : "";
my $URL = $HOST."/api/".$API."/?cmd=shows.stats";
my $sURL = sprintf $URL;
#config output
if(defined $ARGV[0] && $ARGV[0] eq 'config')
{
print <<EOC
graph_title Episodes
graph_vlabel Episodes
graph_category Sick-Beard
down.label Downloaded
total.label Total
EOC
;
exit 0;
}
my $get = LWP::UserAgent->new;
my $req = $get->get($sURL);
my $json = JSON::Any->jsonToObj($req->content());
if ($json->{result} eq 'success') {
print "down.value $json->{data}->{ep_downloaded}\n";
print "total.value $json->{data}->{ep_total}\n";
exit 0;
} else {
print "$json->{message}\n";
exit 1;
}

View file

@ -0,0 +1,69 @@
#!/usr/bin/perl
#
# Munin plugins for Sick-Beard
#
# Copyright (C) 2012 - Blauwbek
# Copyright (C) 2012 - Thiago
#
# Sick-Beard : http://sickbeard.com/
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
#
# Requires: JSON::Any
# LWP::UserAgent
#
# Configuration example
# [sickbeard*]
# env.host http://host:port/
# env.api apikey
#
use strict;
use JSON::Any;
use LWP::UserAgent;
#defines
my $HOST = exists $ENV{'host'} ? $ENV{'host'} : "http://localhost:8081/";
my $API = exists $ENV{'api'} ? $ENV{'api'} : "";
my $URL = $HOST."/api/".$API."/?cmd=shows.stats";
my $sURL = sprintf $URL;
#config output
if(defined $ARGV[0] && $ARGV[0] eq 'config')
{
print <<EOC
graph_title Shows
graph_vlabel Shows
graph_category Sick-Beard
active.label Active
total.label Total
EOC
;
exit 0;
}
my $get = LWP::UserAgent->new;
my $req = $get->get($sURL);
my $json = JSON::Any->jsonToObj($req->content());
if ($json->{result} eq 'success') {
print "active.value $json->{data}->{shows_active}\n";
print "total.value $json->{data}->{shows_total}\n";
exit 0;
} else {
print "$json->{message}\n";
exit 1;
}

106
plugins/system/cpu_by_process Executable file
View file

@ -0,0 +1,106 @@
#!/usr/bin/perl
#
# Copyright 2012 Chris Wilson
# Copyright 2006 Holger Levsen
#
# This plugin monitors ALL processes on a system. No exceptions. It can
# produce very big graphs! But if you want to know where your CPU time
# is going without knowing what to monitor in advance, this can help;
# or in addition to one of the more specific CPU plugins to monitor
# just Apache or MySQL, for example.
#
# It's not obvious what the graph heights actually mean, even to me.
# Each counter is a DERIVE (difference since the last counter reading)
# of the CPU time usage (in seconds) accounted to each process, summed
# by the process name, so all Apache and all MySQL processes are grouped
# together. Processes with no CPU usage at all are ignored. Processes
# that die may not appear on the graph, and anyway their last chunk of
# CPU usage before they died is lost. You could modify this plugin to
# read SAR/psacct records if you care about that.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#scriptname=`basename $0`
#vsname=`echo $scriptname | perl -ne '/^vserver_proc_VM_(.*)/ and print $1'`
#if [ "$1" = "suggest" ]; then
# ls -1 /etc/vservers
# exit 0
#elif [ -z "$vsname" ]; then
# echo "Must be used with a vserver name; try '$0 suggest'" >&2
# exit 2
#fi
use strict;
use warnings;
my $cmd = "ps -eo time,comm h";
open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!";
# my $header_line = <PS>;
my %total_cpu_by_process;
while (<PS>)
{
my @fields = split;
my $cputime = $fields[0];
my $process = $fields[1];
# remove any / and everything after it from the process name,
# e.g. kworker/0:2 -> kworker
$process =~ s|/.*||;
# remove any . at the end of the name (why does this appear?)
# $process =~ s|\.$||;
# change any symbol that's not allowed in a munin variable name to _
$process =~ tr|a-zA-Z0-9|_|c;
my @times = split /:/, $cputime;
$cputime = (($times[0] * 60) + $times[1]) * 60 + $times[2];
$total_cpu_by_process{$process} += $cputime;
}
foreach my $process (keys %total_cpu_by_process)
{
# remove all processes with 0 cpu time
if (not $total_cpu_by_process{$process})
{
delete $total_cpu_by_process{$process};
}
}
close(PS);
if (@ARGV and $ARGV[1] eq "config")
{
print <<END;
graph_title CPU time by Process
graph_args --base 1000
graph_vlabel seconds
graph_category system
graph_info Shows CPU time used by each process name
END
my $stack = 0;
sub draw() { return $stack++ ? "STACK" : "AREA" }
print map
{
"$_.label $_\n" .
"$_.min 0\n" .
"$_.type DERIVE\n" .
"$_.draw " . draw() . "\n"
} sort keys %total_cpu_by_process;
}
else
{
print map
{
"$_.value $total_cpu_by_process{$_}\n"
} sort keys %total_cpu_by_process;
}
exit(0);

0
plugins/system/membyuser Normal file → Executable file
View file

0
plugins/system/memory_by_process Normal file → Executable file
View file

View file

@ -25,8 +25,8 @@ run_watchdog() { # should also trap kill and term signals
run_acquire() {
echo "$$" > $pidfile
mpstat -P ALL $interval |
awk -v cpus=$cpus '$2>=0&&$2<10 {print $2, systime(), (100-$11)/cpus}' >> $cache
LANG=C mpstat -P ALL $interval |
awk -v cpus=$cpus '$2>=0&&$2<99 {print $2, systime(), (100-$11)/cpus; system("");}' >> $cache
rm -f $pidfile $cache
}

View file

@ -0,0 +1,105 @@
#!/usr/bin/perl
#
# Copyright 2012 Chris Wilson
# Copyright 2006 Holger Levsen
#
# This plugin monitors ALL processes on a system. No exceptions. It can
# produce very big graphs! But if you want to know which processes are
# killing your system by page faulting, without knowing what to monitor
# in advance, this can help; or in addition to one of the more specific
# plugins to monitor just Apache or MySQL, for example.
#
# Each counter is a DERIVE (difference since the last counter reading)
# of the number of major page faults, usually 4k each, read in by a
# process. Memory mapped files probably contribute to this. The process
# cannot continue until the page fault is served, so this is a
# high-priority read that usually indicates memory starvation.
# Processes with no page faults at all are ignored. Processes
# that die may not appear on the graph, and anyway their last chunk of
# CPU usage before they died is lost. You could modify this plugin to
# read SAR/psacct records if you care about that.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#scriptname=`basename $0`
#vsname=`echo $scriptname | perl -ne '/^vserver_proc_VM_(.*)/ and print $1'`
#if [ "$1" = "suggest" ]; then
# ls -1 /etc/vservers
# exit 0
#elif [ -z "$vsname" ]; then
# echo "Must be used with a vserver name; try '$0 suggest'" >&2
# exit 2
#fi
use strict;
use warnings;
my $cmd = "ps -eo maj_flt,comm h";
open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!";
# my $header_line = <PS>;
my %total_by_process;
while (<PS>)
{
my @fields = split;
my $value = $fields[0];
my $process = $fields[1];
# remove any / and everything after it from the process name,
# e.g. kworker/0:2 -> kworker
$process =~ s|/.*||;
# remove any . at the end of the name (why does this appear?)
# $process =~ s|\.$||;
# change any symbol that's not allowed in a munin variable name to _
$process =~ tr|a-zA-Z0-9|_|c;
$total_by_process{$process} += $value;
}
foreach my $process (keys %total_by_process)
{
# remove all processes with 0 faults
if (not $total_by_process{$process})
{
delete $total_by_process{$process};
}
}
close(PS);
if (@ARGV and $ARGV[1] eq "config")
{
print <<END;
graph_title Page faults by Process
graph_args --base 1000
graph_vlabel seconds
graph_category system
graph_info Shows number of major page faults caused by each process name
END
my $stack = 0;
sub draw() { return $stack++ ? "STACK" : "AREA" }
print map
{
"$_.label $_\n" .
"$_.min 0\n" .
"$_.type DERIVE\n" .
"$_.draw " . draw() . "\n"
} sort keys %total_by_process;
}
else
{
print map
{
"$_.value $total_by_process{$_}\n"
} sort keys %total_by_process;
}
exit(0);

119
plugins/system/total_by_process_ Executable file
View file

@ -0,0 +1,119 @@
#!/usr/bin/perl
#
# Copyright 2012 Chris Wilson
# Copyright 2006 Holger Levsen
#
# This plugin monitors ALL processes on a system. No exceptions. It can
# produce very big graphs! But if you want to know which processes are
# killing your system by page faulting, without knowing what to monitor
# in advance, this can help; or in addition to one of the more specific
# plugins to monitor just Apache or MySQL, for example.
#
# Each counter is a DERIVE (difference since the last counter reading)
# of the number of major page faults, usually 4k each, read in by a
# process. Memory mapped files probably contribute to this. The process
# cannot continue until the page fault is served, so this is a
# high-priority read that usually indicates memory starvation.
# Processes with no page faults at all are ignored. Processes
# that die may not appear on the graph, and anyway their last chunk of
# CPU usage before they died is lost. You could modify this plugin to
# read SAR/psacct records if you care about that.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
use strict;
use warnings;
my $scriptname = $0;
$scriptname =~ s|.*/||;
my $fieldname = ($scriptname =~ /^total_by_process_(.*)_(.*)/) ? $1 : undef;
my $fieldtype = ($scriptname =~ /^total_by_process_(.*)_(.*)/) ? $2 : undef;
if (@ARGV and $ARGV[1] eq "suggest")
{
system("ps L | cut -d' ' -f1");
exit(0);
}
if (!$fieldname)
{
print STDERR "Must be used with a PS format specifier name; try '$0 suggest'";
exit(2);
}
unless ($fieldtype =~ /^(GAUGE|DERIVE)$/)
{
print STDERR "Unknown field type $fieldtype: should be GAUGE or DERIVE";
exit(2);
}
my $cmd = "ps -eo $fieldname,comm h";
open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!";
# my $header_line = <PS>;
my %total_by_process;
while (<PS>)
{
my @fields = split;
my $value = $fields[0];
my $process = $fields[1];
# remove any / and everything after it from the process name,
# e.g. kworker/0:2 -> kworker
$process =~ s|/.*||;
# remove any . at the end of the name (why does this appear?)
# $process =~ s|\.$||;
# change any symbol that's not allowed in a munin variable name to _
$process =~ tr|a-zA-Z0-9|_|c;
$total_by_process{$process} += $value;
}
foreach my $process (keys %total_by_process)
{
# remove all processes with 0 faults
if (not $total_by_process{$process})
{
delete $total_by_process{$process};
}
}
close(PS);
if (@ARGV and $ARGV[1] == "config")
{
print <<END;
graph_title $fieldname by Process
graph_category system
graph_info Shows total of $fieldname (reported by ps) for each process name
graph_vlabel $fieldname (from ps)
END
# graph_args --base 1000
# graph_vlabel seconds
my $stack = 0;
sub draw() { return $stack++ ? "STACK" : "AREA" }
print map
{
"$_.label $_\n" .
"$_.min 0\n" .
"$_.type $fieldtype\n" .
"$_.draw " . draw() . "\n"
} sort keys %total_by_process;
}
else
{
print map
{
"$_.value $total_by_process{$_}\n"
} sort keys %total_by_process;
}
exit(0);

View file

@ -1,19 +1,21 @@
#!/bin/sh
# This plugin shows Solaris zone memory usage.
#%# family=auto
#%# capabilities=autoconf
PRSTAT=/usr/bin/prstat
PRSTAT_OPTS="-Z 1 1"
PRSTAT_OPTS="-Z -n 1,99 1 1"
if [ "$1" = 'autoconf' ]; then
if [ -f $PRSTAT ]; then
zones=`/usr/sbin/zoneadm list | wc -l`
if [ $zones -gt 1 ]; then
echo yes
else
echo yes
fi
zones=`/usr/sbin/zoneadm list | wc -l`
if [ $zones -gt 1 ]; then
echo yes
else
echo yes
fi
exit 0
else
echo no
@ -24,18 +26,18 @@ fi
if [ "$1" = 'config' ]; then
echo 'graph_title zone memory usage'
echo 'graph_args --upper-limit 100'
echo 'graph_category system'
stack=AREA
echo 'graph_category system'
stack=AREA
$PRSTAT $PRSTAT_OPTS | sed '1,/^ZONEID/d' | grep -v '^Total' | while read i; do
oIFS="$IFS"
IFS='
oIFS="$IFS"
IFS='
'
set -$- $i
name=$1
label=$8
set -$- $i
name=$1
label=$8
printf "$name.label $label\n$name.draw $stack\n$name.warn 95\n"
IFS="$oIFS"
stack=STACK
IFS="$oIFS"
stack=STACK
done
exit 0
fi
@ -48,12 +50,12 @@ fi
# Total: 207 processes, 709 lwps, load averages: 0.05, 0.06, 0.11$
$PRSTAT $PRSTAT_OPTS | sed '1,/^ZONEID/d' | grep -v '^Total' | while read i; do
oIFS="$IFS"
IFS='%
oIFS="$IFS"
IFS='%
'
set -$- $i
name=$1
value=$5
printf "$name.value $value\n"
IFS="$oIFS"
set -$- $i
name=$1
value=$5
printf "$name.value $value\n"
IFS="$oIFS"
done

View file

@ -21,7 +21,7 @@ $0 =~ /vdr_(.+)*$/;
my $host = $1 || "localhost";;
#print "Name: $0\nHost: $host\n";
my $SVDRPSENDPL="/usr/bin/svdrpsend.pl -d $host";
my $SVDRPSENDPL="/usr/bin/svdrpsend -d $host";
sub ermittelnTimer;
sub ermittelnAufnahmen;

View file

@ -19,6 +19,9 @@ configuration:
[xen-multi]
user root
env.xenskip "<space separated module list>"
Modules: cput, cpup, mem, disk, net
Then restart munin-node and you're done.
@ -34,10 +37,14 @@ NOTE: xentop always reports 0 for dom0's disk IOs and network traffic, but
both graphs show its entry all the same, so each domain can keep its own color
along the different graphs.
=head2 CPU usage
=head2 CPU time
This graph shows a percentage of the CPU time used by each domain.
=head2 CPU usage
This graph shows a percentage of the CPU percentage used by each domain.
=head2 Memory usage
This graph shows the amount of memory (in bytes) used by each domain.
@ -66,6 +73,7 @@ Michael Renner for the C<diskstats> plugin which I borrowed some code from.
=head1 AUTHOR
Raphael HALIMI <raphael.halimi@gmail.com>
Modified by Krisztian IVANCSO <github-ivan@ivancso.net>
=head1 LICENSE
@ -76,6 +84,8 @@ GPLv2
use strict;
use Munin::Plugin;
my $XEN_SKIP = $ENV{xenskip} || "";
# autoconf - quite simple
if ($ARGV[0] eq "autoconf") {
if (`which xentop`) {
@ -101,7 +111,7 @@ if ($ARGV[0] eq "autoconf") {
sub trim_label {
my ($type, $label) = @_; my $data_characters;
my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (400,97,10,6);
my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (497,3,5,6);
if ($type eq 'pos') {$data_characters = 32;} elsif ($type eq 'neg') {$data_characters = 64;} else {return $label;}
my $available_characters = abs(($graph_width+$graph_border_width)/$pixels_per_character)-$padding_characters-$data_characters;
@ -117,9 +127,9 @@ sub trim_label {
}
# Global variables
my (%domains,$domain,$munindomain,$cpusecs,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr);
my (%domains,$domain,@domainlist,$munindomain,$cpusecs,$cpupercent,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr);
open (XENTOP,"xentop -b -f -i1 |") or die "Could not execute xentop, $!";
open (XENTOP,"xentop -b -f -i2 |") or die "Could not execute xentop, $!";
# Now we build a hash of hashes to store information
while (<XENTOP>) {
@ -129,7 +139,7 @@ while (<XENTOP>) {
next if /^NAME/;
# We define only what we need
($domain,undef,$cpusecs,undef,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/);
($domain,undef,$cpusecs,$cpupercent,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/);
# We have to store the sanitised domain name in a separate variable
$domains{$domain}{'munindomain'} = clean_fieldname($domain);
@ -137,6 +147,7 @@ while (<XENTOP>) {
# We need the remaining data only for a normal run
if ($ARGV[0] eq "") {
$domains{$domain}{'cpusecs'} = $cpusecs;
$domains{$domain}{'cpupercent'} = $cpupercent;
$domains{$domain}{'mem'} = $memk;
$domains{$domain}{'nettx'} = $nettxk;
$domains{$domain}{'netrx'} = $netrxk;
@ -145,71 +156,94 @@ while (<XENTOP>) {
}
}
@domainlist = sort(keys(%domains));
#
# config - quite simple, too
#
if ($ARGV[0] eq "config") {
print "multigraph xen_cpu_time\n";
print "graph_title Xen domains CPU time\n";
print "graph_args --base 1000 -l 0\n";
print "graph_vlabel %\n";
print "graph_scale no\n";
print "graph_category xen\n";
print "graph_info This graph shows CPU time for each Xen domain.\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_cpu_time.label ".trim_label('pos',$domain)."\n";
print "$domains{$domain}{'munindomain'}_cpu_time.type DERIVE\n";
print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n";
print "$domains{$domain}{'munindomain'}_cpu_time.min 0\n";
print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n";
if ($XEN_SKIP !~ /cput/) {
print "multigraph xen_cpu_time\n";
print "graph_title Xen domains CPU time\n";
print "graph_args --base 1000 -l 0\n";
print "graph_vlabel cpu seconds\n";
print "graph_scale no\n";
print "graph_category xen\n";
print "graph_info This graph shows CPU time for each Xen domain.\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_cpu_time.label ".trim_label('pos',$domain)."\n";
print "$domains{$domain}{'munindomain'}_cpu_time.type DERIVE\n";
print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n";
print "$domains{$domain}{'munindomain'}_cpu_time.min 0\n";
print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n";
}
}
print "\nmultigraph xen_mem\n";
print "graph_title Xen domains memory usage\n";
print "graph_args --base 1024 -l 0\n";
print "graph_vlabel bytes\n";
print "graph_category xen\n";
print "graph_info This graph shows memory usage for each Xen domain.\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n";
print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n";
print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n";
if ($XEN_SKIP !~ /cpup/) {
print "\nmultigraph xen_cpu\n";
print "graph_title Xen domains CPU utilization\n";
print "graph_args --base 1000 -l 0 --upper-limit 100\n";
print "graph_vlabel %\n";
print "graph_scale no\n";
print "graph_category xen\n";
print "graph_info This graph shows CPU utilization for each Xen domain.\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_cpu.label ".trim_label('pos',$domain)."\n";
print "$domains{$domain}{'munindomain'}_cpu.draw AREASTACK\n"
}
}
print "\nmultigraph xen_net\n";
print "graph_title Xen domains network traffic\n";
print "graph_args --base 1000\n";
print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n";
print "graph_category xen\n";
print "graph_info This graph shows network traffic for each Xen domain.\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_netrx.label none\n";
print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n";
print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_netrx.graph no\n";
print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n";
print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n";
print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n";
print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n";
if ($XEN_SKIP !~ /mem/) {
print "\nmultigraph xen_mem\n";
print "graph_title Xen domains memory usage\n";
print "graph_args --base 1024 -l 0\n";
print "graph_vlabel bytes\n";
print "graph_category xen\n";
print "graph_info This graph shows memory usage for each Xen domain.\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n";
print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n";
print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n";
}
}
print "\nmultigraph xen_disk\n";
print "graph_title Xen domains disk IOs\n";
print "graph_args --base 1000\n";
print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n";
print "graph_category xen\n";
print "graph_info This graph shows disk IOs for each Xen domain.\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_vbdrd.label none\n";
print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n";
print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n";
print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n";
print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n";
if ($XEN_SKIP !~ /net/) {
print "\nmultigraph xen_net\n";
print "graph_title Xen domains network traffic\n";
print "graph_args --base 1000\n";
print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n";
print "graph_category xen\n";
print "graph_info This graph shows network traffic for each Xen domain.\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_netrx.label none\n";
print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n";
print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_netrx.graph no\n";
print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n";
print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n";
print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n";
print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n";
}
}
if ($XEN_SKIP !~ /disk/) {
print "\nmultigraph xen_disk\n";
print "graph_title Xen domains disk IOs\n";
print "graph_args --base 1000\n";
print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n";
print "graph_category xen\n";
print "graph_info This graph shows disk IOs for each Xen domain.\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_vbdrd.label none\n";
print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n";
print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n";
print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n";
print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n";
print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n";
}
}
exit 0;
@ -220,24 +254,40 @@ if ($ARGV[0] eq "config") {
# Normal run
#
print "multigraph xen_cpu_time\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n";
if ($XEN_SKIP !~ /cput/) {
print "multigraph xen_cpu_time\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n";
}
}
print "\nmultigraph xen_mem\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n";
if ($XEN_SKIP !~ /cpup/) {
print "\nmultigraph xen_cpu\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_cpu.value $domains{$domain}{'cpupercent'}\n";
}
}
print "\nmultigraph xen_net\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n";
print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n";
if ($XEN_SKIP !~ /mem/) {
print "\nmultigraph xen_mem\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n";
}
}
print "\nmultigraph xen_disk\n";
for $domain (sort(keys(%domains))) {
print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n";
print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n";
if ($XEN_SKIP !~ /net/) {
print "\nmultigraph xen_net\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n";
print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n";
}
}
if ($XEN_SKIP !~ /disk/) {
print "\nmultigraph xen_disk\n";
for $domain (@domainlist) {
print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n";
print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n";
}
}

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/python
"""
Plugin to monitor Wowza streaming servers.
@ -83,14 +83,14 @@ tree.parse(f)
f.close()
vhosts = []
for vh in tree.iter("VHost"):
for vh in tree.findall("VHost"):
if vh.find("Name").text not in vhost_exclude:
applications = []
for app in vh.iter("Application"):
for app in vh.findall("Application"):
if app.find("Name").text not in app_exclude:
if app.find("Status").text == "loaded":
clients = []
for client in app.iter("Client"):
for client in app.findall("Client"):
if client.find("IpAddress").text not in client_exclude:
clients.append({"ClientId": client.find("ClientId").text,
"FlashVersion": client.find("FlashVersion").text,
@ -289,7 +289,7 @@ elif plugin_name == "wowza_vhost_uptime":
elif plugin_name == "wowza_app_listeners":
for vh in vhosts:
for app in vh["Applications"]:
print (vh["Name"].strip("/").replace(".","_").replace("-","_"),"_",app["Name"].strip("/").replace(".","_").replace("-","_"),".value ",app["TimeRunning"],sep='')
print (vh["Name"].strip("/").replace(".","_").replace("-","_"),"_",app["Name"].strip("/").replace(".","_").replace("-","_"),".value ",app["ConnectionsCurrent"],sep='')
elif plugin_name == "wowza_app_duration":
alldurations = {}

117
plugins/xastir/xastir Executable file
View file

@ -0,0 +1,117 @@
#!/bin/bash
## Copyright (C) 2012 Robert Kilian <robertkilian@ostechnologies.net>
##
## This file is part of the Xastir plugin for Munin.
##
## Xastir-Munin is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public
## License as published by the Free Software Foundation;
## either version 3 of the License, or (at your option) any
## later version.
##
## Xastir-Munin 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 Xastir-Munin; see the file COPYING. If not,
## see <http://www.gnu.org/licenses/>.
##
## Version 0.1 -- 07.26.12
##
## Be sure to correctly edit the STATION_CALL, XASTIRDIR, and LOGDIR variables
##
## STATION_CALL: The callsign used by Xastir (include suffix if one is in use)
## XASTIRDIR: The directory where Xastir's data, config, etc files are found. Typically ~/.xastir
## LOGDIR: Logs are typically stored in ~/.xastir/logs. Ensure that permissions are set appropriately to allow the munin user to read these logs
# Location of active instance of Xastir
XASTIRDIR="/home/USERNAME/.xastir"
# Grab the station's callsign from Xastir config
# this currently does not derive the station call correctly when called by the server, but works using munin-run...
#STATION_CALL=`grep ^STATION_CALLSIGN:.* $XASTIRDIR/config/xastir.cnf | awk -F":" '{print $2}'`
STATION_CALL=""
# Location of Xastir's logs (this can be a symlink to where Xastir actually writes the logs)
LOGDIR="/var/log/xastir/logs"
case $1 in
config)
cat <<'EOM'
graph_title Xastir Packet Stats
graph_vlabel Packets
graph_category ham_radio
graph_scale no
graph_printf %.0lf
igatetonet.label IGate - RF to Net
igatetonet.type COUNTER
igatetonet.min 0
igatetonet.max 500
igatetonet.LINE1
message.label Message RX
message.type COUNTER
message.min 0
message.max 500
message.draw LINE1
messagetx.label Message TX
messagetx.type COUNTER
messagetx.min 0
messagetx.max 500
messagetx.draw LINE1
net.label Net RX
net.type COUNTER
net.min 0
net.max 500
net.draw LINE1
nettx.label Net TX
nettx.type COUNTER
nettx.min 0
nettx.max 500
nettx.draw LINE1
tnc.label TNC RX
tnc.type COUNTER
tnc.min 0
tnc.max 500
tnc.draw LINE1
tnctx.label TNC TX
tnctx.type COUNTER
tnctx.min 0
tnctx.max 500
tnctx.draw LINE1
EOM
exit 0;;
esac
# Parse logs for various values
IGATETONET=`cat $LOGDIR/igate.log | grep -e '^IGATE RF' | wc -l`
MESSAGE=`cat $LOGDIR/message.log | grep -v '^\#' | grep -v ^$STATION_CALL | wc -l`
MESSAGETX=`cat $LOGDIR/message.log | grep -v '^\#' | grep ^$STATION_CALL | wc -l`
NET=`cat $LOGDIR/net.log | grep -v '^\#' | grep -v ^$STATION_CALL | wc -l`
NETTX=`cat $LOGDIR/net.log | grep -v '^\#' | grep ^$STATION_CALL | wc -l`
TNC=`cat $LOGDIR/tnc.log | grep -v '^\#' | grep -v ^$STATION_CALL | wc -l`
TNCTX=`cat $LOGDIR/tnc.log | grep -v '^\#' | grep ^$STATION_CALL | wc -l`
# Display values
echo "igatetonet.value $IGATETONET"
echo "message.value $MESSAGE"
echo "messagetx.value $MESSAGETX"
echo "net.value $NET"
echo "nettx.value $NETTX"
echo "tnc.value $TNC"
echo "tnctx.value $TNCTX"

View file

@ -109,8 +109,10 @@ else
fi
L2_ACCESSES_TOTAL=`echo "$L2_HITS+$L2_MISSES" | $BC`
L2_HIT_RATIO_PERC=`echo "scale=2 ; (100*$L2_HITS/$L2_ACCESSES_TOTAL)" | $BC`
L2_MISS_RATIO_PERC=`echo "scale=2 ; (100*$L2_MISSES/$L2_ACCESSES_TOTAL)" | $BC`
if [ $L2_ACCESSES_TOTAL -gt 0 ]; then
L2_HIT_RATIO_PERC=`echo "scale=2 ; (100*$L2_HITS/$L2_ACCESSES_TOTAL)" | $BC`
L2_MISS_RATIO_PERC=`echo "scale=2 ; (100*$L2_MISSES/$L2_ACCESSES_TOTAL)" | $BC`
fi
efficiency() {
if [ "$1" = "config" ]; then

285
plugins/zfs/zfs_usage_ Executable file
View file

@ -0,0 +1,285 @@
#!/usr/local/bin/perl
# -*- perl
=pod
=head1 NAME
zfs_usage_ - Script to monitor zfs pool usage
=head1 CONFIGURATION
Create one symlink per zpool for exampe zfs_usage_system
=head1 BUGS
=head1 AUTHOR
2012, Claudius Herder
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf suggest
=head1 LICENSE
GPLv2
=cut
use strict;
use warnings;
use Munin::Plugin;
need_multigraph();
my $filesystems;
my $zpool;
my $zpoolexec="/sbin/zpool";
my $zfsexec="/sbin/zfs";
my $properties = {
available => "Read-only property that identifies the amount of disk"
." space available to a file system and all its children,"
." assuming no other activity in the pool. Because disk"
." space is shared within a pool, available space can be"
." limited by various factors including physical pool size,"
." quotas, reservations, and other datasets within the"
." pool.",
quota => "Limits the amount of disk space a file system and its"
." descendents can consume. This property enforces a"
." hard limit on the amount of disk space used, including"
." all space consumed by descendents, such as file systems"
." and snapshots. Setting a quota on a descendent of a file"
." system that already has a quota does not override the"
." ancestor's quota, but rather imposes an additional"
." limit. Quotas cannot be set on volumes, as the volsize"
." property acts as an implicit quota.",
referenced => "Read-only property that identifies the amount of data"
." accessible by a dataset, which might or might not be"
." shared with other datasets in the pool."
." When a snapshot or clone is created, it initially"
." references the same amount of disk space as the file"
." system or snapshot it was created from, because its"
." contents are identical.",
refquota => "Sets the amount of disk space that a dataset can"
." consume. This property enforces a hard limit on the"
." amount of space used. This hard limit does not include"
." disk space used by descendents, such as snapshots and"
." clones.",
refreservation => "Sets the minimum amount of disk space that is"
." guaranteed to a dataset, not including descendents,"
." such as snapshots and clones. When the amount of disk"
." space used is below this value, the dataset is treated as if"
." it were taking up the amount of space specified by"
." refreservation. The refreservation reservation is"
." accounted for in the parent dataset's disk space used,"
." and counts against the parent dataset's quotas and"
." reservations."
." If refreservation is set, a snapshot is only allowed if"
." enough free pool space is available outside of this"
." reservation to accommodate the current number of"
." referenced bytes in the dataset.",
reservation => "Sets the minimum amount of disk space guaranteed to"
." a file system and its descendents. When the amount of"
." disk space used is below this value, the file system is"
." treated as if it were using the amount of space specified"
." by its reservation. Reservations are accounted for in the"
." parent file system's disk space used, and count against"
." the parent file system's quotas and reservations.",
type => "Read-only property that identifies the dataset type as"
." filesystem (file system or clone), volume, or"
." snapshot.",
used => "Read-only property that identifies the amount of disk"
." space consumed by a dataset and all its descendents.",
usedbychildren => "Read-only property that identifies the amount of disk"
." space that is used by children of this dataset, which"
." would be freed if all the dataset's children were"
." destroyed. The property abbreviation is usedchild.",
usedbydataset => "Read-only property that identifies the amount of disk"
." space that is used by a dataset itself, which would be"
." freed if the dataset was destroyed, after first destroying"
." any snapshots and removing any refreservation"
." reservations. The property abbreviation is usedds.",
usedbyrefreservation=> "Read-only property that identifies the amount of disk"
." space that is used by a refreservation set on a dataset,"
." which would be freed if the refreservation was"
." removed.",
usedbysnapshots => "Read-only property that identifies the amount of disk"
." space that is consumed by snapshots of a dataset. In"
." particular, it is the amount of disk space that would be"
." freed if all of this dataset's snapshots were destroyed."
." Note that this value is not simply the sum of the"
." snapshots' used properties, because space can be"
." shared by multiple snapshots.",
volsize => "For volumes, specifies the logical size of the volume.",
};
my @order = (
"usedbydataset",
"usedbysnapshots",
"usedbyrefreservation",
"usedbychildren",
"available",
"quota",
"refquota",
"referenced",
"reservation",
"refreservation",
"used",
"volsize",
);
sub do_collect {
my $fslist=(`$zfsexec list -H -r -o name $zpool`);
my @params = join(',',( keys %{$properties} ));
my $fsget="$zfsexec get -H -p @params";
foreach my $fsname (split(/\n/,$fslist)) {
foreach my $line (split(/\n/, `$fsget $fsname` )) {
my ($name, $key, $value, undef ) = (split(/\t/,$line));
($name =~ s/\//_/g);
$filesystems->{$name}->{$key}=$value;
}
}
}
sub do_config_fs {
my ($fs) = @_;
my $fs_slash = ($fs);
($fs_slash =~ s/_/\//g);
if ( $fs ne $zpool ) {
print "multigraph zfs_usage_$zpool.$fs\n";
print "graph_title ZFS usage for $filesystems->{$fs}->{type} $fs_slash\n";
print "graph_info This graph shows used bytes of $filesystems->{$fs}->{type} $fs_slash\n";
} else {
print "multigraph zfs_usage_$zpool\n";
print "graph_title ZFS usage for zpool $zpool\n";
print "graph_info This graph shows used bytes of zpool $zpool\n";
}
print "graph_args --base 1024 --lower-limit 0 --rigid\n";
print "graph_vlabel bytes \n";
print "graph_category zfs\n";
print "graph_order @order\n";
foreach my $key ( keys %{$filesystems->{$fs}}) {
if ( $key ne "type" ) {
if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) {
}
elsif ($filesystems->{$fs}->{type} eq "filesystem" && $key eq "volsize") {
}
else {
print "$key.label $key\n";
print "$key.min 0\n";
print "$key.type GAUGE\n";
print "$key.info $properties->{$key}\n";
if ( $key =~ /quota|referenced|^(ref)*reservation|^used$|volsize/ ) {
print "$key.draw LINE3\n";
}
else {
print "$key.draw AREASTACK\n";
}
}
}
}
}
sub do_fetch_fs {
my ($fs) = @_;
if ( $fs ne $zpool ) {
print "multigraph zfs_usage_$zpool.$fs\n";
} else {
print "multigraph zfs_usage_$zpool\n";
}
foreach my $key ( keys %{$filesystems->{$fs}}) {
if ( $key ne "type" ) {
if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) {
}
elsif ($filesystems->{$fs}->{type} eq "filesystem" && $key eq "volsize") {
}
else {
print "$key.value $filesystems->{$fs}->{$key}\n";
}
}
}
}
sub do_config {
foreach my $fs ( sort keys %{$filesystems}) {
do_config_fs($fs);
}
}
sub do_autoconf {
if (`which $zpoolexec 2>/dev/null` =~ m{^/}) {
print "yes\n";
} else {
print "no ($zpoolexec could not be found)\n";
}
exit 0;
}
sub do_suggest {
my $poollist=(`zpool list -H -o name`);
print "$poollist";
}
sub do_fetch {
foreach my $fs ( sort keys %{$filesystems}) {
do_fetch_fs($fs);
}
}
sub do_setpool {
if ( $0 =~ /zfs_usage_$/) {
die ("Can't run without a symlinked name\n")
}
elsif ($0 =~ /zfs_usage_(.+)*$/) {
$zpool = $1;
}
}
if ($ARGV[0]) {
if ($ARGV[0] eq "config") {
do_setpool();
do_collect();
do_config();
exit 0;
}
elsif ($ARGV[0] eq "autoconf") {
do_autoconf();
exit 0;
}
elsif ($ARGV[0] eq "suggest") {
do_suggest();
exit 0;
}
}
else {
do_setpool();
do_collect();
do_fetch();
}
exit 0;
__END__

4
tools/munin-node-c/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
# output files
/*.o
/munin-node-c
/plugins/*

View file

@ -0,0 +1,24 @@
CC=gcc
CFLAGS=-W -Wall -pedantic -Wextra -g -O2
OBJS=main.o
LINKS=
%.o: %.c
${CC} ${CFLAGS} -c $< -o $@
all: munin-node-c
munin-node-c: ${OBJS}
${CC} ${CFLAGS} $^ -o $@
clean:
rm -f munin-node-c ${OBJS} ${LINKS}
rm -Rf plugins
plugins: plugins/.munin-plugins-busybox.installed
plugins/.munin-plugins-busybox.installed:
mkdir -p plugins
cd ../munin-plugins-busybox && $(MAKE)
cd plugins && for i in $$(find ../../munin-plugins-busybox -type l); do ln -s $$i; done
touch plugins/.munin-plugins-busybox.installed
.PHONY: all clean plugins

28
tools/munin-node-c/README Normal file
View file

@ -0,0 +1,28 @@
This is a rewrite of munin node in C.
Pro:
----
The purpose is multiple:
* reducing resource usage for embedded plateforms, specially when paired
with the C rewrite of the core plugins.
* no need for Perl
* Everything runs from inetd.
Cons:
-----
* You lose flexibility
It is compiled code, so you have to create binaries. Even one for each
architecture.
* Not all the features are implemented
- root uid is not supported. All plugins are run with a single user, usually nobody.
- no socket is opened. Everything runs from inetd.
GPLv2 - (C) 2013 Steve SCHNEPP <steve.schnepp@pwkf.org>

145
tools/munin-node-c/main.c Normal file
View file

@ -0,0 +1,145 @@
#include <libgen.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
char VERSION[] = "1.0.0";
int verbose = 0;
char* host = "";
char* plugin_dir = "plugins";
char* spoolfetch_dir = "";
int main(int argc, char *argv[]) {
int optch;
extern int opterr;
int optarg_len;
char format[] = "vd:h:s:";
char line[LINE_MAX];
opterr = 1;
while ((optch = getopt(argc, argv, format)) != -1)
switch (optch) {
case 'v':
verbose ++;
break;
case 'd':
optarg_len = strlen(optarg);
plugin_dir = (char *) malloc(optarg_len + 1);
strcpy(plugin_dir, optarg);
break;
case 'h':
optarg_len = strlen(optarg);
host = (char *) malloc(optarg_len + 1);
strcpy(host, optarg);
break;
case 's':
optarg_len = strlen(optarg);
spoolfetch_dir = (char *) malloc(optarg_len + 1);
strcpy(spoolfetch_dir, optarg);
break;
}
/* get default hostname if not precised */
if (! strlen(host)) {
host = (char *) malloc(HOST_NAME_MAX + 1);
gethostname(host, HOST_NAME_MAX);
}
printf("# munin node at %s\n", host);
while (fgets(line, LINE_MAX, stdin) != NULL) {
char* cmd;
char* arg;
line[LINE_MAX-1] = '\0';
cmd = strtok(line, " \t\n");
if(cmd == NULL)
arg = NULL;
else
arg = strtok(NULL, " \t\n");
if (!cmd || strlen(cmd) == 0) {
printf("# empty cmd\n");
} else if (strcmp(cmd, "version") == 0) {
printf("munin c node version: %s\n", VERSION);
} else if (strcmp(cmd, "nodes") == 0) {
printf("%s\n", host);
printf(".\n");
} else if (strcmp(cmd, "quit") == 0) {
return(0);
} else if (strcmp(cmd, "list") == 0) {
DIR* dirp = opendir(plugin_dir);
struct dirent* dp;
while ((dp = readdir(dirp)) != NULL) {
char cmdline[LINE_MAX];
char* plugin_filename = dp->d_name;;
if (plugin_filename[0] == '.') {
/* No dotted plugin */
continue;
}
snprintf(cmdline, LINE_MAX, "%s/%s", plugin_dir, plugin_filename);
if (access(cmdline, X_OK) == 0) {
printf("%s ", plugin_filename);
}
}
printf("\n");
closedir(dirp);
} else if (
strcmp(cmd, "config") == 0 ||
strcmp(cmd, "fetch") == 0
) {
char cmdline[LINE_MAX];
pid_t pid;
if(arg == NULL) {
printf("# no plugin given\n");
continue;
}
if(arg[0] == '.' || strchr(arg, '/')) {
printf("# invalid plugin character");
continue;
}
snprintf(cmdline, LINE_MAX, "%s/%s", plugin_dir, arg);
if (access(cmdline, X_OK) == -1) {
printf("# unknown plugin: %s\n", arg);
continue;
}
if(0 == (pid = vfork())) {
execl(cmdline, arg, cmd, NULL);
/* according to vfork(2) we must use _exit */
_exit(1);
} else if(pid < 0) {
printf("# fork failed\n");
continue;
} else {
waitpid(pid, NULL, 0);
}
printf(".\n");
} else if (strcmp(cmd, "cap") == 0) {
printf("cap ");
if (strlen(spoolfetch_dir)) {
printf("spool ");
}
printf("\n");
} else if (strcmp(cmd, "spoolfetch") == 0) {
printf("# not implem yet cmd: %s\n", cmd);
} else {
printf("# unknown cmd: %s\n", cmd);
}
}
return 0;
}

View file

@ -0,0 +1 @@
*.o

View file

@ -0,0 +1,18 @@
CC=gcc
CFLAGS=-W -Wall -pedantic -Wextra -g -O2
OBJS=main.o common.o cpu.o entropy.o forks.o fw_packets.o interrupts.o \
if_err_.o load.o open_files.o open_inodes.o processes.o swap.o threads.o \
uptime.o
LINKS=cpu entropy forks fw_packets interrupts if_err_eth0 load open_files \
open_inodes processes swap threads uptime
%.o:%.c
${CC} ${CFLAGS} -c $< -o $@
all:munin-plugins-busybox
strip -s munin-plugins-busybox
for l in ${LINKS}; do test -f $$l || ln -s munin-plugins-busybox $$l; done
munin-plugins-busybox:${OBJS}
${CC} ${CFLAGS} $^ -o $@
clean:
rm -f munin-plugins-busybox ${OBJS} ${LINKS}
.PHONY:all clean

View file

@ -0,0 +1,36 @@
What is this?
~~~~~~~~~~~~~
This is a rewrite of commonly used munin plugins in C as a single binary.
The purpose is reducing resource usage:
* disk space: the binary is smaler than the plugins together
* more diskspace: it has no dependencies on other programs
* less forks: it does not fork internally
* faster startup: it doesn't start perl or shell
* less memory: just a small C program
* less file accesses: one binary for many plugins
This can be useful for machines with restricted resources like embedded
machines.
What plugins are included?
~~~~~~~~~~~~~~~~~~~~~~~~~~
cpu entropy forks fw_packets interrupts load open_files open_inodes
processes swap uptime
Disadvantages?
~~~~~~~~~~~~~~
You lose flexibility. You can no longer just edit the plugin and if you try
you have to be very careful not to break it. If you want to deploy this you
have to create one binary for each architecture.
How to use?
~~~~~~~~~~~
After compiling there will be binary munin-plugins-busybox. You can just
replace symlinks in /etc/munin/plugins/ with symlinks to this binary.
License?
~~~~~~~~
(C) 2008 Helmut Grohne <helmut@subdivi.de>
At your choice GPLv2 or GPLv3 applies to *.c *.h and Makefile
# vim7:spelllang=en
# vim:textwidth=75

View file

@ -0,0 +1,74 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern char **environ;
int writeyes(void) {
puts("yes");
return 0;
}
int autoconf_check_readable(const char *path) {
if(0 == access(path, R_OK))
return writeyes();
else {
printf("no (%s is not readable, errno=%d)\n", path, errno);
return 0;
}
}
int getenvint(const char *name, int defvalue) {
const char *value;
value = getenv(name);
if(value == NULL)
return defvalue;
return atoi(value);
}
const char *getenv_composed(const char *name1, const char *name2) {
char **p;
size_t len1 = strlen(name1), len2 = strlen(name2);
for(p = environ; *p; ++p) {
if(0 == strncmp(*p, name1, len1) &&
0 == strncmp(len1 + *p, name2, len2) &&
(*p)[len1 + len2] == '=')
return len1 + len2 + 1 + *p;
}
return NULL;
}
void print_warning(const char *name) {
const char *p;
p = getenv_composed(name, "_warning");
if(p == NULL)
p = getenv("warning");
if(p == NULL)
return;
printf("%s.warning %s\n", name, p);
}
void print_critical(const char *name) {
const char *p;
p = getenv_composed(name, "_critical");
if(p == NULL)
p = getenv("critical");
if(p == NULL)
return;
printf("%s.critial %s\n", name, p);
}
void print_warncrit(const char *name) {
print_warning(name);
print_critical(name);
}
int fail(const char *message) {
fputs(message, stderr);
fputc('\n', stderr);
return 1;
}

View file

@ -0,0 +1,15 @@
#ifndef COMMON_H
#define COMMON_H
#define PROC_STAT "/proc/stat"
int writeyes(void);
int autoconf_check_readable(const char *);
int getenvint(const char *, int);
const char *getenv_composed(const char *, const char *);
void print_warning(const char *);
void print_critical(const char *);
void print_warncrit(const char *);
int fail(const char *);
#endif

View file

@ -0,0 +1,175 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include "common.h"
#define SYSWARNING 30
#define SYSCRITICAL 50
#define USRWARNING 80
/* TODO: port support for env.foo_warning and env.foo_critical from mainline plugin */
int cpu(int argc, char **argv) {
FILE *f;
char buff[256], *s;
int ncpu=0, extinfo=0, scaleto100=0, hz;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
s = getenv("scaleto100");
if(s && !strcmp(s, "yes"))
scaleto100=1;
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "cpu", 3)) {
if(isdigit(buff[3]))
ncpu++;
if(buff[3] == ' ') {
s = strtok(buff+4, " \t");
for(extinfo=0;strtok(NULL, " \t");extinfo++)
;
}
}
}
fclose(f);
if(ncpu < 1 || extinfo < 4)
return fail("cannot parse " PROC_STAT);
puts("graph_title CPU usage");
if(extinfo >= 7)
puts("graph_order system user nice idle iowait irq softirq");
else
puts("graph_order system user nice idle");
if(scaleto100)
puts("graph_args --base 1000 -r --lower-limit 0 --upper-limit 100");
else
printf("graph_args --base 1000 -r --lower-limit 0 --upper-limit %d\n", 100 * ncpu);
puts("graph_vlabel %\n"
"graph_scale no\n"
"graph_info This graph shows how CPU time is spent.\n"
"graph_category system\n"
"graph_period second\n"
"system.label system\n"
"system.draw AREA");
printf("system.max %d\n", 100 * ncpu);
puts("system.min 0\n"
"system.type DERIVE");
printf("system.warning %d\n", SYSWARNING * ncpu);
printf("system.critical %d\n", SYSCRITICAL * ncpu);
puts("system.info CPU time spent by the kernel in system activities\n"
"user.label user\n"
"user.draw STACK\n"
"user.min 0");
printf("user.max %d\n", 100 * ncpu);
printf("user.warning %d\n", USRWARNING * ncpu);
puts("user.type DERIVE\n"
"user.info CPU time spent by normal programs and daemons\n"
"nice.label nice\n"
"nice.draw STACK\n"
"nice.min 0");
printf("nice.max %d\n", 100 * ncpu);
puts("nice.type DERIVE\n"
"nice.info CPU time spent by nice(1)d programs\n"
"idle.label idle\n"
"idle.draw STACK\n"
"idle.min 0");
printf("idle.max %d\n", 100 * ncpu);
puts("idle.type DERIVE\n"
"idle.info Idle CPU time");
if(scaleto100)
printf("system.cdef system,%d,/\n"
"user.cdef user,%d,/\n"
"nice.cdef nice,%d,/\n"
"idle.cdef idle,%d,/\n", ncpu, ncpu, ncpu, ncpu);
if(extinfo >= 7) {
puts("iowait.label iowait\n"
"iowait.draw STACK\n"
"iowait.min 0");
printf("iowait.max %d\n", 100 * ncpu);
puts("iowait.type DERIVE\n"
"iowait.info CPU time spent waiting for I/O operations to finish\n"
"irq.label irq\n"
"irq.draw STACK\n"
"irq.min 0");
printf("irq.max %d\n", 100 * ncpu);
puts("irq.type DERIVE\n"
"irq.info CPU time spent handling interrupts\n"
"softirq.label softirq\n"
"softirq.draw STACK\n"
"softirq.min 0");
printf("softirq.max %d\n", 100 * ncpu);
puts("softirq.type DERIVE\n"
"softirq.info CPU time spent handling \"batched\" interrupts");
if(scaleto100)
printf("iowait.cdef iowait,%d,/\n"
"irq.cdef irq,%d,/\n"
"softirq.cdef softirq,%d,/\n", ncpu, ncpu, ncpu);
}
if(extinfo >= 8) {
puts("steal.label steal\n"
"steal.draw STACK\n"
"steal.min 0");
printf("steal.max %d\n", 100 * ncpu);
puts("steal.type DERIVE\n"
"steal.info The time that a virtual CPU had runnable tasks, but the virtual CPU itself was not running");
if(scaleto100)
printf("steal.cdef steal,%d,/\n", ncpu);
}
if(extinfo >= 9) {
puts("guest.label guest\n"
"guest.draw STACK\n"
"guest.min 0");
printf("guest.max %d\n", 100 * ncpu);
puts("guest.type DERIVE\n"
"guest.info The time spent running a virtual CPU for guest operating systems under the control of the Linux kernel.");
if(scaleto100)
printf("guest.cdef guest,%d,/\n", ncpu);
}
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_STAT);
}
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
hz = getenvint("HZ", 100);
if(!strncmp(buff, "cpu ", 4)) {
fclose(f);
if(!(s = strtok(buff+4, " \t")))
break;
printf("user.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
break;
printf("nice.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
break;
printf("system.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
break;
printf("idle.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("iowait.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("irq.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("softirq.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("steal.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("guest.value %ld\n", atol(s) * 100 / hz);
return 0;
}
}
fclose(f);
return fail("no cpu line found in " PROC_STAT);
}

View file

@ -0,0 +1,36 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
#define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail"
int entropy(int argc, char **argv) {
FILE *f;
int entropy;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Available entropy\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel entropy (bytes)\n"
"graph_scale no\n"
"graph_category system\n"
"graph_info This graph shows the amount of entropy available in the system.\n"
"entropy.label entropy\n"
"entropy.info The number of random bytes available. This is typically used by cryptographic applications.");
print_warncrit("entropy");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(ENTROPY_AVAIL);
}
if(!(f=fopen(ENTROPY_AVAIL, "r")))
return fail("cannot open " ENTROPY_AVAIL);
if(1 != fscanf(f, "%d", &entropy)) {
fclose(f);
return fail("cannot read from " ENTROPY_AVAIL);
}
fclose(f);
printf("entropy.value %d\n", entropy);
return 0;
}

View file

@ -0,0 +1,38 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
int forks(int argc, char **argv) {
FILE *f;
char buff[256];
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Fork rate\n"
"graph_args --base 1000 -l 0 \n"
"graph_vlabel forks / ${graph_period}\n"
"graph_category processes\n"
"graph_info This graph shows the forking rate (new processes started).\n"
"forks.label forks\n"
"forks.type DERIVE\n"
"forks.min 0\n"
"forks.max 100000\n"
"forks.info The number of forks per second.");
print_warncrit("forks");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_STAT);
}
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "processes ", 10)) {
fclose(f);
printf("forks.value %s", buff+10);
return 0;
}
}
fclose(f);
return fail("no processes line found in " PROC_STAT);
}

View file

@ -0,0 +1,55 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include "common.h"
#define PROC_NET_SNMP "/proc/net/snmp"
int fw_packets(int argc, char **argv) {
FILE *f;
char buff[1024], *s;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Firewall Throughput\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel Packets/${graph_period}\n"
"graph_category network\n"
"received.label Received\n"
"received.draw AREA\n"
"received.type DERIVE\n"
"received.min 0\n"
"forwarded.label Forwarded\n"
"forwarded.draw LINE2\n"
"forwarded.type DERIVE\n"
"forwarded.min 0");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_NET_SNMP);
}
if(!(f=fopen(PROC_NET_SNMP, "r")))
return fail("cannot open " PROC_NET_SNMP);
while(fgets(buff, 1024, f)) {
if(!strncmp(buff, "Ip: ", 4) && isdigit(buff[4])) {
fclose(f);
if(!(s = strtok(buff+4, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
printf("received.value %s\n", s);
if(!(s = strtok(NULL, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
printf("forwarded.value %s\n", s);
return 0;
}
}
fclose(f);
return fail("no ip line found in " PROC_NET_SNMP);
}

View file

@ -0,0 +1,118 @@
#include <ctype.h>
#include <libgen.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "common.h"
#define PROC_NET_DEV "/proc/net/dev"
int if_err_(int argc, char **argv) {
char *interface;
size_t interface_len;
FILE *f;
char buff[256], *s;
int i;
interface = basename(argv[0]);
if(strncmp(interface, "if_err_", 7) != 0)
return fail("if_err_ invoked with invalid basename");
interface += 7;
interface_len = strlen(interface);
if(argc > 1) {
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_NET_DEV);
if(!strcmp(argv[1], "suggest")) {
if(NULL == (f = fopen(PROC_NET_DEV, "r")))
return 1;
while(fgets(buff, 256, f)) {
for(s=buff;*s == ' ';++s)
;
i = 0;
if(!strncmp(s, "lo:", 3))
continue;
if(!strncmp(s, "sit", 3)) {
for(i=3; isdigit(s[i]); ++i)
;
if(s[i] == ':')
continue;
}
while(s[i] != ':' && s[i] != '\0')
++i;
if(s[i] != ':')
continue; /* a header line */
s[i] = '\0';
puts(s);
}
fclose(f);
return 0;
}
if(!strcmp(argv[1], "config")) {
puts("graph_order rcvd trans");
printf("graph_title %s errors\n", interface);
puts("graph_args --base 1000\n"
"graph_vlabel packets in (-) / out (+) per "
"${graph_period}\n"
"graph_category network");
printf("graph_info This graph shows the amount of "
"errors on the %s network interface.\n",
interface);
puts("rcvd.label packets\n"
"rcvd.type COUNTER\n"
"rcvd.graph no\n"
"rcvd.warning 1\n"
"trans.label packets\n"
"trans.type COUNTER\n"
"trans.negative rcvd\n"
"trans.warning 1");
print_warncrit("rcvd");
print_warncrit("trans");
return 0;
}
}
if(NULL == (f = fopen(PROC_NET_DEV, "r")))
return 1;
while(fgets(buff, 256, f)) {
for(s=buff;*s == ' ';++s)
;
if(0 != strncmp(s, interface, interface_len))
continue;
s += interface_len;
if(*s != ':')
continue;
++s;
while(*s == ' ')
++s;
for(i=1;i<3;++i) {
while(isdigit(*s))
++s;
while(isspace(*s))
++s;
}
for(i=0;isdigit(s[i]);++i)
;
printf("rcvd.value ");
fwrite(s, 1, i, stdout);
putchar('\n');
s += i;
while(isspace(*s))
++s;
for(i=4;i<11;++i) {
while(isdigit(*s))
++s;
while(isspace(*s))
++s;
}
for(i=0;isdigit(s[i]);++i)
;
printf("trans.value ");
fwrite(s, 1, i, stdout);
putchar('\n');
}
fclose(f);
return 0;
}

View file

@ -0,0 +1,46 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
int interrupts(int argc, char **argv) {
FILE *f;
char buff[256];
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Interrupts and context switches\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel interrupts & ctx switches / ${graph_period}\n"
"graph_category system\n"
"graph_info This graph shows the number of interrupts and context switches on the system. These are typically high on a busy system.\n"
"intr.info Interrupts are events that alter sequence of instructions executed by a processor. They can come from either hardware (exceptions, NMI, IRQ) or software.");
puts("ctx.info A context switch occurs when a multitasking operatings system suspends the currently running process, and starts executing another.\n"
"intr.label interrupts\n"
"ctx.label context switches\n"
"intr.type DERIVE\n"
"ctx.type DERIVE\n"
"intr.max 100000\n"
"ctx.max 100000\n"
"intr.min 0\n"
"ctx.min 0");
print_warncrit("intr");
print_warncrit("ctx");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_STAT);
}
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "intr ", 5)) {
buff[5 + strcspn(buff + 5, " \t\n")] = '\0';
printf("intr.value %s\n", buff+5);
} else if(!strncmp(buff, "ctxt ", 5)) {
buff[5 + strcspn(buff + 5, " \t\n")] = '\0';
printf("ctx.value %s\n", buff+5);
}
}
fclose(f);
return 0;
}

View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#define PROC_LOADAVG "/proc/loadavg"
int load(int argc, char **argv) {
FILE *f;
float val;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Load average\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel load\n"
"graph_scale no\n"
"graph_category system\n"
"load.label load");
print_warncrit("load");
puts("graph_info The load average of the machine describes how many processes are in the run-queue (scheduled to run \"immediately\").\n"
"load.info 5 minute load average");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return writeyes();
}
if(!(f=fopen(PROC_LOADAVG, "r")))
return fail("cannot open " PROC_LOADAVG);
if(1 != fscanf(f, "%*f %f", &val)) {
fclose(f);
return fail("cannot read from " PROC_LOADAVG);
}
fclose(f);
printf("load.value %.2f\n", val);
return 0;
}

View file

@ -0,0 +1,86 @@
#include <libgen.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
int cpu(int argc, char **argv);
int entropy(int argc, char **argv);
int forks(int argc, char **argv);
int fw_packets(int argc, char **argv);
int if_err_(int argc, char **argv);
int interrupts(int argc, char **argv);
int load(int argc, char **argv);
int open_files(int argc, char **argv);
int open_inodes(int argc, char **argv);
int processes(int argc, char **argv);
int swap(int argc, char **argv);
int threads(int argc, char **argv);
int uptime(int argc, char **argv);
int busybox(int argc, char **argv) {
if(argc < 2)
return fail("missing parameter");
if(0 != strcmp(argv[1], "listplugins"))
return fail("unknown parameter");
puts("cpu\nentropy\nforks\nfw_packets\ninterrupts\nload\n"
"open_files\nopen_inodes\nswap\nthreads\nuptime");
return 0;
}
int main(int argc, char **argv) {
char *progname;
progname = basename(argv[0]);
switch(*progname) {
case 'c':
if(!strcmp(progname, "cpu"))
return cpu(argc, argv);
break;
case 'e':
if(!strcmp(progname, "entropy"))
return entropy(argc, argv);
break;
case 'f':
if(!strcmp(progname, "forks"))
return forks(argc, argv);
if(!strcmp(progname, "fw_packets"))
return fw_packets(argc, argv);
break;
case 'i':
if(!strcmp(progname, "interrupts"))
return interrupts(argc, argv);
if(!strncmp(progname, "if_err_", 6))
return if_err_(argc, argv);
break;
case 'l':
if(!strcmp(progname, "load"))
return load(argc, argv);
break;
case 'm':
if(!strcmp(progname, "munin-plugins-busybox"))
return busybox(argc, argv);
break;
case 'o':
if(!strcmp(progname, "open_files"))
return open_files(argc, argv);
if(!strcmp(progname, "open_inodes"))
return open_inodes(argc, argv);
break;
case 'p':
if(!strcmp(progname, "processes"))
return processes(argc, argv);
break;
case 's':
if(!strcmp(progname, "swap"))
return swap(argc, argv);
break;
case 't':
if(!strcmp(progname, "threads"))
return threads(argc, argv);
break;
case 'u':
if(!strcmp(progname, "uptime"))
return uptime(argc, argv);
break;
}
return fail("unknown basename");
}

View file

@ -0,0 +1,49 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
#define FS_FILE_NR "/proc/sys/fs/file-nr"
/* TODO: support env.warning and friends after the upstream plugin is fixed */
int open_files(int argc, char **argv) {
FILE *f;
int alloc, freeh, avail;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
if(!(f=fopen(FS_FILE_NR, "r")))
return fail("cannot open " FS_FILE_NR);
if(1 != fscanf(f, "%*d %*d %d", &avail)) {
fclose(f);
return fail("cannot read from " FS_FILE_NR);
}
fclose(f);
puts("graph_title File table usage\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel number of open files\n"
"graph_category system\n"
"graph_info This graph monitors the Linux open files table.\n"
"used.label open files\n"
"used.info The number of currently open files.\n"
"max.label max open files\n"
"max.info The maximum supported number of open "
"files. Tune by modifying " FS_FILE_NR
".");
printf("used.warning %d\nused.critical %d\n",
(int)(avail*0.92), (int)(avail*0.98));
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(FS_FILE_NR);
}
if(!(f=fopen(FS_FILE_NR, "r")))
return fail("cannot open " FS_FILE_NR);
if(3 != fscanf(f, "%d %d %d", &alloc, &freeh, &avail)) {
fclose(f);
return fail("cannot read from " FS_FILE_NR);
}
fclose(f);
printf("used.value %d\nmax.value %d\n", alloc-freeh, avail);
return 0;
}

View file

@ -0,0 +1,38 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
#define FS_INODE_NR "/proc/sys/fs/inode-nr"
int open_inodes(int argc, char **argv) {
FILE *f;
int nr, freen;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Inode table usage\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel number of open inodes\n"
"graph_category system\n"
"graph_info This graph monitors the Linux open inode table.\n"
"used.label open inodes\n"
"used.info The number of currently open inodes.\n"
"max.label inode table size\n"
"max.info The size of the system inode table. This is dynamically adjusted by the kernel.");
print_warncrit("used");
print_warncrit("max");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(FS_INODE_NR);
}
if(!(f=fopen(FS_INODE_NR, "r")))
return fail("cannot open " FS_INODE_NR);
if(2 != fscanf(f, "%d %d", &nr, &freen)) {
fclose(f);
return fail("cannot read from " FS_INODE_NR);
}
fclose(f);
printf("used.value %d\nmax.value %d\n", nr-freen, nr);
return 0;
}

View file

@ -0,0 +1,42 @@
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>
#include "common.h"
/* TODO: The upstream plugin does way more nowawdays. */
int processes(int argc, char **argv) {
DIR *d;
struct dirent *e;
char *s;
int n=0;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Number of Processes\n"
"graph_args --base 1000 -l 0 \n"
"graph_vlabel number of processes\n"
"graph_category processes\n"
"graph_info This graph shows the number of processes in the system.\n"
"processes.label processes\n"
"processes.draw LINE2\n"
"processes.info The current number of processes.");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return writeyes();
}
if(!(d = opendir("/proc")))
return fail("cannot open /proc");
while((e = readdir(d))) {
for(s=e->d_name;*s;++s)
if(!isdigit(*s))
break;
if(!*s)
++n;
}
closedir(d);
printf("processes.value %d\n", n);
return 0;
}

View file

@ -0,0 +1,66 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
int swap(int argc, char **argv) {
FILE *f;
char buff[256];
int in, out;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Swap in/out\n"
"graph_args -l 0 --base 1000\n"
"graph_vlabel pages per ${graph_period} in (-) / out (+)\n"
"graph_category system\n"
"swap_in.label swap\n"
"swap_in.type DERIVE\n"
"swap_in.max 100000\n"
"swap_in.min 0\n"
"swap_in.graph no\n"
"swap_out.label swap\n"
"swap_out.type DERIVE\n"
"swap_out.max 100000\n"
"swap_out.min 0\n"
"swap_out.negative swap_in");
print_warncrit("swap_in");
print_warncrit("swap_out");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_STAT);
}
if(!access("/proc/vmstat", F_OK)) {
in=out=0;
if(!(f=fopen("/proc/vmstat", "r")))
return fail("cannot open /proc/vmstat");
while(fgets(buff, 256, f)) {
if(!in && !strncmp(buff, "pswpin ", 7)) {
++in;
printf("swap_in.value %s", buff+7);
}
else if(!out && !strncmp(buff, "pswpout ", 8)) {
++out;
printf("swap_out.value %s", buff+8);
}
}
fclose(f);
if(!(in*out))
return fail("no usable data on /proc/vmstat");
return 0;
} else {
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "swap ", 5)) {
fclose(f);
if(2 != sscanf(buff+5, "%d %d", &in, &out))
return fail("bad data on " PROC_STAT);
printf("swap_in.value %d\nswap_out.value %d\n", in, out);
return 0;
}
}
fclose(f);
return fail("no swap line found in " PROC_STAT);
}
}

View file

@ -0,0 +1,70 @@
#include <ctype.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "common.h"
int threads(int argc, char **argv) {
FILE *f;
char buff[256];
const char *s;
int i, sum;
DIR *d;
struct dirent *e;
if(argc > 1) {
if(!strcmp(argv[1], "autoconf")) {
i = getpid();
sprintf(buff, "/proc/%d/status", i);
if(NULL == (f = fopen(buff, "r")))
return fail("failed to open /proc/$$/status");
while(fgets(buff, 256, f))
if(!strncmp(buff, "Threads:", 8)) {
fclose(f);
return writeyes();
}
fclose(f);
puts("no");
return 0;
}
if(!strcmp(argv[1], "config")) {
puts("graph_title Number of threads\n"
"graph_vlabel number of threads\n"
"graph_category processes\n"
"graph_info This graph shows the number of threads.\n"
"threads.label threads\n"
"threads.info The current number of threads.");
return 0;
}
}
if(NULL == (d = opendir("/proc")))
return fail("cannot open /proc");
sum = 0;
while((e = readdir(d))) {
for(s=e->d_name;*s;++s)
if(!isdigit(*s))
break;
if(*s) /* non-digit found */
continue;
snprintf(buff, 256, "/proc/%s/status", e->d_name);
if(!(f = fopen(buff, "r")))
continue; /* process has vanished */
while(fgets(buff, 256, f)) {
if(strncmp(buff, "Threads:", 8))
continue;
if(1 != sscanf(buff+8, "%d", &i)) {
fclose(f);
closedir(d);
return fail("failed to parse "
"/proc/somepid/status");
}
sum += i;
}
fclose(f);
}
closedir(d);
printf("threads.value %d\n", sum);
return 0;
}

View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <string.h>
#include "common.h"
int uptime(int argc, char **argv) {
FILE *f;
float uptime;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Uptime\n"
"graph_args --base 1000 -l 0 \n"
"graph_vlabel uptime in days\n"
"uptime.label uptime\n"
"uptime.draw AREA");
print_warncrit("uptime");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return writeyes();
}
if(!(f=fopen("/proc/uptime", "r")))
return fail("cannot open /proc/uptime");
if(1 != fscanf(f, "%f", &uptime)) {
fclose(f);
return fail("cannot read from /proc/uptime");
}
fclose(f);
printf("uptime.value %.2f\n", uptime/86400);
return 0;
}