Script-Exporter

  • Linux

  • Windows

Der Script-Exporter ist ein generischer Exporter, der lediglich dazu dient, lokale selbstgeschriebene Skripte aufzurufen und deren Erfolg, Laufzeit und ggf. Response zurückzugeben. Damit kann er für beliebige Anwendungsfälle eingesetzt werden, z.B. um Informationen aus Dateien zurückzugeben oder curl mit jq auszuwerten und so z.B. Daten aus dem BPC auszuwerten und für VIMON bereitstellen.

Skripte erstellen/anpassen

Die Skripte sollten unter vimon/config/script_exporter/scripts abgelegt werden. Hier werden auch bereits zwei Skripte bereitgestellt, die Daten aus einem BPC-Monitor abfragen und bereitstellen.

Die Ausgabesyntax eines Skriptes sollte immer der Prometheus-Syntax (1..n Zeilen) entsprechen:

metrikname{label1="Foo", label2="Bar"} resultValue(number) unixtimestamp

Mit dem Metriknamen werden die Daten später im Grafana referenziert, mit den Labels gefiltert, aggregiert oder anderweitig ausgewertet.
Der Ergebniswert ist immer eine Zahl (wobei man auch Wahrheitswerte auch mit 1 und 0 abbilden kann).

Der Unix-Zeitstempel ist optional. Ist dieser nicht vorhanden, schreibt Prometheus den Wert auf jetzt. Die Angabe eines Zeitstempels macht dann Sinn, wenn ein Wert bspw. zu Beginn der letzten Stunde gültig war aber später ermittelt wird.

Konfiguration

Die Konfiguration erfolgt über die Datei vimon/config/script_exporter/script_exporter.yml.
Hier werden die Skripte hinterlegt und ihnen ein Alias gegeben.

Nur Skripte, die hier definiert sind, können dann auch von außen abgefragt werden.

Die Abfrage von Prometheus aus muss dann auf die URL /probe erfolgen und der Parameter-Skript mit dem am Exporter definierten Alias übermittelt werden.
Beispielhaft könnte dies im Prometheus dann so erfolgen:

  - job_name: 'bpcProcessesProd'
    scrape_interval: 3600s
    metrics_path:    /probe
    static_configs:
      - targets: ['dingeldangelhost.com:9469']
    params:
      script: ['bpc_client_processes_prod']

Beispielkonfiguration

Beispielskript zum Überwachen eines Cluster-Node-Status:

Details
# CheckIS-Script
# Author tk@virtimo
# returns:
#   0 if the inubit Process Engine is running and active (maintenancemode is inactive)
#   1 if the script failes
#   2 if processing is prohibited by file
#   3 if retrieval via loadbalancer failed
#   4 if this is not the active site
#   5 if maintenancemode is active
#   6 if processing is disabled by heartbeat-connector
#   7 if process engine is down
#   8 if curl failed by any other return value
#
# test with eg "echo $?" after call of this script
#
###############################################################

if [ "$#" -ne 1 ]; then
  echo "Usage: $0 TIMEOUT" >&2
  exit 1
fi

EMERGENCY_STOP_FILE=/inubit/filebase/conf/keepalived_emergencyStop.active
IGNORE_SITE_FILE=/inubit/filebase/conf/keepalived_ignoreSite.active

LOCAL_LOCATION_FROM=/etc/haproxy/monitor-response-200.http
LB_STATUS_URL="https://inubit.int.viritmo.de:8443/status"

WSLISTENERURL="http://localhost:7000/ibis/ws/genericMain_wsc_heartbeatConnector?wsdl"
HTTPTIMEOUT=$1

# check for existence of "emergency stop" file - if we find it we exit immediately with "fault" status
if [ -f "$EMERGENCY_STOP_FILE" ]; then
        echo "processing prohibited - $EMERGENCY_STOP_FILE exists"
        exit 2
fi

