diff --git a/psi-alerts.sh b/psi-alerts.sh old mode 100755 new mode 100644 index 57c5c57..86186c0 --- a/psi-alerts.sh +++ b/psi-alerts.sh @@ -1,19 +1,53 @@ #!/usr/bin/env zsh + +# Send alerts when Pressure Stall Information is high +# +# Copyright © 2023 Trey Blancher # +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# This script monitors the systemd journal, specifically the +# `psi-monitor.service` and waits for Pressure State Information monitor events +# to be logged. The monitor program is shipped in the psi-by-example submodule +# in this git repository; it is released under the three-clause BSD license +# (see its LICENSE file for details). +# +# It is designed to send desktop notifications to a desktop system, it also +# uses the local mail transport agent to send notifications via SMS and email. +# It is assumed the desktop notification system is remote, and it uses the +# local ssh client to connect to the notification daemon on the remote host. +# +# This script expects a number of environment variables to be set, in the +# systemd psi-alerts@.service overrides (will be placed in +# /etc/systemd/system/psi-alerts@.service.d/override.conf. See the +# README.md for details. + svc="psi-monitor.service" cpu="/proc/pressure/cpu" mem="/proc/pressure/memory" io="/proc/pressure/io" -email_to="trey@blancher.net" -sms_dst="2517511550@msg.fi.google.com" -sms_domain="msg.fi.google.com" -port="5999" -ssh_host="localhost" -clear_threshold="5.0" -notification_cmd="dunstify" -notification_opts="--timeout=0 --printid --urgency=critical --icon=/usr/share/icons/breeze-dark/emblems/16/emblem-warning.svg" -id_idx=15 +host="$(hostname)" +email_to="${EMAIL_TO}" +sms_dst="${SMS_DST}" +sms_domain="$(awk -F@ '{print $NF}' <<< ${SMS_DST})" +ssh_port="${SSH_PORT}" +ssh_host="${SSH_HOST}" +clear_threshold="${CLEAR_THRESHOLD}" +notification_cmd="${NOTIFICATION_CMD}" +notification_opts="${NOTIFICATION_OPTS}" +id_idx="${NOTIFICATION_IDX}" print_psi () { local psi_file="${1}" @@ -25,14 +59,14 @@ print_pidstat () { local opts="-l --human" case "${psi_type}" in - MEM) - opts="-r ${opts}" + CPU) + opts="-u ${opts}" ;; IO) opts="-d ${opts}" ;; - CPU) - opts="-u ${opts}" + MEM) + opts="-r ${opts}" ;; *) print "Invalid psi_type: ${psi_type}" >&2 @@ -61,13 +95,13 @@ send_notice () { ;; esac - integer dunst_id - if ! dunst_id=$(ssh -q "${ssh_host}" -p ${port} \ - "${notification_cmd} ${notification_opts} 'deltachunk: PSI ${psi_type} triggered!' '${psi}'"); then - print "Connection to dunst failed!" >&2 + integer notification_id + if ! notification_id=$(ssh -q "${ssh_host}" -p ${ssh_port} \ + "${notification_cmd} ${notification_opts} '${host}: PSI ${psi_type} triggered!' '${psi}'"); then + print "Connection to notification daemon failed!" >&2 false else - echo ${dunst_id} + echo ${notification_id} true fi } @@ -169,7 +203,7 @@ check_dunst_id_is_visible () { local dunst_id="${1}" typeset -a ids - if ids=$(ssh -q "${ssh_host}" -p ${port} \ + if ids=$(ssh -q "${ssh_host}" -p ${ssh_port} \ "dunstctl history | jq '.data[0][][${id_idx}].data'"); then echo "Connection to dunst failed!" >&2 return 2