MRTG

Prozessor-Auslastung auf dem Caipirinha-Server
Prozessor-Auslastung auf dem Caipirinha-Server
Netzwerk-Verkehr auf dem Caipirinha-Server
Netzwerk-Verkehr auf dem Caipirinha-Server

Mit dem Programm Multi Router Traffic Grapher (mrtg) lassen sich der zeitliche Verlauf von Netzwerkverkehr, CPU-Auslastung, Auslastung von Partitionen, etc. grafisch visualisieren. Dazu fragt das Programm periodisch eine oder mehrere Schnittstellen auf einem oder mehreren Netzknoten über SNMP ab. Mit Hilfe von Shell-Skripten sind aber darüber hinaus noch weitergehende Statistiken möglich [1]. David Guerrero hat in [2] eine verständliche Übersicht zum Thema SNMP und mrtg geschrieben. In der NET-SNMP Wiki sind ebenfalls zahlreiche Informationen enthalten.

Auf dem Caipirinha-Server werden aktuell folgende Statistiken bereit gestellt:

  • Netzwerkverkehr auf dem ADSL-Router [3]
  • Prozessorlast der Dual-Core CPU [4]
  • Auslastung der Partitionen /home und /backup [5]
  • Postfach-Größe der Benutzer gabriel und joselia [6]

Um mrtg einzurichten, muss man so vorgehen:

  • Der SNMP-Dienst muss auf den abzufragenden Netzknoten eingerichtet werden.
  • Ein Community-Name für den Lese-Zugriff muss auf den SNMP-Netzknoten festgelegt werden.
  • Das Paket mrtg muss auf dem Server installiert werden.
  • Die Konfigurationsdatei /etc/mrtg.conf muss entsprechend den darzustellenden Statistiken angepasst werden.
  • Eventuell müssen mit Hilfe eines cron-jobs Shell-Skripte ausgeführt werden.
  • In einem für den Apache-Server sichtbaren Bereich wird ein neues Unterverzeichnis eingerichtet und dem Benutzer des Webservers überschrieben. Im einfachsten Fall kann man das so machen:
mkdir /srv/www/htdocs/mrtg
chown wwwrun:www /srv/www/htdocs/mrtg

Hier ist die Konfigurationsdatei /etc/mrtg.conf des Caipirinha-Servers abgedruckt.

######################################################################
# MRTG Configuration File
# Gabriel Rüeck, 28-Apr-2010
######################################################################

Background[_]:  #ffffc8
Language:       german
Options[_]:     growright,integer,noinfo,nopercent
SnmpOptions:    timeout => 10, retries => 2
RunAsDaemon:    yes
WorkDir:        /srv/www/htdocs/mrtg

######################################################################
# System: caipirinha
# Location: "Ostpreußendamm 18B, 12207 Berlin, Germany"
######################################################################

#Target[caipirinha]: \eth0:public@caipirinha
#SetEnv[caipirinha]: MRTG_INT_IP="192.168.3.3" MRTG_INT_DESCR="eth0"
#MaxBytes[caipirinha]: 12500000
#Title[caipirinha]: Traffic Analysis for eth0 -- caipirinha
#PageTop[caipirinha]: <h1>Traffic Analysis for eth0 -- caipirinha</h1>
# <div id="sysdetails">
# <table>
# <tr>
# <td>System:</td>
# <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
# </tr>
# <tr>
# <td>Kontakt:</td>
# <td>"Gabriel Rüeck <gabriel@caipirinha.homelinux.org>"</td>
# </tr>
# <tr>
# <td>ifName:</td>
# <td>eth0</td>
# </tr>
# <tr>
# <td>Max Speed:</td>
# <td>12.5 MBytes/s</td>
# </tr>
# </table>
# </div>

######################################################################
# System: Arcor A800 Router
# Location: "Ostpreußendamm 18B, 12207 Berlin, Germany"
######################################################################

Target[router]:     12:public@192.168.3.1
SetEnv[router]:     MRTG_INT_IP="192.168.3.1" MRTG_INT_DESCR="PPPoE1"
MaxBytes[router]:   1000000
Title[router]:      Datenverkehr am ADSL-Router
YLegend[router]:    Bytes/s
PageTop[router]:    <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">Datenverkehr am ADSL-Router</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small">
 <table>
 <tr>
 <td>System:</td>
 <td>ADSL Router in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>

######################################################################
# System: CAIPIRINHA Server
# Location: "Ostpreußendamm 18B, 12207 Berlin, Germany"
######################################################################

