Server Monitoring mit Munin

Da ich ein Kontrollfreak bin ;) wollte ich mal meinen vServer monitoren.
Nach allem was ich so las, scheint wohl Munin das geeignete Tool zu sein.

Also aufgemacht und es installiert:
Munin ist Server-Client mäßig aufgebaut, ich installiere der Einfachkeit halber mal Server und Client (Node) auf der selben Maschine.
Für Debian Lenny geht das ganz einfach über apt-get:

apt-get install munin munin-node

So nun noch das Webinterface umlegen: ich mache dafür eine eigene Subdomain bei einem meiner vHosts über Plesk.
zB munin.nerdpress.org (nein, die url gibts in echt nicht)

jetzt muss noch das www Verzeichnis, welches Munin generiert umkopiert werden in das Subdomain Verzeichnis:

cp -r /var/www/munin/* /var/www/vhosts/nerdpress/subdomains/munin/httpdocs

Continue reading “Server Monitoring mit Munin”

Schau auf die Error_Log

Man sollte sich tatsächlich angewöhnen beim Entwickeln immer eine Console offen zu haben und die error_log zu beobachten.

tail -f /var/log/apache2/error_log

Bekommt man nämlich so einen Fehler in der error_log:

ALERT - configured POST variable limit exceeded - dropped variable ...

… bleibt die Seite meistens ohne Fehlerausgabe trotz E_ALL und es passieren komische Dinge.
Dann kann man schonmal eine ganze Weile damit verbringen ganz woanders zu suchen.
Mit offenem error_log wäre das nicht passiert ;).

Continue reading “Schau auf die Error_Log”

Symfony 2 PR3: doctrine:schema:create liefert “No Metadata Classes to process.”

Die Doku stellt in Aussicht, dass man den “normalen” Doctrine-Namespace-Shortcut benutzen kann, also bspw. @Entity anstelle von @DoctrineOrmMappingEntity. Funktioniert aber nicht, weil in irgend einer Service-Configuration dieser Namespace auf einen Alias gemapped wird, der da lautet “orm”. Die Syntax lautet aber nun auch nicht @ormEntity, sondern @orm:Entity. Schreibt man sein Model also bspw. so:

<?php

namespace ApplicationHelloBundleEntity;

/**
 * ApplicationHelloBundleEntityUser
 *
 * @orm:Table(name="users")
 * @orm:Entity
 */
