collectd: Anwendungsspezifische Messwerte aufzeichnen

Mit collectd können Systemdaten, wie Last oder Arbeitsspeicherauslastung, auch in verteilte Systemen einfach überwacht werden. Mittels des Network-Plugins werden diese Daten an einen zentralen Server geschickt. Dort können sie dann auch zentral aufbereitet werden.

In manchen Fällen ist es aber auch nötig anwendungsspezifische Messwerte aufzuzeichnen. In unserem Fall CurrySearch sind das z.B. die aktuelle Anzahl der Kunden oder die Anzahl der Suchanfragen je Kunde.


Um diese Daten aufzeichnen zu können bietet collectd die Möglichkeit Werte per Socket anzunehmen. Dazu muss das Socket-Plugin konfiguriert werden:

LoadPlugin unixsock

<Plugin unixsock>
	SocketFile "/var/lib/currysearch/stats.sock"
	SocketGroup "curryadm"
	SocketPerms "0770"
	DeleteSocket false
</Plugin>

Dem Socket können wir jetzt regelmäßig die aktuellen Werte der gewünschten Daten übertragen. Beschrieben werden die Funktionen des Sockets in der Dokumentation.

Mit Rust könnte das z.B. so aussehen:

fn update_stats(&self) -> Result<()> {
    use std::os::unix::net::UnixStream;

    // Verbindung zum Socket herstellen
    let mut stream = UnixStream::connect("/var/lib/currysearch/stats.sock").unwrap();

    // Werte schreiben (N steht für Now, count ist ein vordefinierter Wert-Typ)
    writeln!(&mut stream, "PUTVAL currysearch/active_tenants/count N:{}", self.tenant_count).unwrap();

    // Die Antwort lesen
    let mut response = String::new();
    let mut reader = BufReader::new(stream);
    reader.read_line(&mut response).unwrap();

    // Und überprüfen
    assert!(response.starts_with("0 Success"));

    Ok(())
}

Das ganze in eine Schleife gepackt und … fertig.


Vordefinierte Wert-Typen können in der types.db gefunden werden. Sollen eigene Typen definiert werden ist darauf zu achten, dass diese identisch für collectd-Client und Server sind und in beiden Konfigurationen geladen werden.