Target[cpu]:       .1.3.6.1.4.1.2021.11.50.0&.1.3.6.1.4.1.2021.11.50.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.52.0&.1.3.6.1.4.1.2021.11.52.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.51.0&.1.3.6.1.4.1.2021.11.51.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.54.0&.1.3.6.1.4.1.2021.11.54.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.56.0&.1.3.6.1.4.1.2021.11.56.0:public@caipirinha
RouterUptime[cpu]: public@caipirinha
MaxBytes[cpu]:     200
Title[cpu]:        CPU-Auslastung auf CAIPIRINHA
Options[cpu]:      growright,integer,noinfo,noo,nopercent
Unscaled[cpu]:     ymwd
Suppress[cpu]:     ym
ShortLegend[cpu]:  %
YLegend[cpu]:      CPU Load
Legend1[cpu]:      Gesamt-Auslastung der Prozessor-Kerne
LegendI[cpu]:      CPU-Auslastung
PageTop[cpu]:     <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">CPU-Auslastung</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small" id="sysdetails">
 <table>
 <tr>
 <td>System:</td>
 <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>

######################################################################

Target[dsk]:       .1.3.6.1.4.1.2021.9.1.9.2&.1.3.6.1.4.1.2021.9.1.9.5:public@caipirinha
RouterUptime[dsk]: public@caipirinha
MaxBytes[dsk]:     100
kilo[dsk]:         1024
Title[dsk]:        Auslastung der Datenpartitionen auf CAIPIRINHA
Options[dsk]:      gauge,growright,integer,noinfo,nopercent
Unscaled[dsk]:     ymwd
Suppress[dsk]:     mwd
ShortLegend[dsk]:  %
YLegend[dsk]:      Disk Usage
Legend1[dsk]:      Auslastung der Partition /home
Legend2[dsk]:      Auslastung der Partition /backup
LegendI[dsk]:      /home
LegendO[dsk]:      /backup
PageTop[dsk]:     <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">Auslastung der Datenpartitionen</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small" id="sysdetails">
 <table>
 <tr>
 <td>System:</td>
 <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>

######################################################################

Target[mail]:       .1.3.6.1.4.1.2021.8.1.101.1&.1.3.6.1.4.1.2021.8.1.101.2:public@caipirinha
MaxBytes[mail]:     10000000000
kilo[mail]:         1024
Title[mail]:        Postfach-Größe auf CAIPIRINHA
Options[mail]:      gauge,growright,integer,noinfo,nopercent
Unscaled[mail]:     none
Suppress[mail]:     mwd
ShortLegend[mail]:  B
YLegend[mail]:      Mail Folder Size
Legend1[mail]:      Postfach-Größe von Gabriel
Legend2[mail]:      Postfach-Größe von Josélia
LegendI[mail]:      gabriel
LegendO[mail]:      joselia
PageTop[mail]:     <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">Postfach-Größe auf CAIPIRINHA</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small" id="sysdetails">
 <table>
 <tr>
 <td>System:</td>
 <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>
Auslastung der Partitionen /home und /backup
Auslastung der Partitionen /home und /backup
Postfach-Größe
Postfach-Größe von gabriel und joselia

Diese Konfigurationsdatei enthält sechs Teile. Im ersten Teil werden verschiedene global gültige Einstellungen festgelegt. Der zweite (auskommentierte) Teil enthält eine Abfrage der eth0-Schnittstelle des Caipirinha-Servers, deren Statistiken momentan aber nicht mehr erstellt werden.

Der dritte Teil fragt die PPPoE-Schnittstelle an meinem ADSL-Router ab. Dabei handelt es sich um die sehr gut ausgestattete Easy-Box A800, einem WLAN-VoIP-Adapter von Vodafone [7]. Dieser ist SNMP-fähig, und nach einigem Tüfteln konnte ich die PPPoE-Schnittstelle als Interface #12 lokalisieren (snmpwalk -v2c -cpublic 192.168.3.1 .1.3.6.1.2.1.2.2.1.2). Deshalb ist im zweiten (und nicht auskommentierten) Teil der Konfigurationsdatei für den Parameter Target[router] das Argument 12:public@192.168.3.1 gesetzt worden. Natürlich muss man auch noch SNMP in der Easy-Box A800 aktivieren, damit alles zusammen spielt.

Der vierte Teil setzt die Prozessorlast aus mehreren Variablen zusammen; diesen Ansatz habe ich in einigen Foren gefunden. Mit den Befehlen snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.11 | fgrep "Cpu" kann man sich alle auf dem SNMP-Knoten verfügbare CPU-Variablen ausgeben lassen:

UCD-SNMP-MIB::ssCpuUser.0 = INTEGER: 15
UCD-SNMP-MIB::ssCpuSystem.0 = INTEGER: 3
UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 5
UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 74362304
UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 13087145
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 7511231
UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 150434264
UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 3540187
UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 193882
UCD-SNMP-MIB::ssCpuRawSoftIRQ.0 = Counter32: 332350

