[SCRIPT] Asterisk Überwachung

HobbyStern

Aktives Mitglied
Mitglied seit
5 Dez 2005
Beiträge
1,844
Punkte für Reaktionen
0
Punkte
36
Hallo Gemeinde,

editiert am 12.12.2010 - Update. Gesprächigkeit, besseres Killen, Mail-Parameter, Stopp bei fehlgeschlagener Reparatur.

Ich habe folgendes gerade zusammengestellt - es soll das Start/Stop Skript (SafeSkript) ergänzen.

Hintergrund - mein Asterisk wird in Stoßzeiten sehr oft mit "-rx BEFEHL" geöffnet und wieder geschlossen, da passiert es aktuell leider das er keine Remoteverbindungen via rx mehr zulässt, er schottet sich ab - dieses Problem behebt sich nicht automatisch und alle zukünftigen rx Kommandos gehen leider schief.

Diesem Skript ist es egal, warum der Asterisk nicht reagierte - es wird geholfen. Folgende Szenarien sollten damit abgedeckt sein :

- RX Zugang ist überlastet
- Asterisk friert ein
- Asterisk ist abgestürzt (wurde jedoch durch das Safe Skript nicht neu gestartet)
- Maschinenreboot ohne das safe_skript zu starten

Daher dieses Skript, vielleicht hilft es dem ein oder anderen? Über Feedback würde ich mich sehr freuen.

Code:
#!/bin/bash
#
# Hobbystern aus dem IPPF im Dezember 2010
# Kleines Asterisk-Skript das Helfen soll einen nicht mehr reagierenden Asterisken neu zu starten, warum er nicht merh will soll uns egal sein.
# Ich gehe davon aus das Asterisk ueber safe_asterisk gestartet wurde.
# Es ist angedacht das auch dahdi bzw zapata von diesem skript geprueft wird, es wird jedoch keine aktion ausser einer mail ausgefuehrt.
# Bitte veraendere die Benutzervariablen nach Deinen Bedingungen!
#
# Anbei - dieses Skript eignet sich gut um im CRON zu starten, hier wird es alle 30 Minuten ausgefuehrt.
#
#

#
# Benutzervariablen setzen
# Hier bitte aendern!
#
ASTERISKPID=/var/run/asterisk.pid               # Wo liegt die Asterisk PID Datei?
DAHDIPID=/var/run/dahdi.pid                     # Wo ist das PID fuer DAHDI - ACHTUNG - DAHDI hat anscheinend gar kein PID!
SAFESKRIPT=/etc/init.d/safe_asterisk            # Der lange Name um das Start Skript in der Schleife aufzurufen!
SAFESKRIPTKURZ=safe_asterisk                    # Der Kurzname fuer die KILL Anweisungen des SAFE Skriptes 
HOSTNAME=ASTERISK                               # Wie soll der Rechner heissen?
[email protected]                     # Wohin gehen Emails?
LOCKDATEI=/tmp/ASTERISK-ERROR                   # Die Sperrdatei inkl. Pfad, tritt ein Problem ein und kann es nicht behoben wereden, haelt es das Skript ab laufend zu reparieren
VERBOSE=no                                      # Sollen Ausgaben bei der Verarbeitung gemacht werden? Startet man ueber Cron, so wird Cron dieses laufend per Mail melden!
#
# Ende der Benzervariablen
#

# Haben wir einen kritischen Zustand starten wir sicherheitshalber nicht mehr...
if [ -e ${LOCKDATEI} ]; then
        echo "PANIK DATEI VORHANDEN"
        echo "Start des Skriptes wurde durch die Datei ${LOCKDATEI} verhindert." 
        echo "Es gab anscheinend ein Problem, ist es behoben, so loeschen Sie die Datei ${LOCKDATEI}"
        exit 1
fi

# Versuche die Verbindung zu Asterisk und DAHDI
ASTERISKALIVE=`/usr/sbin/asterisk -rx "dahdi show status" | grep "Unable to connect to remote"`
DAHDIALIVE=`/usr/sbin/asterisk -rx "dahdi show status" | grep "No such command"`

