diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..03f630a --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +.PHONY: install +install: + cp borg_exporter.sh /usr/local/bin/ \ + && chmod +x /usr/local/bin/borg_exporter.sh \ + && cp borg_exporter.rc /etc/borg_exporter.rc \ + && cp prometheus-borg-exporter.timer /etc/systemd/system/ \ + && cp prometheus-borg-exporter.service /etc/systemd/system/ \ + && echo -n "Edit the config file /etc/borg_exporter.rc and press [ENTER] when finished "; read \ + && systemctl enable prometheus-borg-exporter.timer \ + && systemctl start prometheus-borg-exporter.timer diff --git a/README.md b/README.md index 63cabad..0848cdc 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,20 @@ Export borg information to prometheus. ## Dependencies + * [Dateutils](http://www.fresse.org/dateutils/) * Prometheus (obviously) * Node Exporter with textfile collector - * Borg (https://github.com/borgbackup/borg) + * [Borg](https://github.com/borgbackup/borg) ## Install -Copy `borg_exporter` to `/usr/local/bin`. +### With the Makfile + +For convenience, you can install this exporter with the command line +`make install` or follow the process described in the next paragraph. + +### Manually +Copy `borg_exporter.sh` to `/usr/local/bin`. Copy `borg.env` to `/etc/borg` and replace your repokey and repository in it. @@ -27,12 +34,21 @@ Alternative: Use `ExecStartPost` in your borg backupt timer itself to write our Make sure your node exporter uses `textfile` in `--collectors.enabled` and add the following parameter: `--collector.textfile.directory=/var/lib/node_exporter/textfile_collector` -## Example queries +## Exported metrics ``` -backup_total_size_dedup{job='node'} -backup_last_size_dedup{job='node'} -backup_chunks_total{job='node'} +borg_extract_exit_code +bork_hours_from_last_backup +bork_count +bork_files +bork_chunks_unique +bork_chunks_total +bork_last_size +bork_last_size_compressed +bork_last_size_dedup +bork_total_size +bork_total_size_compressed +bork_total_size_dedup ``` ### Grafana dashboard diff --git a/borg_exporter b/borg_exporter deleted file mode 100755 index 658c692..0000000 --- a/borg_exporter +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -set -eu - -source /etc/borg - -TEXTFILE_COLLECTOR_DIR=/var/lib/node_exporter/textfile_collector -PROM_FILE=$TEXTFILE_COLLECTOR_DIR/backup.prom -TMP_FILE=$PROM_FILE.$$ -HOSTNAME=$(hostname) -LIST=$(BORG_PASSPHRASE=$BORG_PASSPHRASE borg list $REPOSITORY |awk '{print $1}') -COUNTER=0 - -mkdir -p $TEXTFILE_COLLECTOR_DIR - -for i in $LIST; do - COUNTER=$((COUNTER+1)) -done - -BORG_INFO=$(BORG_PASSPHRASE=$BORG_PASSPHRASE borg info "$REPOSITORY::$i") -echo "backup_count{host=\"${HOSTNAME}\"} $COUNTER" > $TMP_FILE -echo "backup_files{host=\"${HOSTNAME}\"} $(echo "$BORG_INFO" | grep "Number of files" | awk '{print $4}')" >> $TMP_FILE -echo "backup_chunks_unique{host=\"${HOSTNAME}\"} $(echo "$BORG_INFO" | grep "Chunk index" | awk '{print $3}')" >> $TMP_FILE -echo "backup_chunks_total{host=\"${HOSTNAME}\"} $(echo "$BORG_INFO" | grep "Chunk index" | awk '{print $4}')" >> $TMP_FILE - -function calc_bytes { - NUM=$1 - UNIT=$2 - - case "$UNIT" in - kB) - echo $NUM | awk '{ print $1 * 1024 }' - ;; - MB) - echo $NUM | awk '{ print $1 * 1024 * 1024 }' - ;; - GB) - echo $NUM | awk '{ print $1 * 1024 * 1024 * 1024 }' - ;; - TB) - echo $NUM | awk '{ print $1 * 1024 * 1024 * 1024 * 1024 }' - ;; - esac -} - -# byte size -LAST_SIZE=$(calc_bytes $(echo "$BORG_INFO" |grep "This archive" |awk '{print $3}') $(echo "$BORG_INFO" |grep "This archive" |awk '{print $4}')) -LAST_SIZE_COMPRESSED=$(calc_bytes $(echo "$BORG_INFO" |grep "This archive" |awk '{print $5}') $(echo "$BORG_INFO" |grep "This archive" |awk '{print $6}')) -LAST_SIZE_DEDUP=$(calc_bytes $(echo "$BORG_INFO" |grep "This archive" |awk '{print $7}') $(echo "$BORG_INFO" |grep "This archive" |awk '{print $8}')) -TOTAL_SIZE=$(calc_bytes $(echo "$BORG_INFO" |grep "All archives" |awk '{print $3}') $(echo "$BORG_INFO" |grep "All archives" |awk '{print $4}')) -TOTAL_SIZE_COMPRESSED=$(calc_bytes $(echo "$BORG_INFO" |grep "All archives" |awk '{print $5}') $(echo "$BORG_INFO" |grep "All archives" |awk '{print $6}')) -TOTAL_SIZE_DEDUP=$(calc_bytes $(echo "$BORG_INFO" |grep "All archives" |awk '{print $7}') $(echo "$BORG_INFO" |grep "All archives" |awk '{print $8}')) - - -echo "backup_last_size{host=\"${HOSTNAME}\"} $LAST_SIZE" >> $TMP_FILE -echo "backup_last_size_compressed{host=\"${HOSTNAME}\"} $LAST_SIZE_COMPRESSED" >> $TMP_FILE -echo "backup_last_size_dedup{host=\"${HOSTNAME}\"} $LAST_SIZE_DEDUP" >> $TMP_FILE -echo "backup_total_size{host=\"${HOSTNAME}\"} $TOTAL_SIZE" >> $TMP_FILE -echo "backup_total_size_compressed{host=\"${HOSTNAME}\"} $TOTAL_SIZE_COMPRESSED" >> $TMP_FILE -echo "backup_total_size_dedup{host=\"${HOSTNAME}\"} $TOTAL_SIZE_DEDUP" >> $TMP_FILE - -mv $TMP_FILE $PROM_FILE diff --git a/borg.env b/borg_exporter.rc similarity index 100% rename from borg.env rename to borg_exporter.rc diff --git a/borg_exporter.sh b/borg_exporter.sh new file mode 100755 index 0000000..9e68d58 --- /dev/null +++ b/borg_exporter.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -eu + +source /etc/borg_exporter.rc + +TEXTFILE_COLLECTOR_DIR=/var/lib/node_exporter/textfile_collector +PROM_FILE=$TEXTFILE_COLLECTOR_DIR/bork.prom + +TMP_FILE=$PROM_FILE.$$ +[ -e $TMP_FILE ] && rm -f $TMP_FILE + +HOSTNAME=$(hostname) +ARCHIVES="$(BORG_PASSPHRASE=$BORG_PASSPHRASE borg list $REPOSITORY)" +COUNTER=0 + +[ -e $TEXTFILE_COLLECTOR_DIR ] || mkdir -p $TEXTFILE_COLLECTOR_DIR + +COUNTER=$(echo "$ARCHIVES" | wc -l) +LAST_ARCHIVE=$(BORG_PASSPHRASE=$BORG_PASSPHRASE borg list $REPOSITORY | sort -nr | head -n 1) +LAST_ARCHIVE_NAME=$(echo $LAST_ARCHIVE | awk '{print $1}') +LAST_ARCHIVE_DATE=$(echo $LAST_ARCHIVE | awk '{print $3" "$4}') +CURRENT_DATE="$(date '+%Y-%m-%d %H:%M:%S')" +NB_HOUR_FROM_LAST_BCK=$(dateutils.ddiff "$LAST_ARCHIVE_DATE" "$CURRENT_DATE" -f '%H') + +BORG_EXTRACT_EXIT_CODE=$(BORG_PASSPHRASE="$BORG_PASSPHRASE" borg extract --dry-run "$REPOSITORY::$LAST_ARCHIVE_NAME" > /dev/null 2>&1; echo $?) +BORG_INFO=$(BORG_PASSPHRASE="$BORG_PASSPHRASE" borg info "$REPOSITORY::$LAST_ARCHIVE_NAME") + +echo "borg_extract_exit_code{host=\"${HOSTNAME}\"} $BORG_EXTRACT_EXIT_CODE" >> $TMP_FILE +echo "bork_hours_from_last_backup{host=\"${HOSTNAME}\"} $NB_HOUR_FROM_LAST_BCK" >> $TMP_FILE +echo "bork_count{host=\"${HOSTNAME}\"} $COUNTER" >> $TMP_FILE +echo "bork_files{host=\"${HOSTNAME}\"} $(echo "$BORG_INFO" | grep "Number of files" | awk '{print $4}')" >> $TMP_FILE +echo "bork_chunks_unique{host=\"${HOSTNAME}\"} $(echo "$BORG_INFO" | grep "Chunk index" | awk '{print $3}')" >> $TMP_FILE +echo "bork_chunks_total{host=\"${HOSTNAME}\"} $(echo "$BORG_INFO" | grep "Chunk index" | awk '{print $4}')" >> $TMP_FILE + +function calc_bytes { + NUM=$1 + UNIT=$2 + + case "$UNIT" in + kB) + echo $NUM | awk '{ print $1 * 1024 }' + ;; + MB) + echo $NUM | awk '{ print $1 * 1024 * 1024 }' + ;; + GB) + echo $NUM | awk '{ print $1 * 1024 * 1024 * 1024 }' + ;; + TB) + echo $NUM | awk '{ print $1 * 1024 * 1024 * 1024 * 1024 }' + ;; + esac +} + +# byte size +LAST_SIZE=$(calc_bytes $(echo "$BORG_INFO" |grep "This archive" |awk '{print $3}') $(echo "$BORG_INFO" |grep "This archive" |awk '{print $4}')) +LAST_SIZE_COMPRESSED=$(calc_bytes $(echo "$BORG_INFO" |grep "This archive" |awk '{print $5}') $(echo "$BORG_INFO" |grep "This archive" |awk '{print $6}')) +LAST_SIZE_DEDUP=$(calc_bytes $(echo "$BORG_INFO" |grep "This archive" |awk '{print $7}') $(echo "$BORG_INFO" |grep "This archive" |awk '{print $8}')) +TOTAL_SIZE=$(calc_bytes $(echo "$BORG_INFO" |grep "All archives" |awk '{print $3}') $(echo "$BORG_INFO" |grep "All archives" |awk '{print $4}')) +TOTAL_SIZE_COMPRESSED=$(calc_bytes $(echo "$BORG_INFO" |grep "All archives" |awk '{print $5}') $(echo "$BORG_INFO" |grep "All archives" |awk '{print $6}')) +TOTAL_SIZE_DEDUP=$(calc_bytes $(echo "$BORG_INFO" |grep "All archives" |awk '{print $7}') $(echo "$BORG_INFO" |grep "All archives" |awk '{print $8}')) + + +echo "bork_last_size{host=\"${HOSTNAME}\"} $LAST_SIZE" >> $TMP_FILE +echo "bork_last_size_compressed{host=\"${HOSTNAME}\"} $LAST_SIZE_COMPRESSED" >> $TMP_FILE +echo "bork_last_size_dedup{host=\"${HOSTNAME}\"} $LAST_SIZE_DEDUP" >> $TMP_FILE +echo "bork_total_size{host=\"${HOSTNAME}\"} $TOTAL_SIZE" >> $TMP_FILE +echo "bork_total_size_compressed{host=\"${HOSTNAME}\"} $TOTAL_SIZE_COMPRESSED" >> $TMP_FILE +echo "bork_total_size_dedup{host=\"${HOSTNAME}\"} $TOTAL_SIZE_DEDUP" >> $TMP_FILE + +mv $TMP_FILE $PROM_FILE diff --git a/prometheus-borg-exporter.service b/prometheus-borg-exporter.service index 8eb5648..0e43797 100644 --- a/prometheus-borg-exporter.service +++ b/prometheus-borg-exporter.service @@ -3,5 +3,5 @@ Description=Prometheus Borg Exporter After=network-online.target [Service] -ExecStart=/usr/local/bin/borg_exporter +ExecStart=/usr/local/bin/borg_exporter.sh Type=oneshot