pyinotify - stellt nach n Stunden die Arbeit ein

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Hallo ich hab ein Problem mit einem pyinotify script.
Alles klappt wunderbar für ca 4-5h dann stellt das script seine Arbeit und macht nichts mehr.
Wenn man mit ps nachschaut läuft es noch, allerdings reagiert es nicht mehr auf neue Dateien.
Komm mit dem debug nicht mehr weiter wegen mangelner Ideen woran es liegen könnte, daher frag ich mal hier.

Hier mal das script, ist noch nicht ganz fertig erfüllt seine primär Funktion aber schon jedenfalls für n Stunden :/

Code: Alles auswählen

#!/usr/bin/python2.7
# Notifier example from tutorial
#
# See: http://github.com/seb-m/pyinotify/wiki/Tutorial
#
import pyinotify
import fnmatch
from os.path import basename
import smtplib
from time import strftime
import logging
import sys


mailto = 'my@mail.de'
mailacc = 'senderaccount@gmx.net'
smtppass = '*********'

#### DONT WORK  JET########
logger = logging.getLogger()
hdlr = logging.FileHandler('/tmp/dispo_debug.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.DEBUG)
########################

def folder ( event ):
	print "Folder Function"
	for n in event:
		if fnmatch.fnmatch ( event.lower(), '*hanse*'):
			return "Hanseservice"
		elif fnmatch.fnmatch ( event.lower(), '*intime*'):
			return "Intime"
		else:	
			return 'ERROR IN GET FOLDER'

def filename ( event ):
	print "Filename Function"
	return basename ( event )

def send_e_mail ( ifolder, ifilename, fpath):
	print "send_e_mail Function"
	server =smtplib.SMTP('mail.gmx.net')
	debug =	server.set_debuglevel(1)
	server.ehlo()
	server.starttls()
	server.ehlo
	server.login( mailacc, smtppass)
	header = 'TO:' + str(mailto) + '\n' + 'From:' + str(mailacc) + '\n' + 'Subject:Neue Datei >' + str(ifilename) + '< von ' + str(ifolder) + '\n'
	msg = header + '\n Die neue Datei finden sie unter' + fpath +'\n\n'
	server.sendmail(mailacc, mailto, msg)
	server.quit()
	debug_log( debug, fpath )

def debug_log ( debug , fpath ):
	print "Debug Function"
	timestamp = strftime( "%Y-%m-%d %H:%M:%S" )
	f = open ("/tmp/dispo_mail_debug_log", "a")
	f.write ('\n' + timestamp + '\n' + str(fpath) + '\n' + str(debug) + '\n')
	f.close()

wm = pyinotify.WatchManager()  # Watch Manager
mask = pyinotify.IN_CREATE  # watched events

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        print "Find File:", event.pathname
	ifolder = folder ( event.pathname )
	ifilename = filename (event.pathname )
	fpath=( event.pathname )
	send_e_mail( ifolder, ifilename, fpath)

handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)

hanse_inv = wm.add_watch('/home/hanse/INV', mask, rec=True)
hanse_umlagerung = wm.add_watch('/home/hanse/Umlagerung', mask, rec=True)
hanse_wa = wm.add_watch('/home/hanse/WA', mask, rec=True)
hanse_we = wm.add_watch('/home/hanse/WE', mask, rec=True)
intime = wm.add_watch('/home/intime', mask, rec=True)

#
#notifer.loop() ohne daemonize hat selbes Problem
#
try:
	notifier.loop( daemonize=True, pid_file='/tmp/dispo_mail.pid', stdout='/tmp/dispo_stdout.txt' )

except pyinotify.NotifierError, err:
	print >> sys.stderr, err 