if [ ${ASTERISKALIVE} = ${LEER} ]; then
        if [ ${VERBOSE} == "yes" ];then echo "Asterisk ist okay." ; fi
        if [ ${DAHDIALIVE} = ${LEER} ]; then
                if [ ${VERBOSE} == "yes" ];then echo "DAHDI-ZAP ist okay." ; fi
        else
                # Hier wird keine Aktion ausgefuehrt. Wird hier nicht benoetigt. Nur eine Mail.
                if [ ${VERBOSE} == "yes" ];then echo "DAHDI-ZAP ist nicht okay! Aktion folgt." ; fi
                mail -s "DAHDI ist auf ${HOSTNAME} nicht okay. PANIK!" ${EMAIL}
        fi
else
        if [ ${VERBOSE} == "yes" ];then echo "Asterisk und alle Komponenten sind nicht okay! Aktion folgt." ; fi
        mail -s "ASTERISK ist auf ${HOSTNAME} nicht okay. Versuche Reparatur!" ${EMAIL}
        killall ${SAFESKRIPTKURZ}
        sleep 5
        kill -INT `cat ${ASTERISKPID}`
        sleep 5
        if [ -e ${ASTERISKPID} ]; then
                pkill -9 ${SAFESKRIPTKURZ}
                sleep 2
                kill -9 `cat ${ASTERISKPID}`
                sleep 2
                if [ ${VERBOSE} == "yes" ];then echo "Asterisk und das Safe Skript gekillt!" ; fi
        else
                if [ ${VERBOSE} == "yes" ];then echo "Asterisk nett gestoppt." ; fi
        fi
        if [ ${VERBOSE} == "yes" ];then echo "Neustart des Asterisken..." ; fi
        ${SAFESKRIPT}
        sleep 5
        if [ -e ${ASTERISKPID} ]; then
                if [ ${VERBOSE} == "yes" ];then echo "Asterisk erfolgreich gestartet." ; fi
                mail -s "ASTERISK wurde auf ${HOSTNAME} repariert..." ${EMAIL}
                exit 0
        else
                if [ ${VERBOSE} == "yes" ];then echo "Asterisk konnte nicht starten...PANIK!" ; fi
                echo "Panikdatei vorhanden : ${LOCKDATEI}. Skript darf nicht mehr starten!" | mail -s "ASTERISK wurde auf ${HOSTNAME} NICHT repariert. Brauche Hilfe!" ${EMAIL}
                touch /tmp/ERROR
                exit 1
        fi
fi
Viel Erfolg!
 
Zuletzt bearbeitet:
/etc/init.d/safe_asterisk

Wer mag, ich habe das safe_asterisk Skript ebenfalls eingedeutscht und mit zahlreichen Dingen versehen:

- Legt eine PID an und wenn man will, startet es bei existierender PID nicht mehr
- Ausgaben ein und abschaltbar (Debug Modus)
- Mehr mail-infos bei Sorgen
- Geringe Interaktion mit dem Ueberwachungsskript (prüft ob es existiert)
- Gibt die Zahl der Interaktionen von safe_asterisk aus (Interessant wenn Asterisk selber einen Fehler hat und wir immer wieder starten)

Alles andere ist natürlich so wie immer.

Das hier ist ganz nebenher noch nicht produktiv, läuft aber hier ohne Theater.

Ich würde mich auch hier über Feedback sehr freuen!

Stefan

Code:
#!/bin/sh
CLIARGS="$*"                                    # Wenn wir Variablen (Parameter) an dieses Skript uebergeben werden wir diese einfangen
CONSOLE=yes                                     # Moechten wir eine "wilde" Konsolenausgabe?
TTY=3                                           # Wenn ja , auf welche Konsole?
[email protected]            # Wer erhaelt die Emails?
MACHINE=asterisk                                # Wie soll diese Maschine heissen?
DUMPDROP=/tmp                                   #
ASTSBINDIR=/usr/sbin                            # 
VERBOSITY=vvv                                   # Wieviel VERBOSE wollen wir, ein "v" steht fuer 1, 2 "v" fuer 2 usw
DEBUG=1                                         # Mit welchem Debug Level starten wir (0,1,2,3,4..)
ASTPIDFILE=/var/run/asterisk.pid                # Wo liegt das Asterisk PID
SAFE_PID=/var/run/safe_asterisk.pid             # Unsere PID
LOCKDATEI=/tmp/ASTERISK-ERROR                   # Die Sperrdatei des UeberwachungsSkriptes
NEUSTART=1                                      # Wir wurden gerade NEU gestartet
XMALE=1                                         # Wir wurden zum ersten Mal gestartet
VERBOSE=yes                                     # Moechten wir Ausgaben vom Skript erhalten? Gut fuer Testlauf
RM=/bin/rm                                      # Der Pfad zu RM
PIDNUTZEN=no                                    # Nutzen wir die PID, und wird eine existierende gefunden, wird der Start dieses Skripts verweigert. EXPERIMENTELL!

