Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / logs / loggrepx_ @ 00737cf2

Historique | Voir | Annoter | Télécharger (5,4 ko)

1
#!/bin/bash
2

    
3
set -e
4

    
5
: << =cut
6

    
7
=head1 NAME
8

    
9
loggrepx - Counts the number of matching log lines by log file
10

    
11
=head1 DESCRIPTION
12

    
13
This plugin is somewhat of a bash port of the original loggrep plugin,
14
except that it displays a breakdown of matches per file, rather than
15
aggregating matches across all files. It is intended to answer the
16
question, "Which of my logs are reporting concerning events right now?"
17

    
18
=head1 CONFIGURATION
19

    
20
The plugin can be included multiple times to create graphs for various
21
differing kinds of information in your log files. For example, you may
22
want to monitor the occurrence of 5xx errors in your webserver logs, but
23
also the occurrence of alert|critical|emergency entries in your syslog.
24

    
25
You can accomplish this by linking the plugin twice and providing
26
different criteria for each instance.
27

    
28
Note that most instances will probably work best when run as root, since
29
log files are usually (or at least should be) controlled with strict
30
permissions.
31

    
32
Available config options include the following:
33

    
34
 env.logfiles         - Files to grep (shellglob) (required)
35
 env.regex            - Regex to look for (required)
36
 env.title            - Graph title
37
 env.warning          - Default warning level
38
 env.critical         - Default critical level
39
 env.[field]_label    - Label to use for a specific logfile
40
 env.[field]_warning  - Warning level for specific logfile
41
 env.[field]_critical - Critical level for specific logfile
42

    
43
NOTE: for any variable with [field] in it, [field] is derived from the
44
full logfile path by simply removing the preceding slash and replacing
45
all non-alphanumerics with underscores. For example, the "warning" field
46
for the logfile F</var/log/nginx/errors.log> would be
47
F<var_log_nginx_errors_log_warning>.
48

    
49
One good way to get these names is to run C<munin-run [plugin-name]>
50
after you've configured the required variables and then just copy/paste
51
the names from the output.
52

    
53
=head1 AUTHOR
54

    
55
Kael Shipman <kael.shipman@gmail.com>
56

    
57
=head1 LICENSE
58

    
59
Copyright 2018 Kael Shipman<kael.shipman@gmail.com>
60

    
61
Permission is hereby granted, free of charge, to any person obtaining a
62
copy of this software and associated documentation files (the "Software"),
63
to deal in the Software without restriction, including without limitation
64
the rights to use, copy, modify, merge, publish, distribute, sublicense,
65
and/or sell copies of the Software, and to permit persons to whom the
66
Software is furnished to do so, subject to the following conditions:
67

    
68
The above copyright notice and this permission notice shall be included
69
in all copies or substantial portions of the Software.
70

    
71
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
72
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
73
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
74
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
75
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
76
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
77
OTHER DEALINGS IN THE SOFTWARE.
78

    
79
=head1 MAGIC MARKERS
80

    
81
 #%# family=manual
82

    
83
=cut
84

    
85

    
86

    
87
. "$MUNIN_LIBDIR/plugins/plugin.sh"
88
LOGFILES="$(IFS= ; for f in $logfiles; do echo "$f"; done)"
89
title="${title:-Log Matches}"
90

    
91

    
92

    
93

    
94
function config() {
95
    echo "graph_title ${title}"
96
    echo "graph_args --base 1000 -l 0"
97
    echo "graph_vlabel ${title}"
98
    echo "graph_category other"
99
    echo "graph_info Lists number of times the given regex is matched in the given log files per period"
100

    
101
    local var_prefix var logfile lbl
102
    while read -u 3 -r logfile; do
103
        var_prefix="$(echo "$logfile" | sed -r 's/^[^a-zA-Z]+//g' | sed -r 's/[^a-zA-Z0-9]+/_/g')"
104
        var="${var_prefix}_label"
105
        lbl="${!var:-$logfile}"
106
        echo "$var_prefix.label $lbl"
107
        print_warning "$var_prefix"
108
        print_critical "$var_prefix"
109
        echo "$var_prefix.info Lines that match '${regex}' in log file '$logfile'"
110
    done 3< <(echo "$LOGFILES")
111
}
112

    
113

    
114

    
115

    
116
function fetch() {
117
    # Load state
118
    touch "$MUNIN_STATEFILE"
119
    local curstate="$(cat "$MUNIN_STATEFILE")"
120
    local nextstate=()
121

    
122
    local var_prefix logfile prvlines curlines matches
123
    while read -u 3 -r logfile; do
124
        # Convert current logfile path to variable prefix
125
        var_prefix="$(echo "$logfile" | sed -r 's/^[^a-zA-Z]+//g' | sed -r 's/[^a-zA-Z0-9]+/_/g')"
126

    
127
        # Get running number of lines to determine whether or not the file may have been rotated
128
        prvlines="$(echo "$curstate" | grep "^${var_prefix}_lines=" | cut -f 2 -d "=")"
129
        if [ -z "$prvlines" ]; then
130
            prvlines=0
131
        fi
132

    
133
        # Get the current number of lines in the file
134
        curlines="$(wc -l < "$logfile")"
135
        if [ -z "$curlines" ]; then
136
            curlines=0
137
        fi
138

    
139
        # If the current line count is less than the previous line count, we've probably rotated.
140
        # Reset to 0.
141
        if [ "$curlines" -lt "$prvlines" ]; then
142
            prvlines=0
143
        else
144
            prvlines=$((prvlines + 1))
145
        fi
146

    
147
        # Get current number of incidents
148
        matches="$(tail -n +"$prvlines" "$logfile" | grep -Ec "${regex}" || true)"
149

    
150
        # Echo the value
151
        echo "$var_prefix.value $matches"
152

    
153
        # Push onto next state
154
        nextstate+=("${var}_lines=$curlines")
155
    done 3< <(echo "$LOGFILES")
156

    
157
    # Write state to munin statefile
158
    (IFS=$'\n'; echo "${nextstate[*]}" > "$MUNIN_STATEFILE")
159

    
160
    return 0
161
}
162

    
163

    
164

    
165

    
166

    
167
case "$1" in
168
    config) config ;;
169
    *) fetch ;;
170
esac
171