You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.2 KiB
124 lines
4.2 KiB
#!/bin/bash |
|
# env variables |
|
export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" |
|
export LANG="en_US.UTF-8" |
|
|
|
# colors |
|
red=$(tput setaf 1) |
|
green=$(tput setaf 2) |
|
yellow=$(tput setaf 3) |
|
reset=$(tput sgr0) |
|
|
|
logDepthOfDays=6 |
|
logNTopMessages=10 |
|
logLimitNErrors=0 |
|
|
|
while getopts "hd:n:l:" opt; do |
|
case $opt in |
|
d) |
|
if [ $OPTARG -ge 0 ]; then |
|
logDepthOfDays=$OPTARG |
|
else |
|
echo "Option -d must have numeric value" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
n) |
|
if [ $OPTARG -gt 0 ]; then |
|
logNTopMessages=$OPTARG |
|
else |
|
echo "Option -n must have numeric value" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
l) |
|
if [ $OPTARG -gt 0 ]; then |
|
logLimitNErrors=$OPTARG |
|
else |
|
echo "Option -l must have numeric value" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
\?|h) |
|
echo "log_check.sh can understand next options:" >&2 |
|
echo " -d N How many logs in depth of days are defined by N will be parsed." >&2 |
|
echo " -n N Top of lines which will be show in output are defined by N." >&2 |
|
echo " -l N Low limit of a number of identical messages when lines will not be shown are defined by N." >&2 |
|
echo " N should be a positive numeric value." >&2 |
|
exit 1 |
|
;; |
|
esac |
|
done |
|
|
|
[[ $(which pv) ]] && pvUtil=true || pvUtil=false |
|
pvLimit="50M" # default rate-limit for pv |
|
|
|
psqlCmd="psql -tXAF: $psqlArgs" |
|
pgDataDir=$($psqlCmd -c "show data_directory") |
|
pgLogDir=$($psqlCmd -c "show log_directory") |
|
pgTmplateLogFile=$($psqlCmd -c "show log_filename") |
|
pgLcMessages=$($psqlCmd -c "show lc_messages") |
|
|
|
if [[ $(echo $pgLogDir |cut -c1) == "/" ]]; then # this is an absolute path |
|
pgLogDir="$pgLogDir/$pgLogFile" |
|
else # this is a relative path |
|
pgLogDir="$pgDataDir/$pgLogDir/$pgLogFile" |
|
fi |
|
|
|
for pgDayOfLog in $(seq 0 $logDepthOfDays); do |
|
|
|
pgLogFile=$(date --date="$pgDayOfLog day ago" +$pgTmplateLogFile) |
|
pgCompleteLogPath="$pgLogDir/$pgLogFile" |
|
|
|
if [[ -f $pgCompleteLogPath ]]; then |
|
ls -lh $pgCompleteLogPath |
|
else |
|
continue |
|
fi |
|
|
|
answer="" |
|
if [[ $(stat --printf="%s" $pgCompleteLogPath) -gt 1000000000 ]]; then # print warning about the log size |
|
while [[ $answer != "y" && $answer != "n" ]] |
|
do |
|
echo -n "${yellow}Logfile size is more than 1Gb, parse it anyway? [y/n]: ${reset}" |
|
read answer |
|
done |
|
else |
|
answer="y" # size is less than 2Gb and it's acceptable for us. |
|
fi |
|
|
|
if [[ $answer == "y" ]]; then |
|
answer="" |
|
if [[ $pgLcMessages != 'C' && $pgLcMessages != *"en_US"* ]]; then # print warning about the log size |
|
while [[ $answer != "y" && $answer != "n" ]] |
|
do |
|
echo -n "${red}PostgreSQL server's lc_messages is neither C nor en_US.UTF-8. ${yellow}Parse the log anyway? [y/n]: ${reset}" |
|
read answer |
|
done |
|
else |
|
answer="y" # no problem with lc_messages |
|
fi |
|
fi |
|
|
|
if [[ $answer == "y" ]]; then # we are ready to parse log |
|
tempPgLog=$(mktemp /tmp/pg.XXXXXX.out) |
|
if [[ $pvUtil == true ]]; then # handle log with pv |
|
pv --progress --timer --eta --bytes --width 100 --rate-limit $pvLimit $pgCompleteLogPath |grep -oE '(ERROR|WARNING|FATAL|PANIC).*' > $tempPgLog |
|
else # do it without pv |
|
grep -oE '(ERROR|WARNING|FATAL|PANIC).*' $pgCompleteLogPath > $tempPgLog |
|
fi |
|
|
|
nPanic=$(grep -c ^PANIC $tempPgLog); nFatal=$(grep -c ^FATAL $tempPgLog); nError=$(grep -c ^ERROR $tempPgLog); nWarning=$(grep -c ^WARNING $tempPgLog) |
|
echo -e " PANIC: total $nPanic (print all)" |
|
grep -wE ^PANIC $tempPgLog |sort |uniq -c |sort -rnk1 |
|
echo -e " FATAL: total $nFatal (print all)" |
|
grep -wE ^FATAL $tempPgLog |sort |uniq -c |sort -rnk1 |
|
echo -e " ERROR: total $nError (print top$logNTopMessages)" |
|
grep -wE ^ERROR $tempPgLog |sort |uniq -c |sort -rnk1 |head -n $logNTopMessages | awk -v limit=${logLimitNErrors} '$1 > limit{print}' |
|
echo -e " WARNING: total $nWarning (print top$logNTopMessages)" |
|
grep -wE ^WARNING $tempPgLog |sort |uniq -c |sort -rnk1 |head -n $logNTopMessages | awk -v limit=${logLimitNErrors} '$1 > limit{print}' |
|
[[ -f $tempPgLog ]] && rm -f $tempPgLog |
|
echo "" |
|
fi |
|
done |
|
#######
|
|
|