if [ -e ${LOCKDATEI} ]; then
        # Wir weisen nur hin, safe asterisk sollte ja auch ohne ueberwachung laufen
        echo "Sperrdatei ${LOCKDATEI} existiert. Eine Ueberwachung des Asterisk ist nicht moeglich!" | mail -s "Sperrdatei auf ${MACHINE} vorhanden!" ${NOTIFY}
        if [ ${VERBOSE} == "yes" ];then echo "SPERRDATEI existiert. Kein Ueberwachungsskriptlauf moeglich. Sperrdatei ${LOCKFILE}" ; fi
fi

if [ -e ${SAFE_PID} ]; then
        WARNUNG="\a \n \n ACHTUNG \n \n"
        echo -e ${WARNUNG}
        sleep 1
        echo -e ${WARNUNG}
        sleep 1
        echo -e ${WARNUNG}

        if [ ${PIDNUTZEN} == "yes" };then 
                # Start verweigern...
                echo "${SAFE_PID} EXISTIERT!! Safe_Asterisk wird anscheinend doppelt ausgefuehrt!! START VERWEIGERT!!" | mail -s "SAFE_ASTERISK auf ${MACHINE} wird doppelt ausgefuehrt!" ${NOTIFY}
                if [ ${VERBOSE} == "yes" ];then echo "${SAFE_PID} EXISTIERT!!!";echo "Loeschen Sie ${SAFE_PID} wenn Sie sicher sind das es starten soll.";echo "JETZT STARTET DAS SKRIPT NICHT!"; fi
                exit 0
        else
                #Start erlauben
                echo "${SAFE_PID} EXISTIERT!! Safe_Asterisk wird anscheinend doppelt ausgefuehrt!! Loesche PID und starte trotzdem..." | mail -s "SAFE_ASTERISK auf ${MACHINE} wird doppelt ausgefuehrt!" ${NOTIFY}
                if [ ${VERBOSE} == "yes" ];then echo "${SAFE_PID} EXISTIERT!!!";echo "Starte trotzdem";echo "JETZT STARTET DAS SKRIPT NICHT!"; fi
        fi

else
        touch ${SAFE_PID}
fi

if [ ${VERBOSE} == "yes" ];then echo "************ SAFE SKRIPT *************";echo "Maschine : ${MACHINE}";echo "Gespraechigkeit : ${VERBOSITY}"; echo "Debug : ${DEBUG}";echo "Konsole : ${TTY}";echo "Asterisk startet..." ; fi

ASTARGS=""
if [ "$TTY" != "" ]; then
        if [ -c /dev/tty${TTY} ]; then
                TTY=tty${TTY}
        elif [ -c /dev/vc/${TTY} ]; then
                TTY=vc/${TTY}
        else
                echo "Cannot find your TTY (${TTY})" >&2
                ${RM} ${SAFE_PID}
                exit 1
        fi
        # Originalzeile : ASTARGS="${ASTARGS} -vvvg -d 1"
        ASTARGS="${ASTARGS} -${VERBOSITY}g -d ${DEBUG}"
        if [ "$CONSOLE" != "no" ]; then
                ASTARGS="${ASTARGS} -c -d ${DEBUG}"
        fi
fi
if [ ! -w ${DUMPDROP} ]; then
        echo "Cannot write to ${DUMPDROP}" >&2
        ${RM} ${SAFE_PID}
        exit 1
fi

# Let Asterisk dump core
if [ ${VERBOSE} == "yes" ];then echo "Aufheben der Schreibsperre des BS" ; fi
ulimit -c unlimited

# Don't die if stdout/stderr can't be written to
trap '' PIPE

# Run scripts to set any environment variables or do any other system-specific setup needed

