Strony

Skrypt monitorujący - powiadomienia przez sms (PlusGSM)

Jak to ktoś powiedział potrzeba jest matką wynalazków, tak też było w tym przypadku. Potrzebowałem “coś” co będzie informowało mnie o padzie serwera czy też łącza pod które jest podpięty. Najpierw analiza wstępna jak to zrealizować, całe 5 minut … a więc będziemy “pingać” co jakiś czas serwer z odrębnej maszyny i jeśli serwer będzie odpowiadał to cykl trwa dalej bez zauważalnych skutków, a jeśli będzie timeout wysyłamy smsa. Proste czas na realizacje…

Jako, że podoba mi się obiektowy język skryptowy Python. Postanowiłem główny mechanizm napisać właśnie przy pomocy tego języka. Do zadań skryptu należeć będzie obsługa programu ping oraz wysyłanie smsa (w naszym przypadku maila ponieważ PlusGSM udostępnia dla każdego numeru adres e-mail, wysyłając mail na ten adres dostajemy smsa o treści maila na nasz numer). Zaczynamy więc krok po kroku:

Na początku zaimportujemy moduły, z których będziemy korzystać, subprocess (do wywoływania zewnętrznych procesów), smtplib (do nawiązywania połączeń przez protokół smtp) oraz email.Message (do prawidłowej konstrukcji maila). Warto wspomnieć, że subprocess jest obecny w pythonie od wersji 2.4 i zastępuje starsze metody wywoływania procesów.

import subprocess
import smtplib
import email.Message

Następnie wywołujemy program ping z parametrami -c 2 (wysyłamy 2 pakiety):

status = subprocess.call([’/sbin/ping’,'-c 2′,’host’])

Tworzymy mail do wysłania dzięki modułowi email.Message:

message = email.Message.Message()
message[”To”] = ‘486xxxxxxxx@text.plusgsm.pl’
message[”From”] = ‘cos@cos.pl’
message.set_payload(’Nasz host padł’)

Sprawdzamy czy host odpowiada (czy program ping zwrócił wartość 0), jeśli tak wysyłamy wiadomość i kończymy połączenie:

if(status != 0):
server = smtplib.SMTP(’localhost’)
server.sendmail(’my@host’,'486xxxxxxxx@text.plusgsm.pl’,message.as_string())
server.quit()

To by było wszystko, jako uwagę mogę dodać, że można wysyłać wiadomość również tak:

server.sendmail(’my@host’,'486xxxxxxxx@text.plusgsm.pl’,'wiadomosc’)

nie musimy wtedy używać modułu email.Message jednak brak jawnego podania w mailu pola To i From powoduje odrzucenie maila na bramkach PlusGSM.

Wystarczy już tylko dopisać wykonanie skryptu do crona wedle upodobań i prosty system powiadamiania gotowy. Ja miałem drobne perypetie z tym krokiem na systemie FreeBSD ale to już inna historia ;) Pozostaje tylko rozbudować ten skrypt o dodatkową funkcjonalność, aby dawał większe możliwości.

Kończąc życzę wszystkim, aby skrypt nie okazał się za bardzo przydatny, zatem jak najmniej smsów o treści PingTimeOut :)

5 komentarzy:

  1. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń
  2. Jeszcze raz. :)
    Żeby powyższe działało z bramką Plusa obecnie, warto dodać bezpośrednio po:

    message = email.Message.Message()

    linię:

    message["Message-ID"] = '<%s.qmail@cos.pl>' % str(time.time())

    (linię zmontowałem na podstawie generowanej przez mojego Qmaila oraz ID zgenerowałem z time.time() co jest rozwiązaniem najbardziej prostackim - ale nie wymaga ładowania datetime. Bo oczywiście, żeby było porządnie, trzeba by zbudować pole o formacie YYYYMMDDHHMMSS.nnnnn, ale chodziło mi tu bardziej po przekazanie istoty sprawy niż poprawność. :)

    OdpowiedzUsuń
  3. Wielkie dzięki za poprawkę, skrypt ostatni raz odpalałem wieki temu :)

    OdpowiedzUsuń
  4. Szczerze mówiąc, postanowiłem dziś podejść do tego bardziej solidnie, i po kilku chwilach zrodziła się bardziej aktualna i poprawna (na dziś) wersja nagłówka, oto kod:



    message = email.Message.Message()
    message["Date"] = email.Utils.formatdate(localtime=1)
    message["Message-ID"] = email.Utils.make_msgid()
    message["From"] = 'ja@cos.pl'
    message["Mime-version"] = "1.0"
    message["To"] = '48xxxxxxxxx@text.plusgsm.pl'
    message["Content-type"]="text/plain"
    message["Content-transfer-encoding"]="7bit"

    (7bit i plain dlatego, że głupia bramka i tak nie radzi sobie z UTF8, trudno się mówi).

    Niemniej powyższe definicje generują zarówno całkowicie poprawny Message-ID, jak i zgodny z RFC nagłówek Date:

    Mam nadzieję, że komuś się to przyda.

    OdpowiedzUsuń
  5. Dzięki za pomoc, sam kombinowałem dokładnie to samo, i zastanawiałem się, dlaczego z pythona to nie działa. Dzięki Twoim instrukcjom, zadziałało ^^

    bag

    OdpowiedzUsuń