Seite wählen

NETWAYS Blog

Icinga Plugins in Golang

Golang ist an sich noch eine relativ junge Programmiersprache, ist jedoch bei vielen Entwicklern und Firmen gut angekommen und ist die Basis von vielen modernen Software Tools, von Docker bis Kubernetes.

Für die Entwicklung von Icinga Plugins bringt die Sprache einige hilfreiche Konzepte mit. Golang baut fertige Binaries, Plugins können also zentral kompiliert und ohne große Abhängigkeiten verteilt werden. Alle Abhängigkeiten werden im Rahmen vom Bauprozess abgedeckt, die einzige Unterscheidung liegt in der Ziel Architektur, also Linux, Windows, Mac oder ähnliches, sowie ob 32 oder 64 bit.

Viele Funktionen und Packages (vergleichbar mit Libraries) kommen entweder direkt mit Golang mit oder können leicht aus der Open Source Community verwendet werden. Mit dem Package go-check von uns haben wir eine kleine Basis geschaffen, um leichter Plugins schreiben zu können, ohne sich zu sehr im Code wiederholen zu müssen.

Als ganz einfaches Go Plugin hier ein Beispiel eine „main.go“ Datei:

package main

import (
	"github.com/NETWAYS/go-check"
)

func main() {
	config := check.NewConfig()
	config.Name = "check_test"
	config.Readme = `Test Plugin`
	config.Version = "1.0.0"

	_ = config.FlagSet.StringP("hostname", "H", "localhost", "Hostname to check")

	config.ParseArguments()

	// Some checking should be done here, when --help is not passed

	check.Exitf(check.OK, "Everything is fine - answer=%d", 42)
}

Alles was man noch tun muss, ist das Plugin zu kompilieren oder direkt auszuführen:

go build -o check_test main.go && ./check_test --help
go run main.go

Ein guter Einstieg in Go findet man über die Dokumentation, die Tour und vor allem in dem man sich umschaut, was die Community an Packages zu bieten hat.

Natürlich bleibt die Frage, wie überwache ich das Ding was mir wichtig ist, wofür es aber noch kein Plugin gibt. Gerade dort helfen wir von NETWAYS mit unseren Consulting und Entwicklungsleistungen.  Beispiele unserer Go Plugins findet man auf GitHub unter der NETWAYS Organisation.

 

DevOpsDays 2017 | Berlin, Berlin, wir fahren nach Berlin!

Bald geht’s los zum 2. Hauptstadtevent in diesem Jahr! Am 18.+19. Oktober gehen die DevOpsDays in die nächste Runde!
Und NETWAYS darf wieder bei der Organisation unterstützen!

Als Unterstützung im kaufmännischen Bereich sind wir nun schon mehrere Jahre dabei und das Team der DevOpsDays ist uns dabei richtig ans Herz gewachsen. Umso mehr freuen wir uns auf zwei tolle Tage in Berlin (Hallo, Curry 36!).

Das Programm steht auch schon! Mit dabei sind unter anderem:

– Jason Diller (Long-lived DevOps and the Pit of Success)
– Ken Mugrage (It’s not Continuous Delivery if you can’t deploy right now)
– Andrea Giardini (DevOps moves fast, how can you move faster)
Neben vertiefenden Workshops bieten Open Spaces Raum für eigene Ideen der Teilnehmer! Hier findet Ihr das Programm!

Jetzt müsst ihr eigentlich nur noch euer Ticket holen und euch freuen wie ein Schnitzel! Wir tun das jetzt schon und freuen uns auf das vorletzte Spitzenevent in diesem Jahr, ehe die OSMC dem Jahr den krönenden Abschluss bereitet!

Versteckte Perlen in Icinga Web 2

In Icinga Web 2 gibt es ein paar versteckte Parameter, die leider noch nicht dokumentiert sind aber sicher hier und da hilfreich sein können.
Entwicklermodus für JavaScript und CSS
Icinga Web 2 liefert eigentlich JavaScript und CSS komprimiert an den Client aus. Als Entwickler oder zur Fehlersuche ist aber hilfreich, die Kandidaten in ihrer Originalform auszuliefern. Dazu hängt man den Parameter _dev=1 an die URL.
Listen und Detail-Informationen exportieren
Die Listen zur Ansicht der Hosts, Services und Gruppen und der jeweiligen Detail-Bereiche lassen sich nach JSON und CSV exportieren. Dazu hängt man den format Parameter mit entweder json oder csv als Wert an, also z.B. icingaweb2/monitoring/list/services?format=json.

