Generalised messaging function » History » Version 1
Charles Atkinson, 05/01/2020 11:15
Creation
| 1 | 1 | Charles Atkinson | h1. Generalised messaging function |
|---|---|---|---|
| 2 | 1 | Charles Atkinson | |
| 3 | 1 | Charles Atkinson | {{toc}} |
| 4 | 1 | Charles Atkinson | |
| 5 | 1 | Charles Atkinson | h1. Called function |
| 6 | 1 | Charles Atkinson | |
| 7 | 1 | Charles Atkinson | finalise: called after generating an error message |
| 8 | 1 | Charles Atkinson | |
| 9 | 1 | Charles Atkinson | h1. Function msg |
| 10 | 1 | Charles Atkinson | |
| 11 | 1 | Charles Atkinson | <pre> |
| 12 | 1 | Charles Atkinson | #!/bin/bash <- Does nothing but triggers editor syntax highlighting |
| 13 | 1 | Charles Atkinson | |
| 14 | 1 | Charles Atkinson | # Copyright (C) 2013 Charles Atkinson |
| 15 | 1 | Charles Atkinson | # |
| 16 | 1 | Charles Atkinson | # This program is free software; you can redistribute it and/or modify |
| 17 | 1 | Charles Atkinson | # it under the terms of the GNU General Public License as published by |
| 18 | 1 | Charles Atkinson | # the Free Software Foundation; either version 2 of the License, or |
| 19 | 1 | Charles Atkinson | # (at your option) any later version. |
| 20 | 1 | Charles Atkinson | # |
| 21 | 1 | Charles Atkinson | # This program is distributed in the hope that it will be useful, |
| 22 | 1 | Charles Atkinson | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 23 | 1 | Charles Atkinson | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 24 | 1 | Charles Atkinson | # GNU General Public License for more details. |
| 25 | 1 | Charles Atkinson | # |
| 26 | 1 | Charles Atkinson | # You should have received a copy of the GNU General Public License |
| 27 | 1 | Charles Atkinson | # along with this program; if not, write to the Free Software |
| 28 | 1 | Charles Atkinson | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 29 | 1 | Charles Atkinson | |
| 30 | 1 | Charles Atkinson | #-------------------------- |
| 31 | 1 | Charles Atkinson | # Name: msg |
| 32 | 1 | Charles Atkinson | # Purpose: generalised messaging interface |
| 33 | 1 | Charles Atkinson | # Arguments: |
| 34 | 1 | Charles Atkinson | # $1 class: D, E, I or W indicating Debug, Error, Information or Warning |
| 35 | 1 | Charles Atkinson | # $2 message text |
| 36 | 1 | Charles Atkinson | # $3 logger control. Optional |
| 37 | 1 | Charles Atkinson | # If "logger" then also send class I messages with logger (to syslog) |
| 38 | 1 | Charles Atkinson | # If "no_logger" then do not also send class W and E messages with |
| 39 | 1 | Charles Atkinson | # logger (to syslog). |
| 40 | 1 | Charles Atkinson | # Global variables read: none |
| 41 | 1 | Charles Atkinson | # Output: information messages to stdout; the rest to stderr |
| 42 | 1 | Charles Atkinson | # Returns: |
| 43 | 1 | Charles Atkinson | # Does not return (calls finalise) when class is E for error |
| 44 | 1 | Charles Atkinson | # Otherwise returns 0 |
| 45 | 1 | Charles Atkinson | #-------------------------- |
| 46 | 1 | Charles Atkinson | function msg { |
| 47 | 1 | Charles Atkinson | local buf class i logger_flag logger_msg message_text prefix |
| 48 | 1 | Charles Atkinson | local -r regex='^(|(logger)|(no_logger))$' |
| 49 | 1 | Charles Atkinson | local -r max_logger_chars=100000 |
| 50 | 1 | Charles Atkinson | |
| 51 | 1 | Charles Atkinson | # Process arguments |
| 52 | 1 | Charles Atkinson | # ~~~~~~~~~~~~~~~~~ |
| 53 | 1 | Charles Atkinson | class="${1:-}" |
| 54 | 1 | Charles Atkinson | message_text="${2:-}" |
| 55 | 1 | Charles Atkinson | [[ ! ${3:-} =~ $regex ]] && msg E "Programming error: invalid ${FUNCNAME[0]} third argument '${3:-}' (does not match regex $regex)" |
| 56 | 1 | Charles Atkinson | |
| 57 | 1 | Charles Atkinson | # Class-dependent set-up |
| 58 | 1 | Charles Atkinson | # ~~~~~~~~~~~~~~~~~~~~~~ |
| 59 | 1 | Charles Atkinson | logger_flag=$false |
| 60 | 1 | Charles Atkinson | case "$class" in |
| 61 | 1 | Charles Atkinson | D ) |
| 62 | 1 | Charles Atkinson | [[ ! $debugging_flag ]] && return |
| 63 | 1 | Charles Atkinson | prefix='DEBUG: ' |
| 64 | 1 | Charles Atkinson | [[ ${3:-} = logger ]] && logger_flag=$true |
| 65 | 1 | Charles Atkinson | ;; |
| 66 | 1 | Charles Atkinson | E ) |
| 67 | 1 | Charles Atkinson | error_flag=$true |
| 68 | 1 | Charles Atkinson | prefix='ERROR: ' |
| 69 | 1 | Charles Atkinson | [[ ${3:-} != no_logger ]] && logger_flag=$true |
| 70 | 1 | Charles Atkinson | ;; |
| 71 | 1 | Charles Atkinson | I ) |
| 72 | 1 | Charles Atkinson | prefix= |
| 73 | 1 | Charles Atkinson | [[ ${3:-} = logger ]] && logger_flag=$true |
| 74 | 1 | Charles Atkinson | ;; |
| 75 | 1 | Charles Atkinson | W ) |
| 76 | 1 | Charles Atkinson | warning_flag=$true |
| 77 | 1 | Charles Atkinson | prefix='WARN: ' |
| 78 | 1 | Charles Atkinson | [[ ${3:-} != no_logger ]] && logger_flag=$true |
| 79 | 1 | Charles Atkinson | ;; |
| 80 | 1 | Charles Atkinson | * ) |
| 81 | 1 | Charles Atkinson | msg E "msg: invalid class '$class': '$*'" |
| 82 | 1 | Charles Atkinson | esac |
| 83 | 1 | Charles Atkinson | |
| 84 | 1 | Charles Atkinson | # Write to syslog |
| 85 | 1 | Charles Atkinson | # ~~~~~~~~~~~~~~~ |
| 86 | 1 | Charles Atkinson | if [[ $logger_flag ]]; then |
| 87 | 1 | Charles Atkinson | preamble=<whatever is appropriate for your app> |
| 88 | 1 | Charles Atkinson | logger_msg=("$prefix$message_text") |
| 89 | 1 | Charles Atkinson | if ((${#logger_msg}>max_logger_chars)); then |
| 90 | 1 | Charles Atkinson | unset logger_msg |
| 91 | 1 | Charles Atkinson | logger_msg+=("${prefix}Message too big (>$max_logger_chars characters)") |
| 92 | 1 | Charles Atkinson | logger_msg+=('The message is split into pieces:') |
| 93 | 1 | Charles Atkinson | buf=$message_text |
| 94 | 1 | Charles Atkinson | while ((${#buf}>0)) |
| 95 | 1 | Charles Atkinson | do |
| 96 | 1 | Charles Atkinson | logger_msg+=("${buf:0:$max_logger_chars}") |
| 97 | 1 | Charles Atkinson | buf=${buf:$max_logger_chars} |
| 98 | 1 | Charles Atkinson | done |
| 99 | 1 | Charles Atkinson | fi |
| 100 | 1 | Charles Atkinson | for ((i=0;i<${#logger_msg[*]};i++)) |
| 101 | 1 | Charles Atkinson | do |
| 102 | 1 | Charles Atkinson | buf=$(logger -t "$preamble" -- "${logger_msg[i]}" 2>&1) |
| 103 | 1 | Charles Atkinson | [[ $buf != '' ]] && msg W "${FUNCNAME[0]}: problem writing to syslog: $buf" |
| 104 | 1 | Charles Atkinson | done |
| 105 | 1 | Charles Atkinson | fi |
| 106 | 1 | Charles Atkinson | |
| 107 | 1 | Charles Atkinson | # Write to stdout or stderr |
| 108 | 1 | Charles Atkinson | # ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 109 | 1 | Charles Atkinson | # Which is to log if such redirection is set up, as is usual |
| 110 | 1 | Charles Atkinson | message_text="$(date "$log_date_format") $prefix$message_text" |
| 111 | 1 | Charles Atkinson | if [[ $class = I ]]; then |
| 112 | 1 | Charles Atkinson | echo "$message_text" |
| 113 | 1 | Charles Atkinson | else |
| 114 | 1 | Charles Atkinson | echo "$message_text" >&2 |
| 115 | 1 | Charles Atkinson | if [[ $class = E ]]; then |
| 116 | 1 | Charles Atkinson | [[ ! $finalising_flag ]] && finalise 1 |
| 117 | 1 | Charles Atkinson | fi |
| 118 | 1 | Charles Atkinson | fi |
| 119 | 1 | Charles Atkinson | |
| 120 | 1 | Charles Atkinson | return 0 |
| 121 | 1 | Charles Atkinson | } # end of function msg |
| 122 | 1 | Charles Atkinson | </pre> |