Montag, 27. Juli 2009

"memtest86+" - meine Rettung...

Diese Woche hatte ich zahlreiche Schreckminuten - eine Kernelpanic nach der nächsten... obwohl genau diese Konfiguration eine Uptime von >450 Tagen hatte und immer problemlos funktioniert hat.

Ich habe den Linux-Kernel des Hosts auf meinem VServer-System getauscht (von 2.6.22.18 auf 2.6.26.2) und auch das Update von Debian "Etch" nach "Lenny" vollzogen.

Stutzig wurde ich als der neue Kernel auch ein "Segfault" nach dem nächsten (verschiedene!) meldete...

Ein "memtester"-Aufruf im laufenden Betrieb unter Linux brachte sehr schnell eine Kernelpanic... Ein memtest86+ bestätigte meine Vermutung: Nach wenigen Sekunden hatte memtest86+ schon RAM-Fehler festgestellt (im Bereich um 305MB).

Nach dieser Erkenntnis habe ich den ersten RAM-Riegel ausgebaut und den 2ten in die erste Bank gesteckt. Dann nochmal einen memtest86+ und einen memtester unter Linux gemacht - alles ohne Probleme. Jetzt läuft mein Server wieder mit mageren 1000MB RAM - aber er läuft wieder.

Fazit: Auch wenn man Markenspeicher eines renommierten Herstellers verwendet kann es nach 3-4 Jahren auch zu Problemen kommen - oder die Staubschicht auf dem RAM und der RAM-Bank war etwas zu hoch ;)

Und zum Abschluss noch ein Kernel-Zitat:
"Eeek! page_mapcount(page) went negative! (-1)".

Mittwoch, 15. Juli 2009

Tip: Firefox unter Linux und Backspace

Wer mal einen Windows-Benutzer an seinem Linux-Rechner gesehen hat (ja die soll es ja auch noch vereinzelt geben) dem fällt evtl. das Firefox/Backspace-Problem auf. Der Windows-Firefox-Benutzer drückt häufiger die Backspace-Taste und erwartet anscheinend den Sprung auf die vorige Seite.

Das ist per Default in der Linux-Variante des Firefox-Browsers deaktiviert. Aktiviert werden kann dieses Verhalten in "about:config" unter "browser.backspace_action". Hier einfach den Wert "0" (anstatt "2" oder >1) eintragen und fertig.

Weitere Informationen:

Dienstag, 14. Juli 2009

Tip: Tomcat 5.x Encoding-Problematik...

Das Encoding-Problem ist wohl vielen bekannt - ich wollte mir auch schon ein "Schei* Encoding" T-Shirt bestellen...

Im Apache Tomcat 6 reichte bei mir immer ein
request.setCharacterEncoding("UTF-8");
bei folgendem Seitenkopf in der JSP
<%@ page pageEncoding=”UTF-8″ contentType=”text/html; charset=UTF-8″%>
und ich konnte die Anfrageparameter in UTF-8 ohne Probleme auslesen.

Natürlich sollte man das wie z.B. im Spring-Framework wenn möglich in einen eigenen Servlet-Filter (siehe CharacterEncodingFilter) auslagern.

Beim Tomcat 5.x hatte ich mit diesem Vorgehen leider kein Glück. Weder die Context-Konfigurationsoptionen "URIEncoding" noch "useBodyEncodingForURI" in der Konfigurationsdatei brachten Besserung. Dieses Problem hatten aber wohl schon mehrere Anwender - siehe hier.

Bisher konnte ich das Problem leider nur auf folgendem Weg lösen:
String firstname = request.getParameter("firstname");
if (firstname != null) {
firstname = new String(firstname.getBytes("ISO-8859-1"),"UTF-8");
}
In diesem Fall konvertiere ich den Parameter von "ISO-8859-1" nach "UTF-8". Das sollte laut Tomcat FAQ auch kein Problem darstellen, da das Default-Encoding bei Servlets laut dem FAQ auch "ISO-8859-1" sein sollte:
Default Encoding for POST

ISO-8859-1 is defined as the default character set for HTTP request and response bodies in the servlet specification (request encoding: section 4.9 for spec version 2.4, section 3.9 for spec version 2.5; response encoding: section 5.4 for both spec versions 2.4 and 2.5). This default is historical: it comes from sections 3.4.1 and 3.7.1 of the HTTP/1.1 specification.


Update 14.07.2009: Ich konnte mit folgender Testseite alle drei Tomcat-Versionen:
  • 5.0.28
  • 5.5.27
  • 6.0.20
erfolgreich testen. Bei allen Versionen ergab der Test das gleiche Verhalten. Meine Encoding-Testseite funktionierte problemlos wenn nicht vor dem "setCharacterEncoding" ein Anfrage-Parameter abgefragt wurde.