Eine Beschreibung der einzelnen Variablen gibt es in [8]. Da der Caipirinha-Server einen Zweikern-Prozessor hat, wurde MaxBytes auf 200 gesetzt. Alternativ hätte man die Summe der CPU-Variablen bei Target durch 2 teilen können und MaxBytes dann auf 100 setzen. Da es keinen Sinn macht, die Prozessorlast über einen ganzen Monat oder gar über ein ganzes Jahr zu visualisieren, werden diese beiden Statistiken unterdrückt (Suppress).

Der fünfte Teil visualisiert die Auslastung der Datenpartitionen /home und /backup über die SNMP-Variablen dskPercent.2 und dskPercent.5, die auf dem Caipirinha-Server eben diesen Partitionen entsprechen. Welche Partitionen welchen Variablen zugeordnet sind, kann man mit dem Befehl snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.9 herausfinden. In meinem Fall ergibt dies:

UCD-SNMP-MIB::dskIndex.1 = INTEGER: 1
UCD-SNMP-MIB::dskIndex.2 = INTEGER: 2
UCD-SNMP-MIB::dskIndex.3 = INTEGER: 3
UCD-SNMP-MIB::dskIndex.4 = INTEGER: 4
UCD-SNMP-MIB::dskIndex.5 = INTEGER: 5
UCD-SNMP-MIB::dskPath.1 = STRING: /
UCD-SNMP-MIB::dskPath.2 = STRING: /home
UCD-SNMP-MIB::dskPath.3 = STRING: /home/public/Video
UCD-SNMP-MIB::dskPath.4 = STRING: /var
UCD-SNMP-MIB::dskPath.5 = STRING: /backup
UCD-SNMP-MIB::dskDevice.1 = STRING: /dev/md0
UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/mapper/cr_md2
UCD-SNMP-MIB::dskDevice.3 = STRING: /dev/md3
UCD-SNMP-MIB::dskDevice.4 = STRING: /dev/mapper/cr_md1
UCD-SNMP-MIB::dskDevice.5 = STRING: /dev/mapper/cr_sde1
...
UCD-SNMP-MIB::dskMinPercent.1 = INTEGER: 50
UCD-SNMP-MIB::dskMinPercent.2 = INTEGER: 10
UCD-SNMP-MIB::dskMinPercent.3 = INTEGER: 10
UCD-SNMP-MIB::dskMinPercent.4 = INTEGER: 20
UCD-SNMP-MIB::dskMinPercent.5 = INTEGER: 20
UCD-SNMP-MIB::dskTotal.1 = INTEGER: 51612944
UCD-SNMP-MIB::dskTotal.2 = INTEGER: 901563648
UCD-SNMP-MIB::dskTotal.3 = INTEGER: 1953388800
UCD-SNMP-MIB::dskTotal.4 = INTEGER: 8253744
UCD-SNMP-MIB::dskTotal.5 = INTEGER: 976628416
UCD-SNMP-MIB::dskAvail.1 = INTEGER: 40712692
UCD-SNMP-MIB::dskAvail.2 = INTEGER: 507764800
UCD-SNMP-MIB::dskAvail.3 = INTEGER: 165607280
UCD-SNMP-MIB::dskAvail.4 = INTEGER: 6885812
UCD-SNMP-MIB::dskAvail.5 = INTEGER: 232891056
UCD-SNMP-MIB::dskUsed.1 = INTEGER: 8278452
UCD-SNMP-MIB::dskUsed.2 = INTEGER: 348001984
UCD-SNMP-MIB::dskUsed.3 = INTEGER: 1787781632
UCD-SNMP-MIB::dskUsed.4 = INTEGER: 948664
UCD-SNMP-MIB::dskUsed.5 = INTEGER: 743737344
UCD-SNMP-MIB::dskPercent.1 = INTEGER: 17
UCD-SNMP-MIB::dskPercent.2 = INTEGER: 41
UCD-SNMP-MIB::dskPercent.3 = INTEGER: 92
UCD-SNMP-MIB::dskPercent.4 = INTEGER: 12
UCD-SNMP-MIB::dskPercent.5 = INTEGER: 76
...
UCD-SNMP-MIB::dskErrorFlag.1 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorFlag.2 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorFlag.3 = INTEGER: error(1)
UCD-SNMP-MIB::dskErrorFlag.4 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorFlag.5 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorMsg.1 = STRING:
UCD-SNMP-MIB::dskErrorMsg.2 = STRING:
UCD-SNMP-MIB::dskErrorMsg.3 = STRING: /home/public/Video: less than 10% free (= 92%)
UCD-SNMP-MIB::dskErrorMsg.4 = STRING:
UCD-SNMP-MIB::dskErrorMsg.5 = STRING:

