Ausführliches Logfile

  • Hallo Eukalyptus,

    Deine Idee ist gut. Ich habe zwar nicht nach dieser UDF im englischen Forum gesucht. Doch ich habe kurz was eigenes gemacht.
    Der Trick ist wirklich, dass man die Rückgabewerte immer nur in eine Variable schreibt.

    Mittels einem Adlibregister Timer wird dann z.B. alle 1 Sekunde diese Variable gschrieben und geleert.
    Für 100'000 Werte benötigt dieses Script nun nur 1.2 Sekunden!

    Spoiler anzeigen
    [autoit]

    Global $sLogfile = ""
    Dim Const $LogfilePath = @ScriptDir & "\_Logfile.log"
    FileDelete($LogfilePath)

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_LogfileWriteTimer", 1000)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $Timer = TimerInit()
    For $i = 1 to 100000
    _AddToLogfile($i)
    Next
    $End = TimerDiff($Timer)
    _AddToLogfile($End)

    [/autoit] [autoit][/autoit] [autoit]

    _Exit()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _AddToLogfile($ReturnValueForLogfile)
    $sLogfile &= @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " : " & $ReturnValueForLogfile & @CRLF
    EndFunc ;==>_AddToLogfile

    [/autoit] [autoit][/autoit] [autoit]

    Func _LogfileWriteTimer()
    FileWriteLine($LogfilePath, $sLogfile)
    $sLogfile = ""
    EndFunc ;==>_LogfileWriteTimer

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _LogfileWriteTimer() ;Write the last time.
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Dabei habe ich herausgefunden, dass der Befehl

    [autoit]

    $sLogfile &= @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " : " & $ReturnValueForLogfile & @CRLF

    [/autoit]

    sehr schnell ist. Wenn man ihn allerdins in

    [autoit]

    $sLogfile = $sLogfile & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " : " & $ReturnValueForLogfile & @CRLF

    [/autoit]

    abändert, dauert das Faktor 5 bis 10 länger!

    So allerdings bin ich absolut zufrieden mit AutoIt!
    Was meint ihr zu der Geschwindigkeit?
    Grüsse Veronesi

  • Also ich denke das Problem dabei ist, deine Adlibregister funktion führt sich ja nur jede Sekunde aus

    [autoit]

    AdlibRegister("_LogfileWriteTimer", 1000)

    [/autoit]

    Also hast du denke ich mal maximal 2 Werte in die Datei geschrieben, oder?

    -EDIT- hach, man sollte auch das &= sehen... mein Kommentar hat sich erledigt ^^
    -EDIT2-
    Wenn du auf Geschwindigkeit gehst, solltest du evtl. mit dem Filehandle arbeiten.
    Teste einfach mal, ob in die Datei geschrieben wird, auch wenn das script abstürzt

  • Ob die Datei trotzdem geschrieben wird, weiss ich nicht.
    Das probiere ich lieber nicht aus, da man dann nie so sicher sein kann, was passiert.

    Evtl. kommt es auch darauf an in welchem Moment das Programm abstürzt und welches Betriebssystem und welche Service-Packs etc.

    Wenn schon ein Logfile, dann möchte ich das sauber machen.
    Ich denke 100'000 Werte schreiben in 1.2 Sekunden ist ein super Wert. Das ist mir genug schnell!

    Trotzdem vielen Dank!

  • Ich will deine Euphorie nicht bremsen, aber wenn ca.100'000 Werte in ca. 1 Sekunde geschrieben werden,
    und dein Programm crashed, sind evtl 99'999 Einträge verloren, weil sie ja noch nicht in der Datei stehen.

    Es kommt ja drauf an, wann die Adlib Funktion greift und in die Datei schreibt, in diesem Zeitfenster von 1ner Sekunde fehlen dir die Werte

  • Ja, das ist schon richtig.
    Aber ich logge ja in meinem richtigen Programm nicht 100'000 Werte pro Sekunde!

    Dies war nur ein Extremtest um die Geschwindigkeits(verluste) zu beurteilen.
    In der Realität sind es wohl zwischen 0.1 und 50 Werten, die pro Sekunde geloggt werden müssen, jenachdem, was der PC macht.

    Das ist absolut vertretbar!
    Danke!

  • Wenn du die Logs erst in einer Variablen zwischenspeicherst, dann ist fehlen im Extremfall (Crash) aber die Meldungen der letzten Sekunde. Daher sollte das Log schon direkt in die Datei geschrieben werden denke ich. Das dauert zwar etwa 2-3mal so lange, aber wenn die Logmeldungen bei einem Absturz helfen sollen, muss man das in Kauf nehmen oder?

    PS: Ich habe gerade das in meiner Sammlung gefunden:

    Spoiler anzeigen
    [autoit]

    Global $ghLOGDATA_FILE=-1, $giLOGDATA_LEVEL=0, $gfLOGDATA_OAER=False

    [/autoit] [autoit][/autoit] [autoit]

    Func _Log_Stop()
    ; ProgAndy
    $giLOGDATA_LEVEL = 0
    FileClose($ghLOGDATA_FILE)
    $ghLOGDATA_FILE = -1
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Log öffnen
    Func _Log_Start($sFile, $iLevel)
    ; ProgAndy
    $giLOGDATA_LEVEL = $iLevel
    $ghLOGDATA_FILE = FileOpen($sFile, 1)
    If Not $gfLOGDATA_OAER Then OnAutoItExitRegister("_Log_Stop")
    $gfLOGDATA_OAER = True
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Log schreiben
    ; iLevel mus <= level von _Log_Start sein, damit geschrieben wird
    Func _Log($sData, $iLevel = 1, $e=@error, $x=@extended, $l=@ScriptLineNumber)
    ; ProgAndy
    If $giLOGDATA_LEVEL >= $iLevel Then FileWrite($ghLOGDATA_FILE,'['&@YEAR&'/'&@MON&'/'&@MDAY&' '&@HOUR&':'&@MIN&'](line='&$l&', err='&$e&', ex='&$x&'): '&$sData&@CRLF)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Log schreiben, mit Rückgabewert.
    ; Dadurch z.B. ersetzen von $ergebnis = _Funktion() mit $ergebnis = _LogRet(_Funktion()) möglich
    Func _LogRet($sData, $iLevel = 1, $e=@error, $x=@extended, $l=@ScriptLineNumber)
    ; ProgAndy
    If $giLOGDATA_LEVEL >= $iLevel Then FileWrite($ghLOGDATA_FILE,'['&@YEAR&'/'&@MON&'/'&@MDAY&' '&@HOUR&':'&@MIN&'](line='&$l&', err='&$e&', ex='&$x&'): '&$sData&@CRLF)
    Return SetError($e, $x, $sData)
    EndFunc

    [/autoit]
  • Bis jetzt ist es noch nie vorgekommen, dass das Programm abgestürzt ist. Manchmal sind einfach gewisse Dinge nicht installiert worden. Aus dem Log konnte ich nun aber erkennen, dass das Profil des Benutzers mit Adminrechten (RunAs) nicht geladen werden konnte.

    Einmal das lokale Profil löschen, Script nochmals laufen lassen und gut war's. Manchmal hängt sich auch bei M$ ein Profil auf. (Gut bei 2'000 Profilen auf dem Server kann das schon mal ab und an vorkommen)

    Für mich stimmt das Logfile im Moment so. Aber für den schlimmsten Fehlerfall kann der User in einer bestimmten Settingsdatei einen Eintrag verändern und dann wird nach jedem Logeintrag gespeichert. Quasi der Debugmodus.

    Dann habe ich den Vorteil, dass es normalerweise schnell geht, aber im Fehlerfall kann man auf "ausführliches Loggen" umschalten.

    Damit ist der Auftraggeber vollständig zufrieden. Für ihn war es sowieso eher Nice-To-Have!

    Danke Euch allen.
    Grüße Veronesi

  • Wie wäre es einfach mit ConsoleWrite zu arbeiten und ein 2. Programm schreibt alles in ein Logfile?


    Das wurde schon vorgeschlagen. Da aber AutoIt-Unterprozesse über ConsoleWrite kommunizieren geht das schelcht.

  • Oh tut mir Leid, hab ich wohl überlesen...
    Die Möglichkeit wäre es noch OutputDebugString zu nehmen und dass dann mit einem externen Programm auszulesen, damit wäre
    immerhin dieses Problem behoben:

    Zitat

    Das wurde schon vorgeschlagen. Da aber AutoIt-Unterprozesse über ConsoleWrite kommunizieren geht das schelcht.

    Ich weiß nur grad nicht, wie man das wieder auslesen kann außer mit entsprechenden Debuggern.


    PS: Tjaja, Threads sind schon schön^^