Wirklich komisch - ich muss nochmal genau nachforschen warum das ältere Projekt im Tomcat 6.x problemlos mit dieser Variante funktionierte und bei Tomcat 5.x Probleme bereitet hatte.

Update 15.07.2009: Das Rätsel ist gelöst! eine jar-Datei hat zu diesem Phänomen bei dem alten Projekt geführt. In meinem Fall eine jar-Datei des CMS FirstSpirit namens "fs-access.jar". Wenn diese aus dem "WEB-INF/lib"-Verzeichnis entfernt wird und "setCharacterEncoding" verwendet wird funktioniert auch im Tomcat 5.x alles wie erwartet. Evtl. ist die "fs-access.jar" in diesem Fall eine veraltete Version. Warum der Tomcat 5.x damit ein Problem hat und der Tomcat 6.x nicht ist mir aber immer noch ein Rätsel.

Update 15.07.2009 / 2: Die Kontext-Konfiguration "URIEncoding" wirkt sich nur auf das URI-Encoding aus! d.h. das muss verwendet werden wenn man die Parameter z.B. im Querystring übergibt (HTTP-Methode GET). Wenn das in der server.xml konfiguriert wurde kann man sich das Umwandeln von "ISO-8859-1"-Zeichenfolgen nach "UTF-8" sparen.

Weitere Informationen:

Freitag, 29. Mai 2009

Internet-Zensur



Verhindert die Internet-Zensur und unterzeichnet einfach die ePetition des Bundestags.

Dienstag, 28. April 2009

Kleine Warnung vor Ubuntu 9.04...

alle die daran denken das neue Ubuntu 9.04 verwenden zu können sollten lieber noch etwas warten (@Sven: man sollte also wirklich besser etwas länger warten). Auf meinem System wurde schon das zweite Mal die EXT3-Partition unschön verunstaltet - und das in einer Woche!

Womöglich handelt es sich um diesen Fehler. Ich werde jetzt mal wieder einen Kernel der 2.6.27er-Serie verwenden um zu prüfen ob man dann wieder vernünftig arbeiten kann...

Update 02.05.2009: das Problem ist bis jetzt mit einem Kernel der Serie 2.6.27 (Version 2.6.27-14) nicht mehr aufgetreten. Der neue Kernel 2.6.28-11 scheint das Problem verursacht zu haben.

Update 15.06.2009: ich habe jetzt gute Erfahrungen mit dem Kernel 2.6.29 gemacht. Diesen kann man hier finden. Das Problem scheint aber in Verbindung mit der WLAN-Karte zu stehen - bei einem normalen Rechner hatte ich bisher keinerlei Probleme mit dem 2.6.28er Kernel. Ich habe eine "Intel Corporation PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (rev 61)" in meinem Thinkpad. Weitere Infos bzgl. 2.6.29er-Kernel und Intel WLAN-Karten findet man hier.

Freitag, 17. April 2009

Tip: MySQL - Linux, Windows, Mac OS - Tabellennamen

üble Sache: bei der MySQL auf Windows oder Mac OS-Systemen spielt die Groß- und Kleinschreibung der Tabellen (per Default) keine Rolle. Auf einem Linux-System aber schon! Wenn man also ein Datenbank-Abzug (mysqldump) auf einem Mac OS oder Windows macht und spielt es auf einem Linux-System ein kommt es unter Umständen zu Problemen (u.a. Tabellennamen in Constraints).

Das musste ich kürzlich auch erfahren - Gruß an Frank ;)

Mein Tip: immer die Tabellennamen und Spalten komplett in Kleinschreibung realisieren. Man kann auch mit der Variablen lower_case_table_names experimentieren.

Weitere Informationen:

Mittwoch, 1. April 2009

Die Programmierung, unendliche Weiten... Java: Math.log(0) = -Infinity (double)

Die Unendlichkeit ist so ein Thema für sich. Ich habe heute einen Fehler in der Java-Komponente JFreeChart gemeldet. Es kommt zu einer niemals endenden while-Schleife, da das Ergebnis von Math.log(0) auf meinem System -Infinity (Variablentyp: double) ist und das in einer while-Schleife verwendet wird.
Bei einem Kollegen mit Mac OS als Betriebsystem und dem gleichen Quelltext führt das aber komischerweise nicht zum Fehler - werde Ihn mal fragen was Math.log(0) bei Ihm liefert :)

Hier meine Fehlerbeschreibung:

Summary: endless loop in LogAxis class

Description:

JFreeChart Version 1.0.12
OS: Linux (Kernel: 2.6.27-14)
JVM: sun-java 1.6.0_10-b33
Architecture: x86_64

