# +----+----+----+----+ # | | | | | # Author: Mark David Scott Cunningham | M | D | S | C | # +----+----+----+----+ # Created: 2014-04-18 # Updated: 2018-02-18 # # #!/bin/bash ## COLORS: Taste the Rainbow BLACK=$(tput setaf 0); RED=$(tput setaf 1) GREEN=$(tput setaf 2); YELLOW=$(tput setaf 3) BLUE=$(tput setaf 4); PURPLE=$(tput setaf 5) CYAN=$(tput setaf 6); WHITE=$(tput setaf 7) BRIGHT=$(tput bold); NORMAL=$(tput sgr0) BLINK=$(tput blink); REVERSE=$(tput smso) UNDERLINE=$(tput smul); ## Add extended globbing shopt -s extglob ## Initializations hourtotal=($(for ((i=0;i<23;i++)); do echo 0; done)); grandtotal=0; nocolor=''; progress=''; CSV=''; DECOMP="$(which grep)"; DATE=$(date +"%d/%b/%Y"); DATESET='' FMT=" %5s" DOMAINS="/usr/local/apache/logs/access_log /usr/local/apache/domlogs/*/!(*[^ssl]_log*)"; RANGE=$(for x in {23..0}; do date --date="-$x hour" +"%d/%b/%Y:%H:"; done); THRESH=''; while getopts "a:cd:l:npr:8t:vh" option; do case "${option}" in a) DOMAINS=$(for user in $(echo ${OPTARG} | sed 's/,/ /g'); do echo /usr/local/apache/domlogs/$user/* | grep -Ev '(ftp_log|bytes_log|.offset)$'; done) ;; c) CSV=1; BRIGHT=''; NORMAL=''; FMT='"%s",' ;; # Caclulate date string for searches d) DATESET=1; DATE=$(date --date="-${OPTARG} days" +"%d/%b/%Y"); DECOMP="$(which zgrep)"; SUFFIX=$(date --date="-${OPTARG} days" +"-%b-%Y.gz") DOMAINS="/usr/local/apache/logs/access_log /home/*/logs/!(*[^ssl]_log*)$SUFFIX" RANGE=$(for x in {23..0}; do date --date="-${OPTARG} days -$x hour" +"%d/%b/%Y:%H:"; done) ;; # Use list of domains rather than all sites l) DOMAINS="$(for x in $(echo ${OPTARG} | sed 's/,/ /g'); do echo /usr/local/apache/domlogs/*/$x; done)" ;; # Print w/o color in b/w n) nocolor=1; color=''; BRIGHT=''; NORMAL='' ;; # Show progress indicator: account :: logfile p) progress=1 ;; # Print only a specified range of hours r) INPUT=$(echo ${OPTARG} | sed 's/,/ /g'); FMT=" %7s"; RANGE=$(for x in $(seq -w $INPUT); do echo "${DATE}:${x}:"; done) ;; 8) RANGE=$(for x in {7..0}; do date --date="-$x hours" +"%d/%b/%Y:%H:"; done); FMT=" %7s" ;; # Threshold for printing only busy sites t) THRESH=${OPTARG} ;; # Verbose outpout for debugging v) echo -e "\nDecomp : $DECOMP\nDate : $DATE\nSuffix : $SUFFIX\nRange : $(echo -n $RANGE)\nDomains : $DOMAINS\nThreshold: $THRESH\n" ;; # Help output h) echo -e "\n ${BRIGHT}Usage:${NORMAL} $0 [OPTIONS]\n -a ... Accounts -c ... CSV format (for spreadsheet or graphing) -d ... days-ago <##> -h ... Print this help and quit -l ... list of domains -n ... No Color (for output to files) -p ... Progress, show name of current log -r ... Range of hours -8 ... Auto set to previous 8 hours -t ... threshold value <#####> -v ... Verbose (debugging output)\n"; exit ;; esac done; echo ## Header if [[ $CSV ]]; then printf '"",'; else printf "${BRIGHT} %15s" "User/Hour"; fi for hour in $RANGE; do printf "$FMT" "$(echo $hour | cut -d: -f2):00"; done if [[ $CSV ]]; then printf '\"\"\n' else printf "%8s %-s${NORMAL}\n" "Total" " Domain Name" fi ## Data gathering and display for logfile in $DOMAINS; do total=0; # If progress flag is given then print if [[ $progress && ! $CSV ]]; then log=$(echo $logfile | awk -F/ '{print $(NF-1)" :: "$NF}') printf " Reading: %s \r" "$log" fi # Only print if the threshold condition is set/met if [[ -z $THRESH || $THRESH -le $($DECOMP -c $DATE $logfile) ]]; then if [[ ! $nocolor && ! $CSV ]]; then color="${BLUE}"; fi # Set the logs to use based on the date searched if [[ $DATE != $(date +"%d/%b/%Y") || $DATESET ]]; then ACCT=$(echo $logfile | cut -d/ -f3) SITE=$(basename $logfile $SUFFIX) else ACCT=$(echo $logfile | cut -d/ -f6) SITE=$(echo $logfile | cut -d/ -f7) fi # Print either the account or the domain with formatting if [[ $CSV && $ACCT == 'access_log' ]]; then printf '"%s",' "$ACCT" elif [[ $CSV ]]; then printf '"%s",' "$SITE" else printf "${color} %15s" "$ACCT" fi i=0; # Iterate through the hours for hour in $RANGE; do count=$($DECOMP -c "$hour" $logfile); hourtotal[$i]=$((${hourtotal[$i]}+$count)) if [[ $nocolor || $CSV ]]; then printf "$FMT" "$count" else ## COLOR VERSION (HEAT MAP) if [[ $count -gt 20000 ]]; then color="${BRIGHT}${RED}"; elif [[ $count -gt 2000 ]]; then color="${RED}"; elif [[ $count -gt 200 ]]; then color="${YELLOW}"; else color="${GREEN}"; fi printf "${color}$FMT${NORMAL}" "$count" fi # Totals for all the hours checked total=$((${total}+${count})); i=$(($i+1)) done # Total the totals grandtotal=$(($grandtotal+$total)) # Print Totals if [[ $CSV ]]; then printf '""\n' elif [[ $nocolor ]]; then printf "%8s %-s\n" "$total" "$SITE" else ## Color version printf "${CYAN}%8s ${PURPLE}%-s${NORMAL}\n" "$total" "$SITE" fi fi done ## Footer if [[ ! $CSV ]]; then printf "${BRIGHT} %15s" "Total" for x in $(seq 0 $((${i}-1))); do printf "$FMT" "${hourtotal[$x]}"; done printf "%8s %-s${NORMAL}\n" "$grandtotal" "<< Grand Total" fi echo