# find out, if external LB directs external requests to this site or not
if [ ! -f "$IGNORE_SITE_FILE" ]; then
        MYLOC=`tail -1 "$LOCAL_LOCATION_FROM" | cut -d" " -f3`
        LBLOC=`curl --silent --connect-timeout 2 -k "$LB_STATUS_URL"`
        RETCODE=$?
        if [ "$RETCODE" -ne 0 ]; then
                # curl call has failed - exit with "fault" status
                echo "processing disabled - site-check via $LB_STATUS_URL failed"
                exit 3
        fi
        LBLOC=`echo "$LBLOC" | tail -1 | cut -d" " -f3`
        if [ "$MYLOC" != "$LBLOC" ]; then
                # wrong "site" - let's bail out right here
                echo "processing disabled - we ($MYLOC) are not the current master-site ($LBLOC)"
                exit 4
        fi
fi

# check status of local IS instance
HTTPSTATUS=`curl -s -o /dev/null -m $HTTPTIMEOUT -w "%{http_code}" $WSLISTENERURL`
RETCODE=$?
if [ "$HTTPSTATUS" == 200 ]; then
  echo "processing active"
  exit 0
elif [ "$HTTPSTATUS" == 503 ]; then
  echo "maintenancemode active"
  exit 5
elif [ "$HTTPSTATUS" == 404 ]; then
  echo "heartbeat-webservice missing/url wrong"
  exit 6
elif [ "$HTTPSTATUS" == 000 ]; then
  echo "processengine down"
  exit 7
else

Beispielconfig des Exporters:

scripts:
  - name: fail
    script: curl google.foo
    # optional
    #timeout:
      # in seconds, 0 or negative means none
      #max_timeout: 5
      #enforced: false
  - name: fine
    script: curl google.com
    # optional
    #timeout:
      # in seconds, 0 or negative means none
      #max_timeout: 5
      #enforced: false
  - name: isstatus
    script: /inubit/filebase/scripts/keepalived_checkis.sh 5
  - name: activesiteint
    script: /inubit/filebase/scripts/getActiveSite.sh http://inubit.int.virtimo.de:8000/status

Der Exporter wurde nach den aktuellen Prometheus-Guidelines gebaut, daher liefert er die Daten nun unter /probe?script=<ScriptName>.

/metrics hingegen liefert Details über den Exporter selbst.

Der zusätzliche URL-Parameter output=ignore sorgt dafür, dass die eigentliche Ausgabe des Skripts nicht mitgeliefert wird - anderenfalls würde sie auch als Teil der Antwort zurückkommen.

Daher muss die prometheus.yml hier auch abweichend konfiguriert werden.

Beispiel:

  - job_name: 'clusterActiveSite'
    metrics_path: /probe
    params:
      script: ['activesiteint', 'activesitetest', 'activesitedev']
      output: ['ignore']
    static_configs:
      - targets: ['inubitserver.virtimo.lan:9469']
  - job_name: 'clusterIsState'
    metrics_path: /probe
    params:
      script: ['isstatus']
      output: ['ignore']
    static_configs:
      - targets: ['server1.virtimo.lan:9469', 'server2.virtimo.lan:9469']

Die Response sieht dann so aus:

# virtimo script-exporter, author TK, modified to deliver status codes and format for grafana status map.
# HELP script_statusmap Script exit status as label status with value always 1 for grafana statusmap-plugin.
# TYPE script_statusmap gauge
script_statusmap{script="isstatus", status="6"} 1
# HELP script_returncode Script exit status (0 = ok, != 0 any exit code).
# TYPE script_returncode gauge
script_returncode{script="isstatus"} 6
# HELP script_success Script success status (1 = ok, 0 error).
# TYPE script_success gauge
script_success{script="isstatus"} 0
# HELP script_duration_seconds Script execution time, in seconds.
# TYPE script_duration_seconds gauge
script_duration_seconds{script="isstatus"} 0.025820
  • Die Metrik script_returncode liefert den Return-Code

  • script_success liefert nur 1 oder 0 - abhängig von Erfolg oder nicht

  • script_duration_seconds ist die reine Skript-Laufzeit

  • script_statusmap liefert immer 1 und den Return-Code im Label Status.

    Diese Besonderheit wird für den Einsatz des Status-Map-Plugins im Grafana benötigt, siehe https://grafana.com/grafana/plugins/flant-statusmap-panel. Damit kann dann bspw. eine Cluster-Übersicht erzeugt werden.