Tuesday, December 9, 2025

monitor

#!/bin/bash
# ==============================================================================
# Script: monitor_wls_html.sh
# Author: Abdul Muqeet
# Purpose: Monitor EBS 12.2 WLS logs and send a formatted HTML alert.
#          - Sources EBS environment automatically.
#          - Auto-discovers all 50+ instances using $FMW_HOME.
#          - Generates a styled HTML table with "View" and "Server" columns.
# ==============================================================================

# 1. LOAD EBS ENVIRONMENT
# ------------------------------------------------------------------------------
# We go to HOME and source the run file to get $FMW_HOME, $CONTEXT_NAME, etc.
cd $HOME
if [ -f "./EBSapps.env" ]; then
    . ./EBSapps.env run
else
    echo "Error: EBSapps.env not found in $HOME"
    exit 1
fi

# 2. CONFIGURATION (Dynamic based on Env)
# ------------------------------------------------------------------------------
# dynamically build the domain home path using variables from EBSapps.env
DOMAIN_HOME="$FMW_HOME/user_projects/domains/EBS_domain_$CONTEXT_NAME"
STATE_DIR="$HOME/scripts/wls_monitor_state"
EMAIL_TO="dba_team@company.com"
HOSTNAME=$(hostname)

# Error Patterns (Regex)
PATTERNS="BEA-000337|java.lang.OutOfMemoryError|Deadlock detected|BEA-001129|MDS-00001|UncheckedException"

# 3. PREPARATION
# ------------------------------------------------------------------------------
mkdir -p "$STATE_DIR"
HTML_BODY="$STATE_DIR/email_body.html"
> "$HTML_BODY"
ERRORS_FOUND=0

# 4. START HTML GENERATION
# ------------------------------------------------------------------------------
cat <<EOF > "$HTML_BODY"
<html>
<head>
<style>
  body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #333; }
  .header { background-color: #d9534f; color: white; padding: 15px; text-align: center; border-radius: 5px 5px 0 0; }
  .summary { background-color: #f8f9fa; padding: 15px; border: 1px solid #ddd; margin-bottom: 20px; }
  table { border-collapse: collapse; width: 100%; font-size: 13px; }
  th { background-color: #292b2c; color: white; padding: 10px; text-align: left; }
  td { border: 1px solid #ddd; padding: 8px; vertical-align: top; }
  tr:nth-child(even) { background-color: #f2f2f2; }
  .server-badge { background-color: #0275d8; color: white; padding: 3px 8px; border-radius: 4px; font-weight: bold; font-size: 11px; }
  .log-badge { background-color: #5bc0de; color: white; padding: 3px 8px; border-radius: 4px; font-size: 11px; }
  .error-text { color: #d9534f; font-family: 'Courier New', Courier, monospace; white-space: pre-wrap; word-wrap: break-word; }
</style>
</head>
<body>
EOF

# 5. DYNAMIC LOG DISCOVERY & PARSING
# ------------------------------------------------------------------------------
# Verify DOMAIN_HOME exists before searching
if [ ! -d "$DOMAIN_HOME" ]; then
    echo "Error: Domain Home not found at $DOMAIN_HOME"
    exit 1
fi

echo "Scanning logs in $DOMAIN_HOME..."
LOG_FILES=$(find "$DOMAIN_HOME/servers" -maxdepth 3 -path "*/logs/*.log" -o -path "*/logs/*.out")

TABLE_ROWS=""

for LOG_FILE in $LOG_FILES; do
    # Create unique state file path (replace slashes with underscores)
    STATE_FILE="$STATE_DIR/$(echo "$LOG_FILE" | sed 's/\//_/g').state"
    
    # Get Line Counts
    CURRENT_LINES=$(wc -l < "$LOG_FILE")
    if [ -f "$STATE_FILE" ]; then LAST_LINES=$(cat "$STATE_FILE"); else LAST_LINES=0; fi
    
    # Handle Log Rotation
    if [ "$CURRENT_LINES" -lt "$LAST_LINES" ]; then LAST_LINES=0; fi

    # PROCESS NEW LINES
    if [ "$CURRENT_LINES" -gt "$LAST_LINES" ]; then
        LINES_TO_READ=$((CURRENT_LINES - LAST_LINES))
        
        # Grep for errors, limit to last 50 lines
        NEW_ERRORS=$(tail -n "$LINES_TO_READ" "$LOG_FILE" | grep -E "$PATTERNS" | tail -n 50)

        if [ ! -z "$NEW_ERRORS" ]; then
            ((ERRORS_FOUND++))
            
            # Extract Server Name (e.g., oacore_server1)
            SERVER_NAME=$(echo "$LOG_FILE" | awk -F'/servers/' '{print $2}' | cut -d'/' -f1)
            FILE_NAME=$(basename "$LOG_FILE")

            # HTML Escape special characters
            SAFE_ERRORS=$(echo "$NEW_ERRORS" | sed 's/&/&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')

            # Append Row to Table
            TABLE_ROWS="${TABLE_ROWS}
            <tr>
                <td width='15%'><span class='server-badge'>$SERVER_NAME</span></td>
                <td width='15%'><span class='log-badge'>$FILE_NAME</span></td>
                <td class='error-text'>$SAFE_ERRORS</td>
            </tr>"
        fi

        # Update State
        echo "$CURRENT_LINES" > "$STATE_FILE"
    fi
done

# 6. FINALIZE HTML & SEND
# ------------------------------------------------------------------------------
if [ "$ERRORS_FOUND" -gt 0 ]; then
    
    cat <<EOF >> "$HTML_BODY"
    <div class="header">
        <h2>⚠️ Critical Alerts Detected on $HOSTNAME ($CONTEXT_NAME)</h2>
    </div>
    <div class="summary">
        <strong>Total Servers Affected:</strong> $ERRORS_FOUND<br>
        <strong>Context:</strong> $CONTEXT_NAME<br>
        <strong>Timestamp:</strong> $(date)<br>
    </div>
    
    <table>
        <thead>
            <tr>
                <th>Managed Server</th>
                <th>Log File</th>
                <th>Error Trace snippet</th>
            </tr>
        </thead>
        <tbody>
            $TABLE_ROWS
        </tbody>
    </table>
    <br>
    <p style="font-size: 10px; color: #777;">Generated by Automation Script: monitor_wls_html.sh | Author: Abdul Muqeet</p>
</body>
</html>
EOF

    # SEND EMAIL
    (
    echo "To: $EMAIL_TO"
    echo "Subject: 🔴 WLS Alert: $HOSTNAME - Errors Detected in $ERRORS_FOUND Instances"
    echo "MIME-Version: 1.0"
    echo "Content-Type: text/html; charset=utf-8"
    echo ""
    cat "$HTML_BODY"
    ) | /usr/sbin/sendmail -t

    echo "Alert sent to $EMAIL_TO"
fi

rm "$HTML_BODY"

No comments:

Post a Comment