Benutzer:Leon/WikiCharts

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Ich habe, nach einer Idee aus der russischen Wikipedia, einen Seitenaufrufzähler erstellt, welcher nun ermöglicht, näherungsweise zu bestimmen, welche Artikel wie häufig aufgerufen werden. Das Progrämmchen wurde von Benutzer:Duesentrieb auf „WikiCharts“ getauft.

Neugierige...[Bearbeiten | Quelltext bearbeiten]

...können sich die Auswertung anschauen: [1]

Interessierte...[Bearbeiten | Quelltext bearbeiten]

...sollen erst erfahren, wie das Ganze funktioniert.

Dem Zähler zugrunde liegt der Gedanke, dass man per JavaScript den Artikelnamen an den Toolserver übertragen könnte und dort zählen. So wird das in der russischen Wikipedia gemacht: Ein JavaScript ruft eine Seite auf dem Toolserver auf, dort läuft ein Daemon, der die Zugriffe zählt und in die Datenbank einträgt. Die russische Wikipedia hat zwischen 5 bis 100 Zugriffe pro Sekunde. Der zählende Perl-Daemon hat den Datenbankserver mit dieser Masse bereits mehrfach gekillt.

Die deutsche Wikipedia hat bis zu 1000 Zugriffe pro Sekunde. Daher musste ich das Ganze effizienter gestalten. Ich habe also drei entscheidende Verbesserungen eingebaut.

Das JavaScript[Bearbeiten | Quelltext bearbeiten]

...ist auf MediaWiki:Pagecounter.js zu finden und wird in MediaWiki:Monobook.js eingebunden.

1.  var counter_factor = 600; 
2. 
3.  function pgcounter_setup()
4.  {
5. 	if(disable_counter == 0)
6. 	{
7. 		var url = window.location.href;
8. 		if(Math.floor(Math.random()*counter_factor)==42)  // the probability thing
9. 		{
10.			if(url.match(/\/wiki\//)) // do not count history pages etc.
11.			{
12.				var title = url.replace( /.*\/wiki\//, "" );
13.				var cnt_url = "http://pgcount.wikimedia.de/index.png?title=" + title + "&factor=" + counter_factor + "&wiki=dewiki";
14.				var img = new Image(); 
15.				img.src = cnt_url;
16.			}
17.		}
18.	}
19. }

Zeile 8 enthält die erste Verbesserung: Der Aufruf auf den Toolserver erfolgt nur mit einer Wahrscheinlichkeit von 1/Faktor (momentan 600). Der bekommt dadurch nur ca. einen in zwei Sekunden.

Das Auffangen der Zugriffe[Bearbeiten | Quelltext bearbeiten]

...erfolgt nicht über einen rechenintensiven Perl-Daemon (ich möchte diesen nicht schlechtmachen, da wurde wirklich viel Arbeit reingesteckt), sondern, Dank an Gregory Maxwell für die Idee, ganz einfach in den Apachelogs. U. a um dem Datenschutz gerecht zu werden und das Log regelmäßig leeren zu können (Plattenplatz), wurde mir eine Subdomain eingerichtet (pgcount.wikimedia.de), die auf den Toolserver zeigt. Der schreibt für diese Subdomain ein seperates Log, in welchem eine Zeile dann wie folgt aussieht:

[31/Jul/2006:10:20:31 +0000] "GET index.png?title=Ey_Mann,_wo_is'_mein_Auto%3F&factor=600&wiki=dewiki HTTP/1.1"

Das Zählen der Zugriffe[Bearbeiten | Quelltext bearbeiten]

...erfolgt über schnelle Kommandozeilentools, konkret awk und dem MySQL-client mysql. Hier muss ich Benutzer:Duesentrieb ganz besonders danken, ohne den ich ein dreihundertzeiliges langsames PHP-Script dafür missbraucht hätte, und alle Logeinträge gleichzeitig im Speicher gehabt hätte.

/usr/local/bin/gawk 'BEGIN {
	print \"prepare pageviews_dewiki from 
		\\\"INSERT INTO u_leon.de_articlestats SET stats_title = ?, stats_hits = ?,				stats_samples = 1 ON DUPLICATE KEY  UPDATE stats_hits=stats_hits+?,					stats_samples=stats_samples+?;\\\";\\n\" 
}

/\/index.png\?title=.*\&factor=[1-9][0-9][0-9]/{a[$4]++}
END{ 
	for(i in a) {
		x=i;sub(/^.*\/index.png\?title=/,\"\", x);
		y=x;sub(/^.*&factor=/,\"\", y);
		sub(/&wiki=.*/, \"\", y);
		sub(/&factor=.*/, \"\", x);
		sub(/\?.*/, \"\", x);
		gsub( \"/\\\"/\", \"%22\", x);
		gsub( \"\\\\\", \"%5C\", x);
		print \"set @title = \\\"\"x\"\\\"; set @hits = \"a[i]*y\"; set @factor = \"y\"; 
			set @samples = \"a[i]\"; 
			execute pageviews_dewiki using @title, @factor, @hits, @samples;\" 
	} 
}' /tmp/pgcount/access.log | /usr/local/mysql/bin/mysql

Die Einrückungen und Zeilenumbrüche sind hier nur der Übersichtlichkeit halber eingefügt.

Zum Eintragen in die Datenbank nutze ich prepared statements. Das Script bereitet zu Beginn ein solches vor, danach zählt es, wie oft welcher Artikel im Log vorkommt und erstellt eine Anweisung für dieses prepared statement für jeden Artikel. Das geht dann alles per Pipe in den MySQL-Client.

Die Auswertung[Bearbeiten | Quelltext bearbeiten]

...wird von einem PHP-Script übernommen. Auch hier hat mir Duesentrieb viel geholfen. Die linke Spalte zeigt die Aufrufe pro Tag an, geschätzt. Wenn im Apachelog ein "Hauptseite" vorkommt, wird in der Datenbank um den <Faktor> hochmultipliziert. Die Erhebung läuft seit dem 16. Juli 2006, in Zukunft werde ich aber monatliche Snapshots einführen, so dass man sich die Top 100 für jeden Monat anschauen kann.

± 2% sagt, dass der Fehler an der Zahl der Aufrufe ± 2% beträgt. Wenn der Fehler über 20% liegt, ist die Genauigkeit natürlich nicht mehr so schön, und über 100% schon gar nicht. Die angegebene Abweichung ist der Anteil, den der Radius des Konfidenzintervalls am Absolutwert des Eintrags hat (berechnet für 95% Konfidenz, ohne "Zurücklegen"). Danke an Philipendula für die Hilfe mit dieser Formel.

Die zweite Spalte sagt aus, wieviele Prozent aller registrierten Zugriffe auf diesen Artikel gehen, und die dritte zeigt den Titel an.

Die Tabelle wird immer zur vollen Stunde aktualisiert.

Viel Spaß mit eurem neuen Spielzeug.