Project

General

Profile

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>