function writeToLogFile()



  • Hallo, ich hab folgende Funktion geschrieben:

    function writeToLogFile($access, $ip, $user, $server, $version)
    {
    	$msg = date("[Y-m-d D H:i:s]") . "\t" . $access . "\t" . $ip . "\t" . $user . ((strlen($user) < 8) ? "\t" : "") . "\t\t" . $server . "\t" . $version;
    
    	$logfile = "LOG_" . date("M-Y") . ".txt";
    	$saveLocation = $logfile;
    
    	if(!$handle = @fopen($saveLocation, "a")) exit;
    	else{
    		if(@fwrite($handle, "$msg\r\n")===FALSE) exit;
    		@fclose($handle);
    	}
    }
    

    Diese funktioniert auch in 80 % der Fälle, nur manchmal kommt es vor,
    dass es die Logzeile nicht in eine neue Zeile schreibt,
    sondern einfach die letzte Zeile in im Logfile mit 'sternartigen' Zeichen überschreibt
    und erst dann die neue Logzeile dahinter einfügt.
    Ich kann mir das echt nicht mehr erklären,
    da es scheint, als ob das wirklich total zufällig geschieht, meistens gehts,
    aber es ist immer sicher, dass es mindestens zwei drei mal am Tag nicht geht.
    Hat irgendjemand ne Ahnung woran das liegen könnte??



  • Die Funktion ist nicht thread-safe.
    Es kann passsieren, dass ein Thread die Funktion aufruft und die Datei öffnet. Dann kommt ein zweiter Thread (in der gleichen Sekunde wie der Erste) und öffnet die Datei auch. Und dann fängt der erste Thread an zu schreiben und es kommt wieder ein Kontextswitch und vielleicht macht der zweite Thread auch etwas, aber schon längst ist das Verhalten undefiniert.
    Wird der Code in einer Webseite verwendet? Dann sind die zwei Threads halt zwei PHP-Instanzen, die durch einen zeitgleichen Besuch der Webseite durch den Apache gestartet werden.

    Lösungsvorschlag:
    Entweder synchronisierst du das Schreiben in die Datei per mutex oder per Filelock auf ein anderes File. Zweiterer Weg hätte den Vorteil, dass es auch unter Windows klappt. Bei den anderen multithreading-funktionen von PHP bin ich mir nicht so sicher.

    Noch ne Ergänzung: Wieso beendet die Logfunktion den PHP-Interpreter, wenn ein Fehler auftritt? Du willst doch nich, dass eine Loggingfunktion Probleme macht?



  • Hm da könntest du recht haben.

    Der Code liegt als Teil eines PHP Scripts auf meinem Webspace.
    Das Script wird von einem von mir (in C++) geschriebenen Programm benötigt, um nen Login abzufragen. Mein Programm ruft also praktisch beim starten dieses Script auf ( http:// ... /script.php?user=jemand&server=derserver&version=1111111 ), es wird überprüft ob der Benutzer erlaubt ist, und mein Programm kriegt halt dann die Antwort (allowed/denied), die das Script per echo() ausgibt, zurück.
    Dieser primäre Teil funktioniert ja auch bestens.

    Nur eben der sekundäre Teil, also die Logfunktion, macht wie bereits gesagt Probleme.

    Könntest du mir den Code zur Logfunktion eventuell so umschreiben, dass das ganze auch thread safe wird? Wie gesagt, ich brauch nur den ersten Aufruf, also fällt bei nem Aufruf in der gleichen Sekunde das Umleiten in ne zweite Datei weg. Es soll das ganze in diesem Fall dann eben einfach sein lassen, sodass zumindest der erste Aufruf normal geloggt wird, und nicht die letzte Zeile im Logfile mit kryptischen Zeichen überschrieben wird.

    Ich bedanke mich schon sehr im Voraus.


Anmelden zum Antworten