From a0d08dc47e059d54032a19b58624f60233ccdea3 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Sun, 14 Jul 2019 15:50:14 +0200 Subject: [PATCH] add all the files --- Dockerfile | 15 +++++++++++ http_wrapper.sh | 20 +++++++++++++++ inetd.conf | 2 ++ upsc_exporter.sh | 6 +++++ upsc_to_prometheus.awk | 56 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 Dockerfile create mode 100755 http_wrapper.sh create mode 100644 inetd.conf create mode 100755 upsc_exporter.sh create mode 100755 upsc_to_prometheus.awk diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d9ade55 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM alpine:latest +MAINTAINER Jack Halford [jack.0x5.be] + +# nut is in testing +RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories + +# busybox-extras for inetd +RUN apk update && apk add busybox-extras nut bash gawk + +COPY http_wrapper.sh / +COPY upsc_exporter.sh / +COPY upsc_to_prometheus.awk / +COPY inetd.conf /etc/ + +ENTRYPOINT ["inetd", "-f"] diff --git a/http_wrapper.sh b/http_wrapper.sh new file mode 100755 index 0000000..f2bb81d --- /dev/null +++ b/http_wrapper.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# small http wrapper for bash scripts via inetd + +file="$1" +mime='text/plain' + +if [ ! -f "$file" ]; then + echo "$1: No such file or directory" >&2 + exit 1 +fi + +. $file > /tmp/.$$.output + +size=$(stat -c "%s" "/tmp/.$$.output") + +printf 'HTTP/1.1 200 OK\r\nDate: %s\r\nContent-Length: %s\r\nContent-Type: %s\r\nConnection: close\r\n\r\n' "$(date)" "$size" "$mime" + +cat /tmp/.$$.output + +rm -f /tmp/.$$.output diff --git a/inetd.conf b/inetd.conf new file mode 100644 index 0000000..284dca2 --- /dev/null +++ b/inetd.conf @@ -0,0 +1,2 @@ +# http_wrapper twice because its argv[0] argv[1] ... +9614 stream tcp nowait root /http_wrapper.sh http_wrapper.sh /upsc_exporter.sh diff --git a/upsc_exporter.sh b/upsc_exporter.sh new file mode 100755 index 0000000..906e4bf --- /dev/null +++ b/upsc_exporter.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# default to ups@localhost +UPS_TARGET="${UPS_TARGET:-ups@localhost}" + +upsc "$UPS_TARGET" | ./upsc_to_prometheus.awk diff --git a/upsc_to_prometheus.awk b/upsc_to_prometheus.awk new file mode 100755 index 0000000..254736d --- /dev/null +++ b/upsc_to_prometheus.awk @@ -0,0 +1,56 @@ +#!/usr/bin/awk -f +# Rationale: +# The output of upsc contains numerical metrics and strings. The +# numerical ones are made into prometheus series, while the strings +# are made into labels that are attaches to series by prefix. + +# $1 == metric name +# $2 == metric value +BEGIN { FS=": "; RS="\n" } +# replace dots with underscores +{gsub(/\./,"_",$1)} + +# split outlet_N into outletN to make multiple timeseries +$1 ~ /^outlet_[0-9]+/ {gsub("outlet_","outlet",$1)} + +# convert status into number +$1 ~ /ups_status/ { + if ($2 ~ /OL/) {$2 = "0"}; + if ($2 ~ /OB/) {$2 = "1"}; +} + +# numerical values are metrics +{ if ($2 ~ /^[0-9]*\.?[0-9]+$/) { + metrics[$1] = $2 +} +# non numerical values are metric labels +else { + prefix = getprefix($1) + gsub(prefix"_","",$1); + label=$1; + value=$2; + if (labels[prefix] != "") + labels[prefix]=labels[prefix]", " + else + labels[prefix]="{" + labels[prefix]=labels[prefix]label"=\""value"\""; +}} + +# print all ,etrics with corresponding labels +END { + for (metric in labels) { labels[metric]=labels[metric]"}" } + for (metric in metrics) { + prefix = getprefix(metric) + print "upsc_" metric labels[prefix], metrics[metric] + } +} + +function getprefix(str) { + n=split(str,array,"_"); + return array[1] + # if (array[1] == "ups") + # prefix=array[1]"_"array[2] + # else + # prefix=array[1] + # return prefix +}