Seite 1 von 2
Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 11:15
von Tobbel
Hey ho!
Also ist mein erster Post, verzeiht mir bitte falls ich nicht immer genau das sage was ein erfahrenern progger schreiben würde
Bin nun seit rund 2 Tagen an einem Problem dran und zwar:
Ich lese eine Status datei eines Überwachungsprogrammes ein ( evtl kennt das wer "Nagios"), dort such ich explizit nach einem text also
Code: Alles auswählen
status = open("status.dat", "r")
for line in status:
if "plugin_output=OK" in line:
Das funktioniert auch einwandfrei, jetzt muss ich allerdings im raum der nächsten 25 Zeilen nachprüfen ob sich dort ein zweiter benötigter text befindet.
Also in Pseudocode:
Code: Alles auswählen
status = open("status.dat", "r")
for line in status:
if "plugin_output=" in line:
if "text" in zeilen + 25: #genau hier ist das Prob...
Hab schon mehrere Ansätze gehabt mit *.readline/s(), auch ein missglückter counter war dabei... und bevor ich nun anfang die anfangs datei in kleiner Datein zu splitten wollte ich nachfragen ob es eine elegante Lösung für meine Idee/Problem gibt
Was ich noch dazu sagen sollte , ich hab erst vor 2-3 Tagen mit Python angefangen, also sind mir syntax etc noch nicht ganz geläufig
Grüßle Tobbel
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 11:36
von EyDu
Hallo und willkommen im Forum!
So könntest du das angehen:
Code: Alles auswählen
with open("status.dat") as fp:
match = None
for index, line in enumerate(fp):
if match is None:
if line.startswith("plugin_output="):
match = index
elif match + 25 <= index:
....
Vielleicht verrätst du uns aber mal, was du eigentlich vor hast und postest eine Beispieldatei. Vielleicht lässt sich da noch einiges einfacher lösen.
Sebastian
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 12:36
von Tobbel
Das is schonmal ne idee, bin ich garnicht drauf gekommen es ersteinmal selber nen Index zu machen
Also zu der Datei:
Code: Alles auswählen
servicestatus {
host_name=localhost
service_description=Current Load
modified_attributes=2
check_command=check_load!5.0!4.0!3.0!10.0!6.0!4.0
check_period=24x7
notification_period=24x7
check_interval=5.000000
retry_interval=1.000000
event_handler=
has_been_checked=1
should_be_scheduled=1
check_execution_time=0.004
check_latency=0.065
check_type=0
current_state=0
last_hard_state=0
last_event_id=19
current_event_id=21
current_problem_id=0
last_problem_id=8
current_attempt=1
max_attempts=4
state_type=1
last_state_change=1347004244
last_hard_state_change=1346916726
last_time_ok=1347017144
last_time_warning=0
last_time_unknown=1346942507
last_time_critical=1347004184
plugin_output=OK - load average: 0.00, 0.00, 0.00 # <-- das ist das erste Anzeichen nach dem ich suche, danach sollen die weiteren zeilen geprüft werden
long_plugin_output=
performance_data=load1=0.000;5.000;10.000;0; load5=0.000;4.000;6.000;0; load15=0.000;3.000;4.000;0;
last_check=1347017144
next_check=1347017444
check_options=0
current_notification_number=0
current_notification_id=0
last_notification=0
next_notification=0
no_more_notifications=0
notifications_enabled=1
active_checks_enabled=1
passive_checks_enabled=1
event_handler_enabled=1
problem_has_been_acknowledged=0 # <-- das hier muss nach OK abgefragt werden
acknowledgement_type=0
flap_detection_enabled=1
failure_prediction_enabled=1
process_performance_data=0
obsess_over_service=0
last_update=1347007258
is_flapping=0
percent_state_change=0.00
scheduled_downtime_depth=1 # <-- das hier muss auch nach OK abgefragt werden
__LB_SERVER=0;192.168.121.10
__LB_PORT=0;7297
__LB_CUSTOM=0;
__LB=0;__lb
}
Die Datei hat davon ca. 1000 abteilungen mit diesem
service..{
...
}
Un innerhalb dieser sparten muss ich die ergebnisse überprüfen,
danke auf jeden fall mal, ich werds so mal ausprobieren
Schlussendlich will ich eine Überprüfung machen ob eben ein servicestatus ein Problem, also ein nicht "OK", hat das weder das Attribut " scheduled_downtime_depth=1" noch "problem_has_been_acknowledged=1" hat.
Falls auch nur 1 service gefunden wird der das alles erfüllt soll ein befehl zum betreiben einer USB leuchte an ein Terminal gesendet werden, was kein problem darstellt

Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 13:03
von EyDu
Dein Ansatz mit den Zeilen ist viel zu kompliziert und zu fehleranfällig. Das kannst du doch alles prima in einem Dictionary abbilden:
(ungetestet)
Code: Alles auswählen
def parse(filename):
with open(filename) as fp:
obj = None
for line in (l.strip() for l in fp):
if line.endswith("{"):
obj = {}
elif line.startswith("}"):
yield obj
obj = None
elif obj is not None and line:
name, value = line.split("=", 1)
obj[name] = value
for obj in parse("test.dat"):
if (obj["plugin_output"].startswith("OK") and
obj["problem_has_been_acknowledged"] == "1" and
obj["scheduled_downtime_depth"] == "1"):
....
In obj steckt dann immer ein ganzes servicestatus-Object, auf dessen Elemente du einfach über den Namen zugreifen kannst.
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 13:24
von Tobbel
Ok, also vorneweg gesagt, mit obj usw. hab ich bisher noch nichts gemacht,aber so wie ich das vom lesen her verstehe :
der obere teil zerlegt die status.dat in kleine servicestatus teile, in denen ich dann weiter mit dem untern (ab "for obj..." ) arbeiten kann, soweit richtig hoffe ich
Nun hab ich ncoh zwei Fragen:
1. wird jeder teil in einem neuen objekt gespeichert so dass python eine neue datei ( im bsp. test.dat) erstellt und dort zwischenspeichert um es später wieder zu ersetzen?
Oder dient das quasi als Wildcard und in dem "for obj.." teil wird nacheinander jedes servicestatus teil durchgearbeitet?
2. der Befehl "??.startswith("??")" bezieht sich dieser direkt auf den ersten Buchstaben/Zahl, wenn ja gibt es soetwas für quasi ??.inline("??") sodass auch davor noch ein WOrt stehen darf?
Danke das du mir so schnell hilfst, du rettest mir damit wahrscheinlich mein Wochenende

Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 13:45
von EyDu
"obj" ist kein besonderes Feature, sondern nur ein schlecht gewählter Name. "items" oder "servicestatus" ist passender.
Zu 1: Wie kommst du darauf, dass eine neue Datei erstellt wird? Die bei parse angegebene Datei wird geöffnet und untersucht. die parse-Funktion ist ein Generator, welcher die servicestatus-Elemente liefert.
Zu 2: x in y
Hast du eigentlich das
Tutorial oder dessen
Übersetzung durchgearbeitet? Deine Fragen sind alles mehr oder weniger Grundlagen.
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 14:11
von Tobbel
Noch kein Online-Tutorial o.ä. gelesen, hab hier das Buch "Python 3 Object oriented Programming" von dusty phillips und die sache ist die, es wird gut erklärt wie die ganzen sachen funktioniern, jedoch kaum was zur syntax, zu befehlen, oder gar beispielen...
Daher hab ich mir die befehle usw. eher selber zusammengetragen, daher kenn ich auch noch nicht viele... dachte auch blöderweise das dass ein einfacheres Projekt ist bei dem ich nicht so weit in die Materie muss
B2T:
okay, dann werd ichs mal probieren, danke auf jedenfall
Vielen dank ncoheinmal

Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 15:52
von Tobbel
So nun meld ich mich nocheinmal
Hab jetzt eine weile mit den möglichkeiten rumprobiert und muss leider sagen das ich mit dem zweiten Ansatz zu keinerlei ergebniss kam, bekomm egal was ich mach, ja auch nach google..., diesen Fehler:
Code: Alles auswählen
File "lampe2.py", line 32, in <module>
Main(sys.argv[1:])
File "lampe2.py", line 22, in Main
for obj in parse("status2.dat"):
File "lampe2.py", line 11, in parse
for line in (l.strip() for l in fp):
ValueError: I/O operation on closed file
mit dem zweiten Ansatz komm ich soweit durch, jedoch bekomm ich das "Zeilen-zählen" nicht gebacken...
zwei ansätze hatte ich, die aber entweder in beiden fällen fehlerlos liefen, aber mir nicht das gewünschte ergebnis lieferten...
das ist mein Code , Hilfe ist erwünscht, am liebsten für diese Variante
Code: Alles auswählen
#!/usr/bin/env python
import time
import commands
import sys
def Main(argv):
i = 0
while i < 1:
OK = 0
WARNING = 0
CRITICAL = 0
UNKNOWN = 0
ACKNOW = 0
SCHEDU = 0
with open("/home/tweber/status.dat") as fp:
match = None
for index, line in enumerate(fp):
if match is None:
if "plugin_output=" in line:
if "OK" in line:
match = index
okay = match
OK = OK + 1
match = None
elif "WARNING" in line:
match = index
WARN = match
WARNING= WARNING + 1
match = None
elif "CRITICAL" in line:
match = index
CRIT = match
CRITICAL = CRITICAL + 1
match = None
elif "UNKNOWN" in line:
match = index
UNKN = match
UNKNOWN = UNKNOWN + 1
match = None
elif WARN + 10 <= index:
if "problem_has_been_acknowledged=0" in line:
print "AH2!"
match = None
fp.close()
i = i +1
print "UNKNOWN"
print UNKNOWN
print "WARNING"
print WARNING
print "OK"
print OK
print "CRITICAL"
print CRITICAL
# print "SCHEDU"
# print SCHEDU
# print "ACKNOW"
# print ACKNOW
if __name__ == '__main__':
Main(sys.argv[1:])
Grüßle, Tobi

Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 16:32
von Hyperion
Hui... viel zu viel Copy und Paste Programmierung

