access.log auslesen - und unter Bedingungen Variable erhöhen.

Klappspaten

Grünschnabel
Hallo!

Folgendes Problem. Ich habe eine Log-Datei, in der Informationen in dieser Form gespeichert sind.

195.238.250.5 - - [01/Jun/2001:00:05:54 -0700] "GET /index_1.gif?V=1&R=sbgenergy.net/photovoltaik/p_9_g&B=peg_pege.org-g-1 HTTP/1.0" 200 10253 "http://www.sbgenergy.net/photovoltaik/p_9.htm" "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"

Die für mich relevanten Informationen habe ich fett gemacht. Es ist zum einen der Pfad samt Dateinamen, zum Anderen die übertragende Größe in Byte.

Die Logdateien werden in der Form access-JJJJMM.log abgelegt und liegen im Ordner "logfiles".

Ich möchte jetzt folgendes Verfahren umsetzen:

Suche Datei und Pfad, die identisch mit der Variable $eins sind. & Prüfe, ob die Bytezahl 2/3 der Größe $eins_groesse ausmacht.
- Wenn ja: Erhöhe $eins_couter um 1
Wenn alle Einträge gefunden wurden, mache mit nächster Access-Datei weiter (Anfang: access-200811 - Ende: entsprechende Logdatei des aktuellen Monats)

Wenn das Script durchlaufen wurde, sollen also in $eins_counter alle Einträge für die Datei in $eins vorliegen, die mindestens 2/3 der Größe von $eins_counter enthalten. Die Variablen $eins und $eins_counter seien vorgegeben.

Leider kenne ich mich überhaupt nicht aus mit dem "hin und herspringen" in Zeilen. Kann mir da jemand weiterhelfen?

Vielen Dank!
 
Eine Datei kannst du mit file('filename.log'); Zeilenweise als Array einlesen:

PHP:
$fileAsArray = file('path/to/file.log');

foreach($fileAsArray as $oneLine) {
    echo $oneLine;
    /* do something */
}

Oder mit einem File-Handler, also sozusagen "von Hand" öffnen und einlesen:

PHP:
if($fileHandle = fopen('path/to/file.log')) {
    while(!feof($fileHandle)) {
        $oneLine = fgets($fileHandle);
        echo $oneLine;
        /* do something */
    }
    fclose($fileHandle);
}

(ersteres schon nur aus performance Gründen vor zu ziehen)

Einen Ordner kannst du mit der Standard-PHP-Library (SPL), welche schon in PHP5 enthalten ist, ganz leicht durchlaufen:

PHP:
function search($path, $recursive = true) {
	$dir = new RecursiveDirectoryIterator($path);
	$dir_r = array();

	foreach($dir as $file) {
		if(!$file->isDir()) {
			/* do something*/
		} elseif($file->isDir() && $recursive) {
			$dir_r[] = $file;
		}
	}

	if($recursive) {
		foreach($dir_r as $dirs) {
			search($dirs);
		}
	}
}

Zum die jeweiligen Zeilen auszulesen empfehl ich RegEx (ereg(), eregi()), die Variablen bzw. den Counter hoch zu zählen sollte kein Problem sein - oder?

Weiterführende Links Funktionen:
http://www.php.net/file
http://www.php.net/fopen
http://www.php.net/fgets
http://www.php.net/ereg
http://www.php.net/eregi

Weiterführende Links SPL:
http://www.php.net/~helly/php/ext/spl/
http://php.net/class.recursivedirectoryiterator

Good n8 ;)
 
Hallo!

Vielen Dank für die Hilfe - genau weiß ich aber noch nicht bescheid, aber das liegt definitiv an meiner Beschränktheit.

Wenn ich allein schon den ersten Baustein "allein" teste, gibt er mir einfach die komplette Log aus.

Ich habe nochmal nachgedacht und den Zweck des Programms weiter zugeschnitten. Ich rufe den Counter auf über counter.php?id=1&q=128&date=200811&byte=111111. Damit suche ich nach einer Datei 1 (die Dateien heißen download1_128.mp3, download2_96.mp3 - also erst Nummer und dann Qualität). Das heißt mit dem obigen Beispiel suche ich Aufrufe der Datei download1_128.mp3 in der Logdatei access-200811.log. Wenn der Eintrag gefunden wird, wird geprüft, ob der Zugriff mindestens 2/3 der eingegebenen Bytegröße umfasst, wenn ja, wird der Counter um eins erhöht.

Das müsste weit einfacherer sein, oder?

Leider fehlt mir trotzdem deiner hervorragenden Schilderungen der Ansatz :(

Danke!

LG,
David
 
Hallo!

Ich habe mich mal rangesetzt, allerdings funktioniert ein Teil noch nicht. Der Ausschnitt:

PHP:
// Datei auslesen
$accessarray = file($access);
foreach($accessarray as $zeile) {
// Teile die Zeile in einzelne Segmente.
$elementearray = explode(" ", $zeile);
// Prüfe, ob Element enthalten ist.
if(strpos($elementearray[5],$dateiname)==true)
{
$i++;
}
}
echo $i;

Die Erläuterung:

Der Zustand vor dem Aufruf: Die Variable $access enthält den Dateipfad zur einer Logdatei (z.B. ../logfiles/access-200812.log).

Das Logfile liegt in dieser Form vor:
206.196.125.91 - - [01/Dec/2008:00:02:14 +0100] "GET /feed/ HTTP/1.1" 200 10535 "-" "BlogSearch/2 +http://www.icerocket.com/"
(Durch den 6. Arrayeintrag erhalte ich die fettgedruckte Passage.)

Wenn dieser Teil des Arrays den gesuchten Dateinamen enthält (Variable $dateiname), dann wird der Counter um eins erhöht.

Das ganze läuft für jede Zeile, die ganze Datei ab. Am Ende wird der Wert für $i ausgegeben.

Das Script produziert keine Fehler, es wird aber immer eine 0 ausgegeben. Warum?

Vielen herzlichen Dank!
 
Zurück