class User
{
  /**
   * @var integer $id
   *
   * @orm:Column(name="id", type="integer")
   * @orm:Id
   * @orm:GeneratedValue(strategy="AUTO")
   */
  protected $id;

sollten alle CLI-Tasks auch wunderbar funktionieren. Es bleibt zu hoffen, dass die DI-Services eine reichhaltige Parameter-Dokumentation spendiert kriegen und das ganze Bundle-System eine transparente, dokumentierte API erhalten (wo zum Teufel liegt in der Sandbox bitte der versprochene Doctrine-Controller?)

Die Einstellung findet sich übrigens in der Service-Configuration unter src/vendor/symfony/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml:

<service id="doctrine.orm.metadata_driver.annotation.reader" class="%doctrine.orm.metadata.annotation_reader_class%">
            <call method="setAnnotationNamespaceAlias">
              <argument>DoctrineORMMapping</argument>
              <argument>orm</argument>
            </call>
        </service>

Ist leicht zu finden, wenn man weiß, wonach man suchen muss. Ich denke, es ist am einfachsten, die Service-Definition des DI-Containers an entsprechender Stelle an seine eigenen Bedürfnisse anzupassen. Wie das zuverlässig und projektübergreifend funktioniert, erkläre ich vielleicht mal, wenn ich’s selbst gerafft hab.

Achso, hier noch der Nebensatz (etwas herunter scrollen), in dem gesagt wird, das Jonathan irgendwann mal das “orm:” Präfix einführt. Symfony 2 ist definitiv noch nicht ready for production (was aber auch niemand behauptet).

Dependency Injection mit PHP 5.3, Runkit-Erweiterung und Doctrine 2-Annotationen

Unter Dependency Injection versteht man heute nicht nur ein einfaches Entwurfsmuster, sondern vor allem Framework-gestützte Mechanismen, die den konkreten Implementierungsaufwand verringern (Entwicklungszeitoptimierung), dem Entwickler bessere Übersicht über Abhängigkeiten zu schaffen (Applicationdesignoptimierung) und die Anzahl der Instanzen gleichen Prototyps zu minimieren (Performanceoptimierung).

Heute möchte ich einen alternativen, vielleicht pragmatischeren Ansatz als der andererer populärer Implementierungenn herbeispinnen, um Dependency Injection (DI) in PHP 5.3 zu realisieren.
Continue reading “Dependency Injection mit PHP 5.3, Runkit-Erweiterung und Doctrine 2-Annotationen”

Persistente Objekte in PHP und redirects

Achtung Falle!
Benutzt man persistente Objekte in PHP, die ungefähr so aufgebaut sind, wie hier beschrieben.

class User
{
public function __construct(){}

// save object to session variable
public function __destruct()
{
   $_SESSION['user'] = serialize($this);
} 
// factory method
public static function factory()
{
   session_start();
   if(isset($_SESSION['user']) === TRUE)
   {
      return unserialize($_SESSION['user']);
   }
   return new User();
} 
}

Continue reading “Persistente Objekte in PHP und redirects”

Asus N82j, U80, UL30 Series; Touchpad auschalten unter Ubuntu 10.04

Das für mich als Merkhilfe und eventuell Suchende: Wer sein Touchpad unter Ubuntu via Hotkey abschalten möchte und im Besitz eines neueren Asus-Notebooks ist, wird hier endlich fündig: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/418282 (für mich hat folgender Workaround zuverlässig funktioniert):

This problem is also valid for the ASUS UL30A. The touchpad is seen as an “ImPS/2 Logitech Wheel Mouse”. See in dmesg and by the command “xinput list”. I am using Ubuntu 9.10.

To disable the touchpad the following command can be used:

xinput set-int-prop “ImPS/2 Logitech Wheel Mouse” “Device Enabled” 8 0

To enable use:

xinput set-int-prop “ImPS/2 Logitech Wheel Mouse” “Device Enabled” 8 1

To make the F9 working I did the following:

1. As the F9 does not generate a keycode but an acpi event you cannot assign just a keycode to a script. So I first checked the generated event hotkey code using:
sudo acpi_listen
and pressed F9. This gives 0000006b as event hotkey code.
2. In /etc/acpi/events there is an asus-touchpad event file. This is using the wrong code so I changed it.
3. The script /etc/acpi/assus-touchpad.sh is not correct for this touchpad so I changed it (see attached script)
4. Now send the acpid a SIGHUP signal (or reboot) and the F9 button toggles your touchpad an or off.

Danach kann man via FN + F9 wieder wie gewohnt das Touchpad an- und abschalten.

Grouping & Sorting in MongoDB

Will man mit PHP und MongoDB soetwas wie “SQL Aggregate Functions” umsetzen muss man sich etwas verbiegen.

MongoDb hat zwar eine group() function, die in etwa SQLs GROUP BY entspricht, allerdings kann man dies nicht kombinieren mit SORT oder LIMIT bzw den sort() und limit() Funktionen, da diese keinen Cursor zurückgibt sondern direkt ein Array.

Will man also sortieren und limitieren muss man sich des Map / Reduce features von MongoDB bedienen.

Continue reading “Grouping & Sorting in MongoDB”

sqlite VACUUM

Mal ein kleines Zauberwort für Zwischendurch:
VACUUM;

Dieses Kommando räumt eine Sqlite Datenbank auf, killt unnötige Leerzeichen und defragmentiert den Datenbank File.

In meinem Fall war die DB nach dem löschen einer relativ großen Table immer noch auf ca 20MB, das hat mich doch stutzig gemacht und zu diesem Kommando geführt.
Nachdem ich es ausgeführt hatte, war der File dann tatsächlich auf 2MB geschrumpft!

Sollte man vielleicht nicht im laufendem Betrieb machen und als nächstes schau ich mir dann AUTO_VACUUM an.