refactor log-once
authorIan Kelling <ian@iankelling.org>
Fri, 28 Oct 2016 13:32:08 +0000 (06:32 -0700)
committerIan Kelling <ian@iankelling.org>
Fri, 28 Oct 2016 13:32:08 +0000 (06:32 -0700)
log-once

index f8938c83b23511eb211642b06ea24280fe60dd12..040e2ba72d634a76c3363cc855d3997fd9f72967 100755 (executable)
--- a/log-once
+++ b/log-once
@@ -17,20 +17,23 @@ append() {
     cat >> "$1"
 }
 log-once() {
+    local cbase c log x i out file
+    cbase=/var/local/cron-errors
+    [[ $EUID == 0 ]] || cbase=$HOME/cron-errors
     local help="Usage: log-once [OPTION]... LOG_NAME [LOG_MESSAGE]
 
-For cronjobs, email only once for repeated failures, and for success after failure.
+For cronjobs, email log on repeated failure and success after failure.
 
 Meant for use in cronjobs where LOG_MESSAGE or STDIN represents an error,
 but we only want to output that to STDOUT if we've seen this type of
 error ERRORS(default 3) number of times in a row, then we don't
 want to output anything again until we've seen a success (an empty LOG_MESSAGE).
 
-Logs LOG_MESSAGE or STDIN to ~/.cron_errors/LOG_NAME, and keeps
+Logs LOG_MESSAGE or STDIN to /var/local/cron-errors/LOG_NAME\$error_count
+or $HOME/cron-errors if not root, and keeps
 state in the same directory.
 
--e ERRORS:  ERRORS is the number of errors to accumulate before outputing the error"
-    local cbase c c1 c2 log x i out file
+-ERRORS:  ERRORS is the number of errors to accumulate before outputing the error"
     errors=3
     while true; do
         if [[ $1 == --help ]]; then
@@ -48,7 +51,6 @@ state in the same directory.
     done
     log_name=$1
     # todo, make option & make them overridable based on command line or env variable
-    cbase=$HOME/.cron-errors
     [[ -d $cbase ]] || mkdir -p $cbase
     c=$cbase/$log_name
     # http://stackoverflow.com/questions/2456750/detect-presence-of-stdin-contents-in-shell-script
@@ -62,26 +64,22 @@ state in the same directory.
             [[ $x ]] && log=true
         done
     fi
+    glob="$c[0-9]*"
+    file=($glob); file="${file[0]}"; [[ $glob != $file ]] || file=
     if $log; then
-        file=
-        if [[ -f $c$((errors-1)) ]]; then
-            out="tee -a"
-        else
-            out=append
-        fi
-        for ((i=errors; i>=1; i--)); do
-            if [[ -f $c$((i-1)) ]]; then
-                file=$c$i
-                mv $c$((i-1)) $file
-                break
-            fi
-        done
-        if [[ ! $file ]]; then
-            if [[ -f $c$errors ]]; then
-                file=$c$errors
-            else
-                file=${c}1
+        out=append
+        if [[ $file ]]; then
+            i=${file#$c}
+            if (( i < errors )); then
+                new_file=$c$((i+1))
+                mv $file $new_file
+                file=$new_file
+                if [[ $file == $c$errors ]]; then
+                    out="tee -a"
+                fi
             fi
+        else
+            file=${c}1
         fi
         $out $file <<<"log-once: $(date "+%A, %B %d, %r")"
         if [[ $2 ]]; then
@@ -91,11 +89,12 @@ state in the same directory.
             $out $file
         fi
         return 1
-    elif [[ -f $c$errors ]]; then
-        echo "log-once success after failure for $c"
-        rm -f $c$errors
-    else
-        rm -f $c[0-9]* # assuming  no one is putting crazy files names, as this is not exact
+    fi
+    if [[ $file ]]; then
+        rm -f $file
+        if [[ $file == $c$errors ]]; then
+            echo "log-once success after failure for $c"
+        fi
     fi
     return 0
 }