I get an endless loop in LogAxis.refreshTicksVertical method. This method
calls calculateLog(getLowerBound())-method. getLowerBound() returns 0.0d
and calculateLog calls Math.log on number 0. the result of Math.log(0) =
-Infinity on my system and this is the cause of the endless loop in
LogAxis.refreshTicksVertical - while (current <= end) -
current = -Infinity - is every time true.
I have added a zero (0) check to calculateLog and now everything seems to
work.

A colleague with Mac OS operating system does not have the problem with
the same code.

The class LogarithmicAxis seems to work out of the box - seems to have a
zero check already included (SMALL_LOG_VALUE = 1e-100).


Hier der Link zum Ticket bei sourceforge: link

Update: auf dem Mac gibt Math.log(0) auch -Infitity.

Sonntag, 29. März 2009

Tip: Maven 2, Unit-Test Ausführreihenfolge

Das Maven 2-Plugin "surefire" wird verwendet um die Unit-Tests zu starten. Wie ich festgestellt habe kann es auf verschiedenen Plattformen (Linux, MacOS, ...) zu verschiedenen Ausführreihenfolgen dieser Tests kommen. Um das zu vermeiden kann man ein JUnit "TestSuite" erzeugen und im maven nur noch "TestSuiten" ausführen lassen.

Ein JUnit-TestSuite kann z.B. so aussehen:
   1 package testproject.tests.dao;
2
3 import org.junit.runner.RunWith;
4 import org.junit.runners.Suite;
5
6 @RunWith(Suite.class)
7 @Suite.SuiteClasses({
8 UserTests.class,
9 FolderTests.class
10 })
11
12 public class DAOTestSuite {
13 // the class remains completely empty,
14 // being used only as a holder for the above annotations
15 }

Erst werden die Tests in der Klasse "UserTests" (Zeile 8) und anschließend die Tests in der Klasse "FolderTests" (Zeile 9) ausgeführt.

In der Maven 2-Konfiguration (pom.xml) kann man dann die Konfiguration für das Surefire-Plugin wie folgt anpassen (Zeile 13-17):
   1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3
4 <!-- ... -->
5
6 <build>
7 <!-- ... -->
8 <plugins>
9 <plugin>
10 <groupId>org.apache.maven.plugins</groupId>
11 <artifactId>maven-surefire-plugin</artifactId>
12 <version>2.4.2</version>
13 <configuration>
14 <includes>
15 <include>**/DAOTestSuite.java</include>
16 </includes>
17 </configuration>
18 </plugin>
19 </plugins>
20 </build>

"Nested Set" mit Hibernate und Spring

Das Modell "Nested Set" kann verwendet werden um Baumstrukturen mithilfe von Mengen in einer relationalen Datenbank zu speichern.

Man denkt bei einem Baum direkt an Dinge wie z.B. das Dateisystem: Ein Verzeichnis kann mehrere Unterverzeichnisse und diverse Dateien beinhalten. Diese Parent/Child-Beziehung (von den Verzeichnissen) kann man am einfachsten in der relationalen Datenbank folgendermaßen abbilden:
Tabelle: FOLDER
+----+-------------+-----------+
| ID | NAME | PARENT_ID |
+----+-------------+-----------+
| 1 | Parent1 | NULL |
| 2 | Child1 | 1 |
| 3 | Child2 | 1 |
| 4 | Parent2 | NULL |
| 6 | Child2 | 4 |
| 7 | ChildChild1 | 6 |
| 8 | Child1New | 4 |
+----+-------------+-----------+

Die in einem Verzeichnis enthaltenen Dateien müssen natürlich mit einer Relations-Tabelle realisiert werden. z.B.:
Tabelle: FOLDER_FILES
+-----------+-------------+
| FOLDER_ID | FILE_ID |
+-----------+-------------+
| 1 | 2 |
| 2 | 3 |
+-----------+-------------+

Jetzt kommt der Kunde und möchte z.B. nur noch die Verzeichnisse sehen die Dateien beinhalten. Das hört sich erstmal sehr einfach an - nur haben wir das Problem, dass ein Verzeichnis keine Dateien beinhaltet aber in einem Unterverzeichnis Dateien zu finden sein könnten. Wir müssten also Teilmengen selektieren können. Genau zu diesem Zweck kann das "Nested Set"-Modell verwendet werden.

Ein einfacheres Modell ist "Materialzed path" (Pfad-Modell) - hier wird zu jedem Knoten (in diesem Beispiel Verzeichnis) der komplette Pfad in eine zusätzliche Spalte gespeichert:
Tabelle: FOLDER
+----+-------------+---------+-----------+
| ID | NAME | PATH | PARENT_ID |
+----+-------------+---------+-----------+
| 1 | Parent1 | .1. | NULL |
| 2 | Child1 | .1.2. | 1 |
| 3 | Child2 | .1.3. | 1 |
| 4 | Parent2 | .4. | NULL |
| 6 | Child2 | .4.6. | 4 |
| 7 | ChildChild1 | .4.6.7. | 6 |
| 8 | Child1New | .4.8. | 4 |
+----+-------------+---------+-----------+