Kann mir irgendwer sagen woran es liegt dass das script nach einigen Stunden die Arbeit einfach einstellt und nichts mehr macht, bzw was ich dagegen tun kann.
Gibt leider 0 Fehlermeldungen wenns es nicht mehr reagiert :(
Zuletzt geändert von taake am Mittwoch 30. November 2011, 11:02, insgesamt 1-mal geändert.
BlackJack

@taake: Also einen Fehler habe ich auf jeden Fall schon mal entdeckt: Du schliesst in der `debug_log()`-Funktion die Datei nicht. Theoretisch sollte das bei CPython trotzdem funktionieren, aber vielleicht gibt es praktisch ja doch Fälle wo dem Process dadurch die Filehandles ausgehen.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Danke für den Hinweis, schon korregiert und neu angeworfen, allerdings hab ich die debug_log() erst gebaut nachdem das erste Mal der Fehler aufgereten ist.
lunar

@taake: Woran merkst Du, dass keine Dateien mehr behandelt werden? Um wie viele Dateien und Verzeichnisse handelt es sich insgesamt?
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Also es handelt sich um 5 Verzeichnisse die ich beobachten will ob neue Daten von unseren Parternern auf unseren FTP Server gestellt werden, der schreibt dann denn Leuten ne Mail das ne neue Datei da ist die importiert werden möchte.

Merken das es nicht mehr geht tu ich daran, das ich ne neue Datei via touch erstellen kann ohne ne Mail zu bekommen, es passiert gar nichts mehr, die print ausgaben die beim durchlaufen des scripts eigentlich kommen müssten kommen auch nicht.
Also liegt das ganze brach, der prozess läuft allerdings noch.
BlackJack

@taake: Kannst Du mit ``print`` eingrenzen wo das hängt? Die Frage nach wievielen Dateien hast Du nicht beantwortet — vielleicht ist daraus resultierend auch die Anzahl der Mails insgesamt oder pro Stunde auch interessant. Möglicherweise hängt das ja beim Mail verschicken, denn viele Anbieter limitieren die Anzahl pro Stunde oder Tag.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Also daran liegt es eher weniger.
Wenns läuft kann ich da auch locker 30 Mails pro Minute durchjagen, habs schon probiert lief ohne Probleme.
Und das die print ausgaben nicht mehr kommen, schrieb ich bereits.
Im Schnitt kommen über den Tag verteilt cirka 4-8 dieser Dateien auf die das script reagieren soll.
Wenns beim Mailversand liegen würde, hätte ich das gesehen, 'notifer.loop()' ohne daemonzie betrieben hab, da sieht man dann auch den output der kommunikation mit dem gmx Webserver.

Wie geschrieben ich denke das script stellt die Arbeit ein und ich kann mir nicht erklären woran es liegt bzw. was ich dagegen tun kann.

Hab mir überlegt unabhänig von den events auf die er reagieren soll noch ne nen weiteres log zu machen wo er jede Minute nen timestamp in ne Datei schreibt, allerdings hab ich keine gute Idee wie ich das umsetzen kann.
time.sleep() scheint in dem Fall nicht die richtige Wahl zu sein, da ich das script ja nicht schlafen schicken will.
deets

Ich wuerde das skript runterkochen auf das absolute Minimum - nur deine File-events monitoren, und dann eine Zeile in ein logfile schreiben (oder auf stdout, und das dann wegpipen).

Dann kannst du sehen, ob dasselbe Verhalten auftritt, und es auf inotify eingrenzen. Kann ja durchaus ein Bug darin (oder im Kernel event system) sein.

Eine Frage haette ich noch - wie startest du das denn? Ist das Ding auch proper daemonisiert, oder ist das einfach auf der Kommandozeile gestartet. Da koennte es dann ja unter Umstaenden Probleme geben, wenn der Parent-Prozess verschwindet oder so.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Also ich habs mal komplett runtergestript bis aufs minimum.
Hat sich herausgestellt dass das Problem weiterhin besteht, er stellt den Dienst einfach nach einiger Zeit ein.
Hat Jemand ne Idee wo man noch ansetzen könnte?

Ich starte das script übrigens indem ich es direkt mit bash aus ner tty aufrufe.
BlackJack

@taake: Ich denke jetzt könntest Du Dich mit der Minimalversion und der Problembeschreibung an den/die Entwickler von pyinotify wenden.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Hab gerade nochmal bissel was umgeschrieben, hab jeden einzelnen Watch in nen eigenen thread ausgelagert.
Vielleicht hilft das, lass es jetzt das WE durchlaufen wenns klappt meld ich mich nochmal.
Benutzeravatar
jtschoch
User
Beiträge: 400
Registriert: Freitag 6. Mai 2011, 15:40
Kontaktdaten:

Villeicht macht GMX ein TimeOut oder
es ist begrennzt für solche langen Nutzungen.
------------------------------------------------------------------
Muss ja nicht an Python liegen!
Meine Webseite http://www.develos.de
Forum: http://www.develos.de/forum
Mein Minecraft-Server: jonel.minecraft.to [dynmap(:8123)] | Webseite: http://jonel-minecraft.tk
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jtschoch hat geschrieben:Villeicht macht GMX ein TimeOut oder
es ist begrennzt für solche langen Nutzungen.
Das kurze Versenden einer Mail würde ich jetzt nicht als "lange Nutzung" beschreiben.
Benutzeravatar
jtschoch
User
Beiträge: 400
Registriert: Freitag 6. Mai 2011, 15:40
Kontaktdaten:

Stimmt er logt sich ja immer wieder aus,
könnte aber trotzdem sein wegen der Serverbelastung,
wenn der server zu oft genutzt wird von GMX.
Meine Webseite http://www.develos.de
Forum: http://www.develos.de/forum
Mein Minecraft-Server: jonel.minecraft.to [dynmap(:8123)] | Webseite: http://jonel-minecraft.tk
deets

@jtschoch

Du redest hier Unsinn. Was ja nix neues ist. Der OP hat den Mail-Part schon laengst rausgeloest aus dem Skript. Und selbst wenn GMX timeouts haette, wuerden die einen Verbindungsabbruch oder eine ablehnende SMTP-Antwort bedeuten. Nicht eine ewig haengende, resourcen-konsumierende Verbindung.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Hat leider nichts gebracht das ganze nochmal umzuschreiben.
Python inotify scheint defintiv broken zu sein, hab beim project bescheid gesagt.
Vielleicht können die da was fixen.

Versuchs jetzt mir was mit os.system() bash und "inotifywait" zusammenzufrickeln.
Was dann hoffentlich auch mehrere Tage durchläuft ohne Probleme.

Also am Mailversand liegt es defintiv nicht, da der inaktiv war und es trotzdem nicht ging.
Das script selbst selbst läuft weiter, scheint also defintiv an der inotify implementierung in python zu liegen.

Hoffentlich wirds gefixt, war echt angenehm einfach.

Vielen Dank für eure Hilfe, wenn ich was von nem Entwickler hören sollte sag ich euch noch bescheid.
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

Interessant wäre noch zu erfahren auf was für einer Distribution du das versucht hast umzusetzen, woher das pyinotify stammt.

Ich habe das bisher einmal benutzt, und zwar auf einem Debian Lenny. Python und pyinotify kamen direkt aus den Debian-Quellen. Das hat problemlos, auch über Tage hinweg, funktioniert.
Dabei ging es es um eine Daemon der im Hintergrund läuft, über neue Dateien informiert wird (sich diese merkt) und nach dem schließen der Datei (fertig geschrieben, Upload kann dauern) Programme aufrufen die diese Datei als Input nutzen.
Wie gesagt, das ganze war relativ simpel und hat ganz gut funktioniert.


Gruß
Sparrow
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Also laufen tut das ganze auf nem x86 gentoo system.
Installiert ist via portage dev-python/pyinotify-0.9.2
lt. ebuild nimmt er das hier
http://seb.dbzteam.org/pub/pyinotify/re ... 9.2.tar.gz
lunar

@taake: Hast Du geprüft, ob pyinotify überhaupt die Ursache ist? Funktioniert "inotifywait" denn? Was ist denn die Ausgabe von "sysctl fs.inotify"? Was zeigt "ls -l /proc/${PID_DEINES_SKRIPTS}/fd"?

Edit: Nochwas: Gibt es bei der Ausführung Deines Skripts auffällig Einträge im syslog (meist "/var/log/messages", machmal auch "/var/log/syslog")?
Antworten