failcam minor: shellcheck warnings
[log-quiet] / sysd-mail-once
1 #!/bin/bash
2 # Copyright (C) 2016 Ian Kelling
3
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16
17 set -eE -o pipefail
18 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
19
20 errors=3
21 cbase=$HOME/sysd-mail-once-state
22 to=root
23 case "$1" in
24 -h|--help)
25 cat <<EOF
26 Usage: sysd-mail-once [-t TO_ADDRESS] [-ERRORS] SERVICE COMMAND [COMMAND_ARGS...]
27
28 For use with systemd timers, to email (with exim) on repeated failure &
29 success after failure.
30
31 In the service triggered by the timer, prepend this script to the ExecStart.
32 The email will contain the service's logs for the last ERRORS runs.
33
34
35 Stores error counts in $cbase
36
37 -ERRORS: ERRORS is the number of failurs to accumulate before mailing the error.
38 Default is 3.
39
40 -t TO_ADDRESS: Address to email about errors
41 EOF
42 exit 0
43 ;;
44 -[0-9]*)
45 errors=${1#-}
46 shift
47 ;;
48 -t)
49 to="$2"
50 shift 2
51 ;;
52 esac
53 service=$1
54 shift
55
56 c=$cbase/$service # c for command file path base
57
58 glob="${c}[0-9]*"
59 arr=($glob); file="${arr[0]}"; [[ $glob != "$file" ]] || file=
60 [[ -d $cbase ]] || mkdir -p $cbase
61
62 if [[ ! $file ]]; then
63 cursor=$(journalctl --show-cursor -qn0|sed 's/^\s*--\scursor:\s*//')
64 fi
65
66 code=0
67 "$@" || code=$?
68 if (( code )); then
69 send_mail=false
70 if [[ $file ]]; then
71 i=${file#"$c"}
72 if (( i < errors )); then
73 new_file=$c$((i+1))
74 mv $file $new_file
75 file=$new_file
76 if [[ $file == $c$errors ]]; then
77 send_mail=true
78 fi
79 fi
80 else
81 file=${c}1
82 printf "%s\n" "$cursor" >$file
83 if (( errors == 1 )); then
84 send_mail=true
85 fi
86 fi
87 if $send_mail; then
88 exim -odf -t <<EOF
89 To: $to
90 From: $USER@$(hostname -f)
91 Subject: $HOSTNAME: $service exit code: $code
92
93 $(journalctl -u $service.service --after-cursor="$(<$file)")
94 EOF
95 fi
96 else
97 if [[ $file ]]; then
98 rm -f $file
99 if [[ $file == $c$errors ]]; then
100 exim -odf -t <<EOF
101 To: $to
102 From: $USER@$(hostname -f)
103 Subject: $HOSTNAME: $service success
104
105 EOF
106 fi
107 fi
108 fi