Nun kann man einen kompletten Teilbaum mit folgender SQL-Abfrage erhalten:
SELECT * FROM FOLDER WHERE PATH LIKE '.4.%'
Hier selektiert man das Verzeichnis "Parent2" inklusive aller Kinder.

Dieses Pattern ist mit Hibernate relativ einfach zu realisieren. Einfach eine zusätzliche Property/Spalte "PATH" hinzufügen und einen Interceptor schreiben, der vor dem Schreiben in die RDBMS den "Path" pro Element ermittelt.

Leider gibt es beim Modell "Materialized path" einige Restriktionen - u.a. die Länge der PATH-Spalte restriktiert die Verzeichnisbaumtiefe, die Performance auf eine Text-Spalte mit LIKE ist nicht optimal u.v.m

Das führt uns zum Modell "Nested Set". In diesem Blogbeitrag wurde das Prinzip sehr einfach und verständlich erklärt - deshalb werde ich mich hierzu nicht weiter auslassen (DRY-Prinzip). Ich werde mich hier auf die Implementierung in Spring und Hibernate konzentrieren.

Das Resultat in der Datenbank sieht dann wie folgt aus:
Tabelle: FOLDER
+----+-------------+-----------+-----------+---------+----------+
| ID | NAME | PARENT_ID | NS_THREAD | NS_LEFT | NS_RIGHT |
+----+-------------+-----------+-----------+---------+----------+
| 1 | Parent1 | NULL | 1 | 1 | 6 |
| 2 | Child1 | 1 | 1 | 2 | 3 |
| 3 | Child2 | 1 | 1 | 4 | 5 |
| 4 | Parent2 | NULL | 4 | 1 | 8 |
| 6 | Child2 | 4 | 4 | 2 | 5 |
| 7 | ChildChild1 | 6 | 4 | 3 | 4 |
| 8 | Child1New | 4 | 4 | 6 | 7 |
+----+-------------+-----------+-----------+---------+----------+

Hier handelt es sich um eine spezielle "Nested set"-Implementierung ist. Es gibt neben den Spalten "NS_LEFT" und "NS_RIGHT" noch die Spalte "NS_THREAD".

Um hier einen Teilbaum zu erhalten genügt folgende SQL-Abfrage:
SELECT * FROM FOLDER WHERE NS_THREAD = 4 AND NS_LEFT BETWEEN 1 AND 8

Die Implementierung des Interceptors, des Modells sowie die Hibernate-Konfiguration könnt Ihr hier begutachten.

Was man also von einem "Einzeiler" aus Rails, CakePHP und anderen Frameworks kennt ist bei Hibernate wirklich ziemlich komplex zu implementieren. Hier stellt sich die Frage ob Hibernate das nicht etwas einfacher für den Benutzer (Programmierer) machen sollte.

Weitere Links zum Thema:

Freitag, 13. März 2009

"Freitag der 13." Server-Upgrade (dist-upgrade)

Ich habe es gewagt an einem "Freitag den 13." ein Update von einigen meiner Linux-VServer von Debian 4.0 ("Etch") auf Debian 5.0 ("Lenny") zu machen.

Zu meiner Überraschung lief das ohne größere Probleme. Hier ein paar Notizen was so aufgetreten ist:

Neues Layout der Konfiguration von Apache2
Unter /etc/apache2/ hat sich einiges getan. u.a. ist die Datei /etc/apache2/apache2.conf kürzer geworden und einiges aus dieser Datei ist in das Verzeichnis /etc/apache2/conf.d gewandert. Das finde ich wirklich besser als vorher.

klogd mit sysklogd machten im Linux-VServer Probleme
klogd wollte im VServer einfach nicht starten. Hierfür gibt es eine einfache Lösung: einfach stattdessen rsyslog verwenden. Man kann sogar in der Datei /etc/rsyslog.conf den Eintrag "imklog" auskommentieren, da ein Linux-VServer ja kein Kernel-Logging benötigt.

neues PHP5 memory_limit
die php.ini von PHP5 hat jetzt ein memory_limit von 128M

Trac 0.11
Trac hat mich etwas mehr Zeit gekostet, da sich die Konfiguraton gegenüber der Version 0.10 etwas geändert hat. Vorher habe ich Trac in Verbindung mit FastCGI verwendet. Bei der Version 0.11 habe ich mich für modpython entschieden. Natürlich musste ich noch das WebAdmin-Plugin aus meinem "EggCache" löschen, da dieses Plugin seit 0.11 Bestandteil von Trac geworden ist.
Die Trac "Datenbank" muss mit dem Programm trac-admin und dem Kommando "upgrade" auf den neuesten Stand gebracht werden. Man sollte auch noch das Kommando "wiki upgrade" verwenden um die Standard-Wiki-Seiten auf die neue Version zu heben.