Hier macht es meiner Meinung nach nur Sinn, die Jahresgrafik darzustellen, denn man ist ja eher am langfristigen Trend interessiert. Deshalb werden hier alle anderen Statistiken unterdrückt (Suppress).

Der sechste Teil zeigt die Postfach-Größe der beiden Benutzer gabriel und joselia im Verzeichnis /home/public/Mail. Dazu wird durch das Auslesen der SNMP-Variablen extOutput.1 und extOutput.2 über den SNMP-Dienst ein Shell-Skript ausgeführt, welches die Postfach-Größe des jeweiligen Benutzers ermittelt. Hier macht es meiner Meinung nach ebenfalls nur Sinn, die Jahresgrafik, also den langfristigen Trend, darzustellen. Deshalb werden auch hier alle anderen Statistiken unterdrückt.

SNMP-Konfiguration der Easy-Box A800
SNMP-Konfiguration der Easy-Box A800

Mit snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.8 [9] bekommt man übrigens eine Übersicht über die im SNMP-Dienst eingebundenen ausführbaren Skripte:

UCD-SNMP-MIB::extIndex.1 = INTEGER: 1
UCD-SNMP-MIB::extIndex.2 = INTEGER: 2
UCD-SNMP-MIB::extNames.1 = STRING: mbox_gabriel
UCD-SNMP-MIB::extNames.2 = STRING: mbox_joselia
UCD-SNMP-MIB::extCommand.1 = STRING: /root/bin/mailsize.sh
UCD-SNMP-MIB::extCommand.2 = STRING: /root/bin/mailsize.sh
UCD-SNMP-MIB::extResult.1 = INTEGER: 0
UCD-SNMP-MIB::extResult.2 = INTEGER: 0
UCD-SNMP-MIB::extOutput.1 = STRING: 521066367
UCD-SNMP-MIB::extOutput.2 = STRING: 160176044
UCD-SNMP-MIB::extErrFix.1 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFix.2 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFixCmd.1 = STRING:
UCD-SNMP-MIB::extErrFixCmd.2 = STRING:

Auf der Easy-Box A800 sind im Übrigen auch Traps aktiviert, so dass der WLAN-Router bei Problemen auf den Schnittstellen eine Mitteilung and den Caipirinha-Server schickt. Darunter fallen beispielsweise auch die Benachrichtigungen über das Zusammenbrechen der Internet-Verbindung wegen der in Deutschland obligatorischen Zwangstrennung nach 24h.

Mit dem Befehl snmpnetstat -v2c -cpublic -Ci -Cn 192.168.3.1 kann man sich die aktiven Netzwerk-Interfaces der A800 anzeigen lassen (public und 192.168.3.1 müssen natürlich entsprechend angepasst werden). Dies sieht dann beispielsweise so aus:

Name              Mtu Network      Address        Ipkts Ierrs    Opkts Oerrs Queue
LOCAL_LOOPBACK   1500 127.0.0.1/32 127.0.0.1          0     0        0     0     1
LAN              1500 192.168.3/24 192.168.3.1 10606794     0  8372114     0     1
WLAN             1500                             50788     0   506993     0     1
ATM1             1500                           8354414     0 11400582     0     1
PPPoE1           1492 88/0         88.74.99.8   8354356     0 11400515     0     1
WDS1             1500                                 0     0   121785     0     1
WDS2             1500                                 0     0   121785     0     1
WDS3             1500                                 0     0   121785     0     1
WDS4             1500                                 0     0   121785     0     1

Man kann klar die Adresse des internen Netzwerks 192.168.3/24 und die momentan zugewiesene externe IP-Adresse 88.74.99.8 erkennen.

Wie im Artikel über SNMP, so gilt auch hier, dass der Community-Name public aus Sicherheitsgründen im gesamten Netzwerk gegen einen anderen, einheitlich benutzten Community-Namen ausgetauscht werden sollte.

Nachdem die Konfigurationsdatei /etc/mrtg.conf angepasst worden ist, muss man mrtg noch explizit starten. Dies geschieht beispielsweise mit: env LANG=C mrtg --user wwwrun --group www --logging /var/log/mrtg.log --lock-file /var/tmp/mrtg --pid-file=/var/run/mrtg.pid /etc/mrtg.conf.

Dem eigentlichen Aufruf von mrtg wird das Kommando env LANG=C voran gestellt, sonst beklagt sich mrtg darüber, dass es nicht in einer Umgebung mit einem UTF8-Zeichensatz laufen kann. Es ist leider bei mrtg nicht möglich, einen automatischen Start über den Runlevel-Editor einzustellen. Man muss das Programm daher nach dem Systemstart manuell starten.

Posted on: 2010-06-29Gabriel Rüeck