Hab leider keine Zeit da zu rezensieren.
Was war denn an EyDus Ansatz so magisch, dass Du den nicht weiter verfolgst?
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 17:40
von Tobbel
Hab jetzt eine weile mit den möglichkeiten rumprobiert und muss leider sagen das ich mit dem zweiten Ansatz zu keinerlei ergebniss kam, bekomm egal was ich mach, ja auch nach google..., diesen Fehler:
Nein magisch war sie nicht, nur leider hat es nicht funktioniert da bei mir der Parser nie startete, sondern sich immer mit der netten fehlermeldung verbschiedet hat, wie ich schon im vorherigen Post geschriebn habe...
Was meinst du mit zu viel copy/paste Programmierung, nur weil ich 3 Zeilen von EyDu kopiert habe und mir dann nicht die Mühe gemacht hab einen eigenen namen einzufügen?
mfg Tobi
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 17:51
von EyDu
Tobbel hat geschrieben:Nein magisch war sie nicht, nur leider hat es nicht funktioniert da bei mir der Parser nie startete, sondern sich immer mit der netten fehlermeldung verbschiedet hat, wie ich schon im vorherigen Post geschriebn habe...
Dann zeig doch mal den Code dazu, nur die Fehlermeldung ist etwas wenig. Auf Grund des Fehlers würde ich vermuten, dass du die Datei irgendwo in der for-Schleife schließt oder dass die for-Schleife nicht im with-Block enthalten ist.
Tobbel hat geschrieben:Was meinst du mit zu viel copy/paste Programmierung, nur weil ich 3 Zeilen von EyDu kopiert habe und mir dann nicht die Mühe gemacht hab einen eigenen namen einzufügen?
Du hast da einige Blöcke, welche alle nahezu identisch aussehen. Da kann man viel zusammenfassen.
Re: Frage zu dateien lesen
Verfasst: Freitag 7. September 2012, 18:25
von Tobbel
Das geht nun leider nicht, hab nur die obrige Variante von der Arbeit mitgenommen, das mit dem parser liegt dort auf der festplatte
realistisch gefragt: macht es sinn an meiner obigen idee festzuhalten, oder nicht? bzw ist es "einfacher" auf die andere methode?
Re: Frage zu dateien lesen
Verfasst: Samstag 8. September 2012, 12:56
von EyDu
Tobbel hat geschrieben:realistisch gefragt: macht es sinn an meiner obigen idee festzuhalten, oder nicht? bzw ist es "einfacher" auf die andere methode?
Gegenfrage: hältst du es für sinnvoll eine lange, unübersichtliche, mehr schlecht als recht programmierte, fehleranfällige, schwer zu erweiternde und gegen diverse Paradigmen verstoßende Funktion zu benutzen und eine robuste kurze Lösung zu verwerfen?
Re: Frage zu dateien lesen
Verfasst: Sonntag 9. September 2012, 20:34
von Tobbel
Na wenn du es so sagst dann werde ich mich morgen mal deinem Vorschlag näher widmen und bei eventuellen mich hier wieder melden , vielen dank jedenfalls noch einmal