Subversion
Bei Subversion lief bis auf ein älteres Repository alles ohne Probleme. Das besagte Repository hatte das "bdb"-Layout, verwendete also das Berkeley-DB Backend und kam noch aus der Migration von Debian 3.1 ("Sarge"). Jetzt gab es beim Zugriff über den Apache (mod_dav_svn) eine Fehlermeldung. Als ich ein Dump (via svnadmin) von diesem Repository machen wollte kam ein bdb-Versionskonflikt Version 4.4/Version 4.6 zutage.
Abhilfe schaffte hier ein "svnadmin recover". Hiernach konnte ich ein "svnadmin dump" von dem Repository machen. Dann habe ich ein neues Repository angelegt (natürlich wie empfohlen "fsfs") und habe den Dump eingefahren. Et Voilà... das Repository funktioniert jetzt wieder tadellos.

Der Rest
Die restlichen Programme wie munin, mercurial, apt-cacher usw. machten beim Upgrade keinerlei Probleme.

Jetzt habe ich "nur" noch 6 Linux-VServer mit Debian 4.0 ("Etch") die ich dann auch noch irgendwann mal migrieren sollte... Im November gibt es wieder einen "Freitag den 13." - bis dahin habe ich hoffentlich schon die Zeit gefunden und alle VServer brav migriert.

Samstag, 7. März 2009

Das Leben ist ungerecht

Meine "bessere Hälfte" hat ein G1 (Android Plattform) bekommen (beruflich).

Das G1 ist wirklich super einfach zu bedienen - für ein Linux-System ;)

Was mich an dieser Android-Plattform reizt:
  • offenes/freies Linux-System
  • Programme lassen sich einfach mit Java programmieren
  • kostenloses/freies SDK
  • viele tolle Programme


Es gibt für diese relativ neue Plattform schon viele schöne Programme: z.B. Chatclients, Barcode-Scanner, DynDns-Client ... und sogar einen SSH-Client! Was jetzt noch fehlt ist eine Shell - am liebsten die zsh.

Übrigens: das G1 (aktuelle Firmware 1.1) läuft wohl mit einem Linux-Kernel 2.6.25.

Weitere Links:

Mittwoch, 4. März 2009

Tip: Server-Konfigurationsdateien in einer verteilten Versionsverwaltung

Das Problem
Konfigurationsdateien auf einem Server (i.d.R "/etc") ändern sich häufiger - und man möchte eine Historie - wann, was, warum modifiziert wurde. Das Problem wird noch schlimmer wenn mehrere Personen einen Server konfigurieren. Person A sollte wissen wann, was und warum Person B z.B. die Webserverkonfiguration modifiziert hat.

Welches SCM
Zuerst dachte ich an Subversion, da ich dieses SCM schon von der Programmierung kannte.

Folgende Punkte sprechen aber dagegen:
  • Subversion erzeugt in jedem Verzeichnis in der "Working Copy" ein ".svn"-Verzeichnis
  • die Geschwindigkeit bei vielen Dateien ist bei Subversion "nicht der Renner"
  • das Subversion-Backend ("Dateisystem") wird schnell sehr groß
  • das Konzept der "Working Copy" (welche erst ausgecheckt werden muss) und dem zentralen Repository ist hier leider etwas umständlich

Lösung: eine verteilte Versionsverwaltung.

Für diesen Zweck habe ich mir folgende verteilte Versionsverwaltungen angesehen:


Entscheidung: Ich habe mich für Mercurial aus folgenden Gründen entschieden:
  • einfache Verwendung
  • gute Performance, Repository-Größe klein
  • integrierter Webserver


Wie wird es gemacht
Schritt 1: man initialisiert ein neues Repository im "Root" des Dateisystems ("cd /"). Das geschieht mit dem Kommando "hg init". Nun legt Mercurial ein .hg-Verzeichnis in / an (es wird aber wirklich nur ein einziges Verzeichnis angelegt!).

Schritt 2: Dateien aus "/etc" zum Repository hinzufügen (unter Versionskontrolle stellen) geht mit dem Kommando "hg add /etc".

Schritt 3: Mit einem "hg commit" werden die neu hinzugefügten Dateien ins Repository übertragen.

Hier noch ein paar nützliche Kommandos:
Status abfragen: "hg status -amrd" (added, modified, removed, deleted)

Dateien umbenennen: mit "hg rename QUELLE ZIEL" kann man dann Dateien umbenennen. Man sollte also anstatt "mv" in Zukunft einfach dieses Kommando verwenden.