if [ -d /etc/asterisk/startup.d ]; then
        for script in /etc/asterisk/startup.d/*.sh; do
                if [ -x ${script} ]; then
                        if [ ${VERBOSE} == "yes" ];then echo "Lasse Skript ${script} laufen..." ; fi
                        source ${script}
                fi
        done
fi

run_asterisk()
{
        if [ ${NEUSTART} == 1 ]; then
                if [ ${VERBOSE} == "yes" ];then echo "INFO ${MACHINE}-Asterisk wurde durch safe-asterisk initial gestartet." ; fi
                echo "INFO ${MACHINE}-Asterisk wurde durch safe-asterisk initial gestartet." | \
                mail -s "Asterisk wurde initial gestartet" $NOTIFY
        else
                if [ ${VERBOSE} == "yes" ];then echo "INFO ${MACHINE}-Asterisk wurde durch safe-asterisk zum ${XMALE}ten Mal gestartet." ; fi
                echo "INFO ${MACHINE}-Asterisk wurde durch safe-asterisk ${XMALE}x gestartet." | \
                mail -s "Asterisk wurde ${XMALE}x gestartet" $NOTIFY
        fi

        NEUSTART=0
        # Startzaehler um 1 erhoehen
        XMALE=$((XMALE+1))
        while :; do 

                if [ "$TTY" != "" ]; then
                        cd /tmp
                        stty sane < /dev/${TTY}
                        ${ASTSBINDIR}/asterisk -f ${CLIARGS} ${ASTARGS} >& /dev/${TTY} < /dev/${TTY}
                else
                        cd /tmp
                        ${ASTSBINDIR}/asterisk -f ${CLIARGS} ${ASTARGS}
                fi
                EXITSTATUS=$?
                echo "Asterisk ended with exit status $EXITSTATUS"
                if [ "$EXITSTATUS" = "0" ]; then
                        # Properly shutdown....
                        echo "Asterisk shutdown normally."
                        ${RM} ${SAFE_PID}
                        exit 0
                elif [ $EXITSTATUS -gt 128 ]; then
                        let EXITSIGNAL=EXITSTATUS-128
                        echo "Asterisk exited on signal $EXITSIGNAL."
                        if [ ${VERBOSE} == "yes" ];then echo "Asterisk ist nicht normal beendet worden" ; fi
                        if [ "$NOTIFY" != "" ]; then
                                echo "Asterisk on $MACHINE exited on signal $EXITSIGNAL.  Might want to take a peek." | \
                                mail -s "Asterisk Died" $NOTIFY
                        fi

                        PID=`cat ${ASTPIDFILE}`
                        if [ -f /tmp/core.${PID} ]; then
                                if [ ${VERBOSE} == "yes" ];then echo "Ich speichere Debugdaten zum Crash in ${DUMPDROP}/core.`hostname`-`date -Iseconds`" ; fi
                                mv /tmp/core.${PID} ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
                        elif [ -f /tmp/core ]; then
                                if [ ${VERBOSE} == "yes" ];then echo "Ich speichere Debugdaten zum Crash in ${DUMPDROP}/core.`hostname`-`date -Iseconds`" ; fi
                                mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
                        fi
                else
                        if [ "${EXITSTATUS}" = "0" ]; then
                                echo "Asterisk normal beendet. Skript endet ebenfalls."
                                if [ ${VERBOSE} == "yes" ];then echo "Bedenken Sie das der Asterisk NUN AUSGESCHALTET IST" ; fi
                                echo "Asterisk auf $MACHINE wurde normal beendet. Er wird nicht automatisch neu hochgefahren..." | \
                                mail -s "Asterisk abgeschaltet" $NOTIFY
                                ${RM} ${SAFE_PID}
                                exit 0
                        else
                                echo "Asterisk died with code $EXITSTATUS."
                                if [ ${VERBOSE} == "yes" ];then echo "Asterisk ist nicht normal beendet worden" ; fi

                                PID=`cat ${ASTPIDFILE}`
                                if [ -f /tmp/core.${PID} ]; then
                                        if [ ${VERBOSE} == "yes" ];then echo "Ich speichere Debugdaten zum Crash in ${DUMPDROP}/core.`hostname`-`date -Iseconds`" ; fi
                                        mv /tmp/core.${PID} ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
                                elif [ -f /tmp/core ]; then
                                        if [ ${VERBOSE} == "yes" ];then echo "Ich speichere Debugdaten zum Crash in ${DUMPDROP}/core.`hostname`-`date -Iseconds`" ; fi
                                        mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
                                fi
                        fi
                fi
                if [ ${VERBOSE} == "yes" ];then echo "Asterisk wurde beendet. Automatischer Neustart..." ; fi
                sleep 4
        done
}

run_asterisk &
 
Zuletzt bearbeitet:
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.