Vollbildmodus
Um eine Sicht in Icinga Web 2 in den Vollbildmodus zu bringen, hängt man einfach die zwei Parameter showCompact=1 und showFullscreen=1 an die URL. showCompact blendet die Kontrollelemente wie den Filter-Editor und Paginator aus und showFullscreen das Menü und den Header. Das ganz sieht dann so aus:

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.

Improved NodeJS Events durch Cluster …


… jeder von euch kennt das Problem, der Kollege kommt um die Ecke und möchte wenn möglich sofort, dass ein neues geiles Tools mit in den Infra Stack aufgenommen wird, gesagt getan.
In diesem Bespiel eine besonders cooles in NodeJS geschriebenes Dashboard für… lass es hier ein DockerManagement Tool sein. Dabei stößt man bei der großen Akzeptanz durch die Kollegen, auch auf einmal auf noch ganz andere Probleme (Stichwort: Performance Bottlenecks wie DDoS durch eigene Leute).
Hierbei könnte euch das NodeJS Modul Cluster behilflich sein, hier ist die Doku zu finden.
Cluster macht dabei nicht viel, es erweitert den NodeJS Stack insbesondere das Event Driven Modell von NodeJS ( so Arbeitet Google(s) v8 Engine ) um eine Art Interprocess Schnittstelle zu forked Child NodeJS Prozessen, die sich dabei Filesystem Elemente/Typen wie Sockets, Filedeskriptoren etc. teilen können und somit gemeinsam auf diesen operieren können.
Hier wollen wir eine schon bestehende Express Framework Anwendung mit einigen wenigen Zeilen Code um die Fähigkeit erweitern, dem System zur Verfügung stehenden CPU Cores effizienter ausnutzen zu können, damit sich die Events schneller abarbeiten lassen.
Ich werde hier allerdings nicht Express selber beschreiben, sondern setzte hier voraus das der Leser dieses Framework kennt. Wenn nicht könnt ihr die Infos unter diesem Link abrufen, so let’s beginn …

$ sudo -i                                  # <- da meine Workstation ein Ubuntu ist sollten wir zumindest was die Essentials sind kurz zu 'root' werden um diese Problemlos installiert zu bekommen
$ npm install express -g                   # <- installiert uns das Express Framework samt CLI Tools
express@4.13.3 /usr/lib/node_modules/express
├── escape-html@1.0.2
├── merge-descriptors@1.0.0
├── cookie@0.1.3
├── array-flatten@1.1.1
├── cookie-signature@1.0.6
├── utils-merge@1.0.0
├── content-type@1.0.1
├── fresh@0.3.0
├── path-to-regexp@0.1.7
├── content-disposition@0.5.0
├── vary@1.0.1
├── etag@1.7.0
├── serve-static@1.10.0
├── range-parser@1.0.2
├── methods@1.1.1
├── parseurl@1.3.0
├── depd@1.0.1
├── qs@4.0.0
├── on-finished@2.3.0 (ee-first@1.1.1)
├── finalhandler@0.4.0 (unpipe@1.0.0)
├── debug@2.2.0 (ms@0.7.1)
├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
├── send@0.13.0 (destroy@1.0.3, statuses@1.2.1, ms@0.7.1, mime@1.3.4, http-errors@1.3.1)
├── type-is@1.6.9 (media-typer@0.3.0, mime-types@2.1.7)
└── accepts@1.2.13 (negotiator@0.5.3, mime-types@2.1.7)
$ npm install express-generator -g
/usr/bin/express -> /usr/lib/node_modules/express-generator/bin/express
express-generator@4.13.1 /usr/lib/node_modules/express-generator
├── sorted-object@1.0.0
├── commander@2.7.1 (graceful-readlink@1.0.1)
└── mkdirp@0.5.1 (minimist@0.0.8)
$ exit                                     # <- ab hier geht es ohne 'root' Rechte weiter
$ mkdir cool-app && cd cool-app            # <- Projekt Verzeichnis anlegen und in dieses wechseln
$ pwd                                      # <- vergewissern das wir uns auch in diesem wirklich befinden
/home/enzo/nodejsProjects/cool-app
$ express --git .                          # <- wir provisionieren uns unser Projekt from Scratch, dieses ist somit direkt Lauffähig ohne das wir einen Zeile Code schreiben müssen, haben hier leider keine Zeit zu 😉
   create : .
   create : ./package.json
   create : ./app.js
   create : ./.gitignore
   create : ./public
   create : ./routes
   create : ./routes/index.js
   create : ./routes/users.js
   create : ./views
   create : ./views/index.jade
   create : ./views/layout.jade
   create : ./views/error.jade
   create : ./bin
   create : ./bin/www
   create : ./public/javascripts
   create : ./public/images
   create : ./public/stylesheets
   create : ./public/stylesheets/style.css
   install dependencies:
     $ cd . && npm install
   run the app:
     $ DEBUG=cool-app:* npm start