Dateien löschen: mit "hg remove DATEI/VERZEICHNIS" kann man die Datei oder das Verzeichnis aus der Versionierung nehmen. Ohne Parameter löscht "hg remove" auch die lokale Datei oder das Verzeichnis. Wenn man nur die Datei oder das Verzeichnis aus der Versionskontrolle nehmen will diese aber lokal behalten möchte sollte man "hg remove -Af DATEI/VERZEICHNIS" verwenden.

Unterschiede ansehen: mit "hg diff DATEI/VERZEICHNIS" kann man sich den Unterschied zwischen der lokalen Version und der im Repository befindlichen Version ansehen.

Repository für andere zugänglich machen: den eingebauten kleinen Webserver kann man mit "hg serve" starten. Dann kann man über "http://IP:8000" auf das Repository zugreifen. Hier ein paar Screenshots:







Repository "klonen": mit dem Kommando "hg clone http://URL ZIEL" kann man eine Repository-Kopie erstellen.

Grafischer Repository-Browser: sogar ein grafischer Repository-Browser ist bei Mercurial enthalten. Diesen bekommt man mit dem Kommando "hg view":



Konfiguration: Es gibt eine globale Konfiguration in "/etc/mercurial/hgrc" und pro User eine im Home-Verzeichnis "~/.hgrc". Mehr Informationen hierfür gibts mit "man hgrc".

Shell completion: Mercurial liefert wohl auch eine zsh-Completion mit. Dazu evtl. in einem folgenden Blog-Beitrag mehr.

Debian: Wer wie ich immer noch Debian Etch verwendet findet eine aktuellere Version von Mercurial im Backports-Reporitory.

Übrigens: das Projekt FSVS ist mir auch in den Sinn gekommen. Ich fand die Bedienung zu kompliziert und das Programm verwendet das SVN-Backend, was meiner Meinung nicht die beste Wahl hierfür ist. Dieses Programm berücksichtigt dann noch die Dateirechte und Benutzer/Gruppe. Das kann die hier vorgestellte Lösung nicht.

Update 14.03.2009: Wie ich heute gesehen habe gibt es auch das Projekt etckeeper das man mit mercurial, git, darcs und bzr verwenden kann. Es bietet Paketmanager-Integration und speichert Metadaten (u.a. Rechte) der Dateien mit ab. Sehr interessante Sache - das werde ich mal versuchen.

Weitere Links:

Dienstag, 3. März 2009

Tip: FritzBox-Verbindungsstatus mit Nagios überwachen

Ich habe mal mein nagios2-UPNP-Skript zur Überwachung der FritzBox-Verbindung hier publiziert. Der Quellcode ist nicht der Beste - für diese Aufgabe reicht er aber :)

Hier noch ein kleiner Screenshot aus nagios als "Beweis":


Wie man sieht ist das UPNP-Protokoll gar nicht schlecht... es muss nicht immer SNMP sein.

Wer weitere Infos zum Thema FritzBox sucht sollte mal hier vorbeischauen.

Montag, 2. März 2009

Tip: Server-Überwachung mit Visualisierung

Ich verwende seit ca. 2 Jahren zusätzlich zur Nagios-Überwachung meiner Server auch munin. Munin zeichnet kontinuierlich Daten auf und erzeugt schöne Grafiken daraus. So kann man z.B. feststellen, wann die CPU am wärmsten war oder wie stark die Datenmenge auf der Festplatte über einen Zeitraum zunimmt.

Hier ein paar Beispiele:




Hier kann man sehen, dass meine Daten auf der Festplatte innerhalb eines Jahres (02/2008 bis 02/2009) ziemlich zugelegt haben. Gut zu wissen, dass diese Steilkurve die Backup-Partition mit diversen rsnapshot-Ständen ist :)


...und hier wie die Temperatur zwischen Juni und August "ein Hoch" hat. Auch hier geht der Graph von 02/2008 bis 02/2009.

Die Installation von munin ist sehr einfach. Man installiert einfach auf den Server das Paket munin und für die zu überwachenden Knoten das munin-node Paket. Dann muss man dem Server nur noch die Knoten in der Datei "/etc/munin/munin.conf" mitgeben und fertig. Auf den munin-nodes kann man dann die einzelnen Plugins konfigureren. Tip für Debian-Benutzer: es können noch zusätzliche Plugins mit dem Paket munin-plugins-extra installiert werden.

Samstag, 28. Februar 2009

Tip: neuere FritzBox-Firmware-Versionen fragen "Referrer" ab

Wer kennst das nicht: Man möchte was an der FritzBox zuhause (per Remote) einstellen (z.B. eine Port-Freigabe hinzufügen) und verbindet sich mit SSH auf den "Heimserver" und macht via "SSH Local Port Forwarding" eine Anfrage auf das FritzBox-Webfrontend.

