sys.stdout anstelle von print()

  • Hallo Experten

    um im Nachhinein zu prüfen ob ein Script unter crontab korrekt

    ausgeführt wird wollte ich die darin enthaltenden print
    statements in die Datei mylog1.log umleiten, damit ich sie später

    ansehen bzw. überprüfen kann ob das Script ausgeführt wurde..

    Wenn ich das Script

    direkt mit python relais_einzeltest.py ausführe erscheinen die

    print statements richtig in /home/pi/mylog1.log.

    Wenn dasselbe Script mit einer Zeitvorgabe in crontab ausgeführt wird

    erscheinen diese print statements in mylog1.log nicht, das Script läuft

    aber korrekt durch.

    ?????

  • Du musst den vollen Pfad in dein Script / in der crontab eintragen!

  • Und wir hatte doch schon den Schritt zu Python3 gemacht.


    Wenn du kontrollieren willst, ob deine regelmäßigen Autostarts funktionieren, dann könntest du crontabs mal auf die Seite legen und die aktuelle Variante verwenden: SystemUnits.


    chmod +x /home/pi/relais_einzeltest.py


    nano /etc/systemd/system/relais_einzeltest.timer

    nano /etc/systemd/system/relais_einzeltest.service

    Code
    [Unit]
    Description=Beschreibung
    
    [Service]
    ExecStart=/home/pi/relais_einzeltest.py

    systemctl enable relais_einzeltest.timer

    systemctl enable relais_einzeltest.service


    Mit 'start', 'stop' oder 'status' kannst du den Service steuern oder abfragen. Logs werden auch geschrieben.


    https://opensource.com/article/20/7/systemd-timers

    https://wiki.archlinux.de/title/Systemd/Timers

    https://www.howtogeek.com/6879…-at-startup-with-systemd/


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • vielen Dank für die Links zum Gebrauch von systemd timer. Habe die Vorteile

    gegenüber crontab begriffen, sehe aber für mein Vorhaben im Moment

    keinen Nutzen, ich möchte lediglich ein einziges Script täglich zu einer

    bestimmten Zeit ausführen, was mit dem Eintrag in crontab

    python relais_einzeltest.py

    funktioniert, der betreffende Leuchtkörper geht wie programmiert an und aus.


    Was nicht funktioniert, bzw. was mein Problem - wie eingangs geschildert -

    ist, ist dass die print statements unter crontab nicht in die Logdatei

    (mylog1.log) geschrieben werden, aber ohne crontab schon.

    Kann mir im Moment nicht vorstellen, dass das mit systemd geht, aber

    vielleicht liege ich da falsch ???

  • luemar Wo denkst Du denn das die Datei `mylog1.log` liegen soll? Der Pfad muss da ins `open()` mit rein. Beziehungsweise würde ich das `open()` und die ”Umleitung” nicht ins Programm schreiben, sondern in der crontab dafür sorgen, dass die Ausgaben in die Logdatei umgeleitet werden (``>>``). Auch da gilt: nicht darauf verlassen was denn das aktuelle Arbeitsverzeichnis sein mag und den vollen Pfad zur Logdatei angeben.


    Was das Protokollieren selbst angeht, da gibt's in der Standardbibliothek das `logging`-Modul. Für Anwendungen und Dienste nehme ich gerne das externe `loguru`-Modul.

    “The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents.” — Nathaniel Borenstein

  • ich möchte lediglich ein einziges Script täglich zu einer

    bestimmten Zeit ausführen

    Das macht mein Beispiel-Timer doch auch. Ich verstehe nicht wieso man sich dagegen so wehrt. :conf:


    Was das Protokollieren selbst angeht, da gibt's in der Standardbibliothek das `logging`-Modul. Für Anwendungen und Dienste nehme ich gerne das externe `loguru`-Modul.

    So Hinweise werden hier irgendwie überlesen:

    Der Namen log1 lässt eher darauf schließen, dass du nicht die Ausgaben von Python in einer anderen Datei haben möchtest, sondern dass du etwas wie das logging-Modul oder Loguru gesucht hast?


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • also ich "wehre" mich nicht gegen das Erstellen eines Timers

    in systemd. Ich fühle mich nur nicht sattelfest in Rasbian und

    crontab - auch ein Teil von systemd - ist mir z.Z. einfacher zu

    handhaben und vertrauter. Erstellen von service units ist kein

    Problem. Werde mich aber sicher damit auseinandersetzen.


    Das Loggen von print statements wie in meinem Script habe ich

    gegoogelt. Das kann ich sicher noch verbessern.


    Aber nochmals, ich verstehe nicht warum das Loggen bei direktem

    Ausführen meines Scripts funktioniert, beim Ausführen durch

    crontab aber nicht. Kann mir das jemand erklären ??

  • luemar ``open("mylog1.log", "a")`` heisst „öffne die Datei mit dem Namen »mylog1.log« im aktuellen Arbeitsverzeichnis“. Und das ist beim crond-Prozess ziemlich sicher ein anderes als wenn Du das manuell startest.

    “The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents.” — Nathaniel Borenstein

  • also ich bin wohl etwas schwer von Begriff:

    Bis jetzt hat nichts funktioniert.

    Habe es mit dem dem logging Modul mit einem ganz simplen Script

    versucht (kein crontab), das print statement erscheint zwar 3 mal

    aber die Datei mylog1.log bleibt leer:

    Code
    #!/usr/bin/env python3
    #import sys
    #import datetime
    #import time
    import logging
    
    logging.basicConfig(filename= '/home/pi/mylog1.log',level=logging.INFO)
    for i in range(3):
        logging.info('Hello World')
        print ('hello world')

    ich denke es liegt an den directories, kann das Problem aber nich

    lösen.

  • ja, das war's !!!

    in nano /home/pi/mylog1.log wird logging.info() korrekt

    ausgegeben.

    Leider - und das ist mein eigentliches Problem - nicht, wenn

    das Script unter crontab -e ausgeführt wird, wie z.B.:

    21 19 * * * /usr/bin/python3 /home/pi/test_script.py 

    Ich komme da einfach nicht zum Ziel.

  • Dann zeige doch bitte dein Script, vielleicht ist irgendwas nicht richtig (z.B absolute Pfade). Bei mir funktioniert folgendes Script ohne Probleme und schreibt jede Minute drei mal "Hello World" in das Log-File.


    Python: logging_test.py
     #!/usr/bin/env python3
    import logging
    
    logging.basicConfig(filename= '/home/synology/logging_test/my.log',level=logging.INFO, format='%(asctime)s %(message)s')
    for i in range(3):
        logging.info('Hello World')
        print ('hello world')


    Und hier der crontab -e Eintrag


    */1 * * * * /usr/bin/python3 /home/synology/logging_test/logging_test.py


    Und hier der Inhalt von my.log


  • Hallo,


    ich habe das jetzt auf meinem Laptop mit Fedora Betriebssystem nach gespielt.

    Skript:


    crontab -e:

    Code
    30 22 * * * /usr/bin/python3 /home/dennis/Dokumente/test.py

    Hinweis:

    Wichtig ist, dass am Ende der Tabelle ein Kommentar oder eine Leerzeile steht. Ähnlich wie die fstab muss die crontab mit einer Leerzeile enden!

    sudo systemctl restart crond.service


    mylog1.log geändert um 22:30:02:

    Code
    INFO:root:Hello World
    INFO:root:Hello World
    INFO:root:Hello World


    Also grundsätzlich funktioniert dein Vorhaben schon, eventuell muss du auch mal Schritt für Schritt beschreiben wie du vorgegangen bist.

    Ich denke nicht, dass es unter Fedora funktioniert und unter Raspberry OS nicht.


    Grüße

    Dennis


    Edit: Okay, jetzt sind wir immerhin schon zwei mit einem Erfolgserlebnis Steinardo^^

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Eventuelle Fehlermeldungen der Crontab lassen sich auch mit der Umleitung in eine Datei anzeigen, z.B.:

    Code
    21 19 * * * /usr/bin/python3 /home/pi/test_script.py >> /home/pi/cronausgabe.txt 2>&1

    (Edit: Möglicherweise aber erst, nachdem das Skript beendet wurde, falls es denn läuft.)



    Steinardo Das /1 für minütlich kannst Du übrigens weglassen, weil das Sernchen eh für alle Minuten steht. ;)

  • immer noch kein Erfolg:

    Den Code meines Scripts habe ich in thread #10 gepostet.

    Wenn ich Steinardo's Syntax in thread13 folge und meine Zeile 7 ändere in

    Code
    logging.basicConfig(filename= '/home/pi/test_script/mylog1.log',level=logging.INFO)

    bzw. den Namen meines Scripts einfüge funktioniert das Loggen in meine

    Logdatei mylog1.log wobei es keine Rolle spielt, ob ich diese mit
    nano /home/pi/mylog1.log oder nano mylog1.log öffne und

    zwar nur mit direktem Befehl zum Ausführen.


    Wenn ich aber noch das format-Argument hinzufüge:

    Code
    logging.basicConfig(filename= '/home/pi/test_script/mylog1.log',level=logging.INFO, format='%(asctime)s %(message)s')

    kommt diese Fehlermeldung:

    Traceback (most recent call last):

    File "test_script.py", line 7, in <module>

    logging.basicConfig(filename= '/home/pi/test_script/mylog1.log',level=logging.INFO, format='%(asctime)s %(message)s')

    File "/usr/lib/python2.7/logging/__init__.py", line 1554, in basicConfig

    hdlr = FileHandler(filename, mode)

    File "/usr/lib/python2.7/logging/__init__.py", line 920, in __init__

    StreamHandler.__init__(self, self._open())

    File "/usr/lib/python2.7/logging/__init__.py", line 950, in _open

    stream = open(self.baseFilename, self.mode)

    IOError: [Errno 2] No such file or directory: '/home/pi/test_script/mylog1.log'


    Wenn ich den Scriptnahme wieder entferne geht das Loggen.


    Aber wie auch immer, unter crontab - e geht nichts wobei ich zum Testen immer etwa

    die Zeit 2 Minuten nach meinem Eintrag eingebe relativ zur Zeitangabe an meinem PC.

  • Deine Fehlermeldung hat nichts mit der format-argument. Dein Pfad gibt es nicht. /home/pi/test_script/mylog1.log ist nicht /home/pi/test_script/mylog1.log. Deine Fehlermeldung lässt auch darauf schliessen das du dein Script mit python2 startest. Wenn ich den Fehler provoziere bekomme ich folgende Fehlermeldung.


    Code
    Traceback (most recent call last):
      File "logging_test.py", line 4, in <module>
        logging.basicConfig(filename= '/home/synology/logging_test/gibt_es_nicht//my.log',level=logging.INFO, format='%(asctime)s %(message)s')
      File "/usr/lib/python3.7/logging/__init__.py", line 1900, in basicConfig
        h = FileHandler(filename, mode)
      File "/usr/lib/python3.7/logging/__init__.py", line 1092, in __init__
        StreamHandler.__init__(self, self._open())
      File "/usr/lib/python3.7/logging/__init__.py", line 1121, in _open
        return open(self.baseFilename, self.mode, encoding=self.encoding)
    FileNotFoundError: [Errno 2] No such file or directory: '/home/synology/logging_test/gibt_es_nicht/my.log'


    Aufgerufen mit python2


    Code
    Traceback (most recent call last):
      File "logging_test.py", line 4, in <module>
        logging.basicConfig(filename= '/home/synology/logging_test/gibt_es_nicht//my.log',level=logging.INFO, format='%(asctime)s %(message)s')
      File "/usr/lib/python2.7/logging/__init__.py", line 1554, in basicConfig
        hdlr = FileHandler(filename, mode)
      File "/usr/lib/python2.7/logging/__init__.py", line 920, in __init__
        StreamHandler.__init__(self, self._open())
      File "/usr/lib/python2.7/logging/__init__.py", line 950, in _open
        stream = open(self.baseFilename, self.mode)
    IOError: [Errno 2] No such file or directory: '/home/synology/logging_test/gibt_es_nicht/my.log'


    Wie Dennis89 schon schreibt

    Also grundsätzlich funktioniert dein Vorhaben schon, eventuell muss du auch mal Schritt für Schritt beschreiben wie du vorgegangen bist.

    Ich denke nicht, dass es unter Fedora funktioniert und unter Raspberry OS nicht.

    Bitte beschreibe genau was du machst, welche Befehle du benutzt, etc.

  • nun endlich funktioniert es, die logging Ausgabe in mylog1.log und die

    print Ausgabe in cronausgabe.txt.

    Offensichtlich habe ich zu früh in mylog1.log nachgeschaut. Nachdem ich

    die Datei ca. 4 Minuten später und mehr öffnete, ware die Einträge da !

    Vieln Dank für Eutre Hilfe!!! :danke_ATDE:

  • muss nochmals nachhaken:

    im shebang meines Scripts steht python3. Warum sollte es mit
    Python2.7 gestartet werden ?


    Und warum ist /home/pi/test_script/mylog1.log nicht

    /home/pi/test_script/mylog1.log wenn es den Pfad

    sowieso nicht gibt ?

  • Entschuldige bitte, beim C&P habe ich nicht aufgepasst. Ich meinte /home/pi/mylog1.log und /home/pi/test_script/mylog1.log.

    Du schreibst ja das du mit nano /home/pi/mylog1.log das Logfile aufmachen kannst aber wenn /home/pi/test_script/mylog1.log im Script ist crashed es.


    Der shebang wird ja nur beachtet wenn das Script ausführbar gemacht ist und kein Interpreter angegeben wird. Du hast dein Script mit python aufgerufen. python ruft in einer standard PI Installation python2 auf. Python 3 wird mit python3 aufgerufen.


    Anyway, schön das es jetzt läuft. Magst du den Thread noch als "erledigt" markieren?