Seite wählen

NETWAYS Blog

Graphite-API für Grafana und Icinga Web 2

Ziel dieses Posts ist es, am Ende die Metriken über die Graphite-API als Backend für Grafana und das Icinga-Web-2-Module graphite betreiben zu können.

Grafana übernimmt hierbei optional die Visualisierung über eigene Dashboards, was ansonsten Graphite-Web leistet. Für Icinga Web 2 ist Grafana nur erforderlich, falls nicht das Module graphite zum Einsatz kommen soll, sondern stattdessen grafana zur Darstellung im Icinga Web 2 verwendet werden sollte.

Die Graphite-API ist in Python implementiert und soll hierbei via HTTPS angesprochen werden. Zusätzlich ist der Zugriff via Basis-Authentifizierung zu beschränken. Dies alles überlassen wir dem Apache, auch die API lassen wir mittels WSGI im Apache laufen.

Der Vorteil gegenüber dem Graphite-Web liegt darin, die ganzen Django-Bibliotheken nicht zu benötigen und auch kein DB-Backend a la SQLite, MySQL oder PostgreSQL. Nachteil ist, das Projekt Graphite-API wird nicht vom Graphite-Team betrieben, somit ist die Pflege und Aktualität nicht sichergestellt.
mehr lesen…

Lennart Betz
Lennart Betz
Senior Consultant

Der diplomierte Mathematiker arbeitet bei NETWAYS im Bereich Consulting und bereichert seine Kunden mit seinem Wissen zu Icinga, Nagios und anderen Open Source Administrationstools. Im Büro erleuchtet Lennart seine Kollegen mit fundierten geschichtlichen Vorträgen die seinesgleichen suchen.

Asynchroner Webserver in Python mit gevent

Was ist gevent?
gevent ist eine Koroutinen-basierte Netzwerkbibliothek für Python basierend auf libev und greenlet.
greenlets sind leichtgewichtige Koroutinen, die im Prozess des ausführenden Programms laufen, aber nebenläufig ausgeführt werden. Im Gegensatz dazu werden beim Multitasking, Threads vom Betriebssystem geplant, die echt gleichzeitig laufen.
Parallelität vs Nebenläufigkeit
Zwei Aufgaben heißen nebenläufig, wenn sie voneinander unabhängig, in einem sich überschneidenden Zeitfenster, abgearbeitet werden. Dabei müssen diese nicht unbedingt echt gleichzeitig bearbeitet werden.
Zwei Aufgaben werden parallel bearbeitet, wenn sie unabhängig voneinander und zur gleichen Zeit ausgeführt werden.
„Benchmark“
Um die Performance von gevent zu vergleichen (Achtung nicht repräsentativ), lassen wir es gegen Twisted und wsgiref antreten. Die drei Kandidaten starten jeweils einen WSGI Server auf http://127.0.0.1:8088/ und beantworten jede Request mit „HTTP/1.0 200 OK“.
Mit dem Apache HTTP server benchmarking tool lassen wir 30 Sekunden (maximal 50 000 Requests) 1 000 Requests parallel laufen um vergleichen zu können, welche Implementation, die meisten Requests pro Sekunde beantwortet:

ab -r -c 1000 -t 30 http://127.0.0.1:8088/

Twisted

#!/usr/bin/python
from twisted.web import server
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor
def handle_request(env, start_response):
    status = '200 OK'
    output = 'The Output'
    response_headers = [('Content-Type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]
if __name__ == '__main__':
    resource = WSGIResource(reactor, reactor.getThreadPool(), handle_request)
    reactor.listenTCP(8088, server.Site(resource))
    reactor.run()

Requests per second: 1093.40 [#/sec] (mean)
Time per request: 0.915 [ms] (mean, across all concurrent requests)

wsgiref

#!/usr/bin/python
from wsgiref.simple_server import make_server
def handle_request(env, start_response):
    status = '200 OK'
    output = 'The Output'
    response_headers = [('Content-Type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]
if __name__ == '__main__':
    wsgiserver = make_server('', 8088, handle_request)
    wsgiserver.serve_forever()

Requests per second: 1610.80 [#/sec] (mean)
Time per request: 0.621 [ms] (mean, across all concurrent requests)

gevent

#!/usr/bin/python
from gevent.wsgi import WSGIServer
def handle_request(env, start_response):
    status = '200 OK'
    output = 'The Output'
    response_headers = [('Content-Type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]
if __name__ == '__main__':
    WSGIServer(('', 8088), handle_request, spawn=None).serve_forever()

Requests per second: 2121.29 [#/sec] (mean)
Time per request: 0.471 [ms] (mean, across all concurrent requests)

Die Einfachheit des Benchmark lässt natürlich keine Rückschlüsse auf Applikationen in der echten Welt zu. gevent ist aber definitiv einen Blick wert, wenn es um asynchrone Socket-Programmierung geht.

Eric Lippmann
Eric Lippmann
CTO

Eric kam während seines ersten Lehrjahres zu NETWAYS und hat seine Ausbildung bereits 2011 sehr erfolgreich abgeschlossen. Seit Beginn arbeitet er in der Softwareentwicklung und dort an den unterschiedlichen NETWAYS Open Source Lösungen, insbesondere inGraph und im Icinga Team an Icinga Web. Darüber hinaus zeichnet er für viele Kundenentwicklungen in der Finanz- und Automobilbranche verantwortlich.