Vor einiger Zeit hat das auch noch super funktioniert. Die neueren Firmware-Versionen fragen aber den Referrer des Browsers ab. Wenn man jetzt via SSH-Tunnel auf die FritzBox zugreift schickt der Browser leider den falschen Referrer mit (z.B. vom localhost). Daraufhin zeigt die FritzBox eine leere Seite im Browser.

Um der FritzBox einen anderen Referrer vortäuschen zu können kann man das FireFox-Plugin RefControl verwenden. Als Referrer stellt man in diesem Plugin für diese Seite einfach "http://" ein und aktualisiert die Seite - et voilà: Man kann sich nun wieder an der FritzBox anmelden.

@Marcin: das funktioniert auch mit Putty unter Windows ("SSH Local Port Forwarding"). Jetzt hast Du deinen Tip für Windows-Benutzer :)

Dienstag, 24. Februar 2009

Grails 1.1 RC1-Test mit maven 2 erfolgreich!


Eben habe ich Grails 1.1 RC1 mal installiert, ein Projekt angelegt und getestet. Bei der Installation von Grails sind die Umgebungsvariablen JAVA_HOME und GRAILS_HOME wichtig uns müssen gesetzt sein.

Hiernach wollte ich die maven 2-Integration testen. Hierfür muss in ~/.m2/settings.xml folgendes eingetragen werden:
<settings>
  <pluginGroups>
    <pluginGroup>org.grails</pluginGroup>
  </pluginGroups>
</settings>
Danach kann man mit dem Kommando "mvn grails:create-pom -DgroupId=<m2-groupId>" eine maven pom.xml erzeugen lassen. Hier kann man dann die Abhängigkeiten pflegen und danach "mvn eclipse:eclipse" ausführen. Ich hatte den MySQL-JDBC-Treiber als Abhängigkeit hinzugefügt - hat alles super geklappt.

Das Grails Eclipse Plugin war anfangs etwas "mürrisch". Ein Grails-Projekt in Eclipse kann man einfach als "Java Application" starten. Hier verlangte Eclipse aber explizit die Einstellung von JAVA_HOME und GRAILS_HOME.

Als Rails-Fan finde ich das Konzept von Grails super. Wenn man dann auch noch alle Java-Bibliotheken, Frameworks und Tools (à la maven) verwenden kann - noch besser.
Meine "Lieblinge" unter den Java Frameworks (Spring, Hibernate) werden von Grails ja schon (intern) verwendet.

Mit der Programmiersprache Groovy konnte ich mich bisher noch nicht 100%ig anfreunden - das kommt aber bestimmt noch, wenn ich etwas mehr Zeit investiere :)

Weitere Links:
  1. Grails Eclipse Plugin
  2. Grails Maven Plugin
  3. Grails 1.1 RC1 Release Notes

kuriose Sache: Ubuntu nvidia-glx-177 mag Grails-Homepage nicht

Das ist sehr kurios: wenn man den nvidia-glx-177-Treiber (properitärer Treiber von NVidia) unter Ubuntu verwendet bekommt man beim Besuch der Grails Homepage einen 2-5 Sekunden-Freeze des Systems und mächtig CPU-Last.
Zuerst hatte ich diverse Firefox-Erweiterungen in Verdacht... doch das war nicht das Problem. Ich habe diesen Bug-Report (#289964) gefunden.

Nach der Installation von nvidia-glx-180 und einem Neustart funktioniert die Grails Homepage "wie geschmiert".

Ja, ja - properitäre Software ist schon was Tolles ;)

Update: übrigens ist der
nvidia-glx-180-Treiber (180.11 momentan in Ubuntu Intrepid) eine Beta-Version!

Update 2: man kann den Fehler wohl auch mit folgender Einstellung und den nvidia Treibern (177) beheben:
nvidia-settings -a InitialPixmapPlacement=0 -a GlyphCache=1
Mehr Infos dazu gibt es in diesem Bugreport: #232197

Montag, 23. Februar 2009

Tapestry 5 Web-Framework

Ich lese gerade ein Buch über das Web-Framework Tapestry 5. Wer schonmal ein Java-Projekt mit JSP, JSTL realisiert hat weiss, dass das nicht wirklich Spaß macht - und ziemlich aufwendig ist.
Wenn Ihr auch von JSF (1.x) nicht so begeistert seit kann ich Euch Tapestry nur empfehlen.



Mein "Spiel-Projekt" wird Spring 2.5 und Tapestry 5 verwenden - in Kürze hoffentlich mehr.

Tip: Linux Swapnutzung

Wer auch etwas mehr RAM in seinem Rechner hat fragt sich manchmal vielleicht auch warum soviel Daten in den Auslagerungsspeicher auf der Festplatte (swap) ausgelagert werden - und soviel "cache" verwendet wird.
Ab dem Linux Kernel 2.6 kann man das Swap-Verhalten beinflussen. Mit dem Kommando "cat /proc/sys/vm/swappiness" kann man den aktuell eingestellten Wert bekommen. Dieser Wert kann zwischen 0 und 100 liegen.