$

Ab hier können wir das ganze mal kurz testen, um uns zu vergewissern das die Anwendung auch läuft ...

$ npm start
> cool-app@0.0.0 start /home/enzo/nodejsProjects/cool-app
> node ./bin/www

Nicht wundern die Applikation bleibt im Vordergrund hängen, was ist Ok ist, somit können wir diese schneller terminieren und relaunchen. Weiter geht es mit einem Test im Browser, die Anwendung lauscht standardmäßig am Port 3000, somit rufen wir hier einmal http://localhost:3000 auf und lassen uns überraschen was da so schönes kommt ...

Geil es läuft also, nun gut machen wir das ganze mit Cluster noch skalierbarer, let's go ...
Öffnet hierzu im Projekt Verzeichnis einmal die bin/www Datei, diese stellt laut package.json unseren Eintrittspunkt in die Anwendung dar, wir kopieren uns diese als Backup weg bevor wir anfangen hier Änderungen vorzunehmen.
Kommentiert bitte folgende Zeilen einmal aus ...

/**
 * Get port from environment and store in Express.
 */
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
 * Create HTTP server.
 */
var server = http.createServer(app);
/**
 * Listen on provided port, on all network interfaces.
 */
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

... nun fügt ihr ab Zeile 10 bitte folgendes hinzu ...

// cluster requirements
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if( cluster.isMaster ) {
  for( var i = 0; i < numCPUs; i++ ) {
    cluster.fork();
  }
  cluster.on( 'listening', function( worker ){
    console.log( 'worker ' + worker.process.pid + ' is now listen for incoming connections ... ' );
  });
  cluster.on( 'exit', function( worker, code, signal ) {
    console.log( 'worker ' + worker.process.pid + ' died' );
  });
} else {
    // Workers can share any TCP connection
    // In this case it is an HTTP server
    /**
    * Get port from environment and store in Express.
    */
    var port = normalizePort(process.env.PORT || '3000');
    app.set('port', port);
    /**
    * Create HTTP server.
    */
    var server = http.createServer(app);
    /**
    * Listen on provided port, on all network interfaces.
    */
    server.listen(port);
    server.on('error', onError);
    server.on('listening', onListening);
}

.. jetzt sollte das ganze auch schon funktionieren, probieren wir es doch einmal aus.

$ npm start
> cool-app@0.0.0 start /home/enzo/nodejsProjects/cool-app
> node ./bin/www
worker 31979 is now listen for incoming connections ...
worker 31974 is now listen for incoming connections ...
worker 31985 is now listen for incoming connections ...
worker 31996 is now listen for incoming connections ...
GET / 304 840.784 ms - -
GET /stylesheets/style.css 304 31.416 ms - -

Jetzt könnte man denken das sich hier nichts geändert hat, dem ist aber nicht so, der Beweis ist in der Prozess Tabelle zu finden, gucken wir doch kurz einmal hinein ...

$ ps auxf | grep node
enzo     31969  0.1  0.4 901264 33004 pts/7    Sl+  14:47   0:00          |   |       \_ node ./bin/www
enzo     31974  0.1  0.4 901256 32324 pts/7    Sl+  14:47   0:00          |   |           \_ /usr/bin/nodejs /home/enzo/nodejsProjects/cool-app/bin/www
enzo     31979  0.4  0.6 946192 47560 pts/7    Sl+  14:47   0:01          |   |           \_ /usr/bin/nodejs /home/enzo/nodejsProjects/cool-app/bin/www
enzo     31985  0.1  0.4 902668 32736 pts/7    Sl+  14:47   0:00          |   |           \_ /usr/bin/nodejs /home/enzo/nodejsProjects/cool-app/bin/www
enzo     31996  0.1  0.4 901256 32168 pts/7    Sl+  14:47   0:00          |   |           \_ /usr/bin/nodejs /home/enzo/nodejsProjects/cool-app/bin/www

Whoop whoop, 4 neue NodeJS Prozesse die hier ihre Arbeit verrichten, somit lassen sich auch die beschäftigsten Web Anwendungen wieder beschleunigen.
Das ist aber nur der Anfang wie sich NodeJS Applications aller Art verbessern lassen, für weiter Themen habe ich heute allerdings keine Zeit daher heben wir uns den Rest einfach für ein anderes mal auf.
Ich wünsche euch hiermit noch viel Spaß, ich hoffe ihr habt nun mehr Lust auf NodeJS bekommen.