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 |
|