Wert 0 bedeutet, dass der Kernel den swap nur dann nutzt, wenn es nicht anders geht. Wert 100 bedeutet das genaue Gegenteil - d.h. es wird so früh wie möglich auf die Festplatte ausgelagert.

Um den Wert im laufenden Betrieb ändern zu können gibt man folgendes ein: "sudo sysctl vm.swappiness=0".

Um diese Einstellung auch nach dem nächsten Neustart des Systems aktiviert zu haben muss man diese Einstellung in der Datei "/etc/sysctl.conf" vornehmen und folgende Zeile hinzufügen: "vm.swappiness=0"

Ich habe z.Zt. den Wert 0 - und bin sehr zufrieden damit. Zuvor hatte ich den Wert 60 auf meinem Client (Ubuntu-Default) und hatte ab und zu richtige Performance-Probleme wenn ich z.B. Eclipse, JBoss und eine VM (Virtualbox) am Laufen hatte - da war das System völlig mit den Festplatten-Zugriffen überlastet.

Weitere Infos zu diesem Thema gibt es hier:
  1. help.ubuntu.com
  2. wiki.ubuntuusers.de

Samstag, 21. Februar 2009

Ruby on Rails - Präsentation von Oktober 2007

Ruby on Rails Einführung

...wenn ich mal wieder Zeit finden sollte muss ich diese Präsentation mal auf den neuesten Stand bringen :)

Tip: Produktivität auf dem Gnome-Desktop steigern


Ich wollte es wirklich nicht glauben bis ich einen Launcher namens gnome-do ausprobiert habe: Ein Launcher-Programm kann die Arbeitsgeschwindigkeit auf dem Desktop wirklich erhöhen. Das Prinzip ist folgendes: "erledige mehr mit der Tastatur und weniger mit der Maus".
Um z.B. ein Programm zu starten gibt man einfach die Anfangsbuchstaben ein und startet aus der Auswahl einfach das passende Programm. Gnome-do kennt aber auch z.B. Deine Kontakte und man kann den Namen eingeben und dann die jeweilige Aktion - z.B. Chat, Email, usw. Es gibt auch sehr viele nützliche Plugins für Gnome-do (u.a. für Pidgin, Rythmbox, Thunderbird, Twitter).

Tip: screen auch auf dem Client-Desktop


Den "alt bekannten" Terminal-Multiplexer screen kennen und schätzen viele im Server-Umfeld. So kann man sich wieder an eine bestehende Screen-Session "andocken" und findet seine Terminals wieder so vor wie zuvor. Auch mehrere Terminals können so mit einer SSH-Verbindung realisiert werden.
Auf dem Client kann Screen aber auch sehr sinnvoll verwendet werden, wenn man sich ein kleines Shell-Skript schreibt was eine neue Session anlegt (wenn noch keine Session vorhanden ist). Sollte eine Session vorhanden sein wird diese wiederverwendet. So kann man das Terminal-Fenster "aus versehen" schließen und bekommt genau diese Screen-Terminal-Session beim nächsten Mal wieder.

Tip: welche Hardware steckt in (m)einem System?

Wer auch mal Hardware-Informationen vergisst dem kann ich nur das Programm dmidecode empfehlen. Mit diesem Programm bekommt man viele wertvolle Informationen über die Hardware eines Rechners (ermittelt wird das über das SMBIOS bzw. DMI). z.B. wollte ich mir eine RAM-Erweiterung für meinen Laptop bestellen, wusste aber nicht ob ich noch eine RAM-Bank frei habe und welche RAM-Typen verwendet werden können. Mit dmidecode ist das ganz einfach möglich: "sudo dmidecode -t memory".

Tip: syndaemon

Wer kennt das Problem nicht: man tippt auf seinem Linux-Laptop und berührt ab und zu evtl. das Touchpad. Gerade bei der Programmierung kann das zu komischen Effekten im Code führen. Jetzt habe ich den "syndaemon" entdeckt. Dieses Programm kann das Touchpad bei einer Texteingabe für eine gewisse Zeit sperren. Man muss einfach das Programm z.B. zu Beginn der Gnome-Session starten. Meine Programmoptionen sind folgende: "/usr/bin/syndaemon -S -d -t"

Damit das funktioniert muss man für den Xorg-Synaptic-Treiber die Option SHMConfig einschalten. Bei älteren Xorg-Versionen konnte man das wohl noch in der xorg.conf-Konfigurationsdatei machen (siehe hier). Jetzt macht das hal und muss für den hal-Daemon eingestellt werden - siehe hier).