Re: Frage zu dateien lesen
Verfasst: Montag 10. September 2012, 11:08
von Tobbel
So da bin ich wieder, saß nun den ganzen morgen dran und komm nicht weiter...
Zu Anfangs hatte ich KeyErrors, die sind nun weg aber hab nun keinerlei Erfolg....
Code: Alles auswählen
def auslesen(status):
with open("/home/tweber/status.dat") as statuspart:
servicestatus = None
for line in (l.strip(" ") for l in statuspart):
if line.endswith("{", 1, len(line)):
servicestatus = {}
elif line.startswith("}", 0, len(line)):
yield servicestatus
servicestatus = None
elif servicestatus is not None and line:
name, value = line.split("=", 1)
servicestatus["plugin_output"] = value
servicestatus["problem_has_been_acknowledged"] = value
servicestatus["scheduled_downtime_depth"] = value
def Main(argv):
print "hallo"
for servicestatus in auslesen("/home/tweber/status.dat"):
print "das hier?"
if (servicestatus["plugin_output"].startswith("OK", 0, len(servicestatus["plugin_output"])) and # oder "OK" in servicestatus["plugin_output"]
servicestatus["problem_has_been_acknowledged"] == "0" and
servicestatus["scheduled_downtime_depth"] == "0"):
green()
else:
print "hallo?"
off()
if __name__ == "__main__":
Main(sys.argv[1:])
green(), off() sind fehlerfreie codeteile, die jedoch nichts hiermit zu tun haben.
Wenn ich den Code ausführe kommt keinerlei Fehlermeldung, jedoch greift das Programm aber auch nicht in die bereiche die nach "for servicestatus in auslesen..." zu, bzw. kann mit dem variablen-namen servicestatus nichts anfangen, hatte auch schon versucht servicestatus zuvor als global zu definieren, machte jedoch keinen sinn da dies ja von "yield" übernommen wird, kann mir irgendjemand helfen? Ich steck hier echt fest und würde mich über einen Ratschlag sehr freuen
Bin mir auch nicht sicher ob das
Code: Alles auswählen
elif servicestatus is not None and line:
name, value = line.split("=", 1)
servicestatus["plugin_output"] = value
servicestatus["problem_has_been_acknowledged"] = value
servicestatus["scheduled_downtime_depth"] = value
sinn macht, da von meinem Verständnis das ja eigentlich der Code "servicestatus[name]", so wie ihn EyDu gepostet hat, übernehmen müsste ...
Hilfe...
Gruß Tobi
Re: Frage zu dateien lesen
Verfasst: Montag 10. September 2012, 11:54
von sparrow
So ein paar Print-Anweisungen könnten dir beim Debuggen helfen, damit du siehst wo was wirklich passiert.
Du stripst nur Leerzeichen weg. Warum? Das steht so auch nicht in dem Beispiel von EyDu. Dadurch bleiben aber ander Whitespaces drin. Eine Zeile endet mit \n, dann kannst du nicht mehr darauf testen ob eine Zeile mit } endet.
strip(), Danach sollte es funktionieren.
Und
sollte
sein.
Re: Frage zu dateien lesen
Verfasst: Montag 10. September 2012, 12:18
von Tobbel
Super , vielen vielen Dank! Das hat es gebracht! Ich hatte halt "open" immer in Verwendung mit spezifischem Pfad oder Dateinamen gelesen/gesehen, aber nachdem das geändert war hat es funktioniert!
und das mit dem strip(" ") hatte ich irgendwo aufgeschnappt und ausprobiert, dass das, nun wo du es sagst, natürlich nicht alles stripped hab ich nun auch verstanden. Danke nocheinmal
Jedoch bekomme ich keines der erwünschten Ergebnisse, könnte das in Zusammnhang mit
Code: Alles auswählen
servicestatus["plugin_output"] = value
servicestatus["problem_has_been_acknowledged"] = value
servicestatus["scheduled_downtime_depth"] = value
anstatt
zusammenhängen? Oder eher an Fehlern die sich woanders im Code verstecken?
Gruß Tobi
Re: Frage zu dateien lesen
Verfasst: Montag 10. September 2012, 12:22
von sparrow
Gibt es eigentlich noch andere Blöcke die in der Datei stehen können?
servicestatus { leitet gerade genauso einen neuen Servicestatus ein wie weißwurstgrütze {. Unter Umständen könnte es robuster sein, nicht nur auf eine abschließende { in einer Zeile zu schauen, sondern die ganze Zeile zu vergleichen. Ggf. muss man dann auch über ein Flag festhalten ob man sich gerade in dem korrekten Block befindet und ansonsten das schließende } ignorieren. //Edit: Das mit dem Flag ist natürlich Blödsinn, dafür kann man hier ja servicestatus verwenden, das dann nur in einem Block nicht None ist.
Aber wenn das nicht vorkommen kann, ist alles gut.
Re: Frage zu dateien lesen
Verfasst: Montag 10. September 2012, 12:37
von Tobbel
Ja es gibt andere, die sind nur z.B. Hoststatus o.ä genannt ,jedoch ist der inhalt identisch und soll auch ausgewertet werden, daher ist das in diesem fall sogar gut
Habe eben noch meinen Beitrag von zuvor editiert, evtl weis jemand noch etwas darüber

Re: Frage zu dateien lesen
Verfasst: Montag 10. September 2012, 12:44
von sparrow
Was glaubst du denn was die Zuweisungen dort machen?
Du setzt bei jeder Zeile deren Wert für drei verschiedene Schlüssel im Dictionary. Bei jeder Zeile. Egal welche kommt.
Der Code von EyDu hat hingegen für jede Zeile ein Schlüssel-Wert-Paar im Dictionary angelegt, über das man später sehr einfach an den Inhalt kommt.