Skip to content

Instantly share code, notes, and snippets.

@ltakens
Last active May 2, 2025 16:09
Show Gist options
  • Select an option

  • Save ltakens/cb6b16164bd84248822b533c1900b2bc to your computer and use it in GitHub Desktop.

Select an option

Save ltakens/cb6b16164bd84248822b533c1900b2bc to your computer and use it in GitHub Desktop.
Linux Open File Descriptor Watchdog
#!/bin/bash
# ===============================================================
# Open File Descriptor Watchdog
# ===============================================================
#
# This script monitors the number of open file descriptors (FDs)
# per process on a Linux server. If any process exceeds the
# defined threshold, it sends a Telegram alert with process info.
#
# ---------------------
# Configuration
# ---------------------
# 1. Set your Telegram bot ID and token below.
# 2. Set the FD usage threshold below (default is 100).
#
# ---------------------
# Install cronjob
# ---------------------
# Run every 15 minutes:
# */15 * * * * /path/to/fd_watchdog.sh
#
# Make sure the script is executable:
# chmod +x /path/to/fd_watchdog.sh
#
# ===============================================================
# ================
# Config
# ================
THRESHOLD=5000
DATE=$(date "+%Y-%m-%d %H:%M:%S")
TG_BOT_ID="your_bot_id_here" # Only the numeric ID (e.g., 123456789)
TG_BOT_TOKEN="your_bot_token_here" # Full token from BotFather
# ================
# URL encode helper
# ================
urlencode() {
local LANG=C
local length="${#1}"
for (( i = 0; i < length; i++ )); do
local c="${1:i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
done
}
# ================
# Telegram function
# ================
send_telegram_message() {
local message="$1"
local message_encoded=$(urlencode "$message")
curl -s -o /dev/null --max-time 5 \
"https://api.telegram.org/bot$TG_BOT_ID:$TG_BOT_TOKEN/sendMessage?chat_id=-156311897&text=$message_encoded"
}
# ================
# Watchdog logic
# ================
lsof -nP | awk '{print $2}' | sort | uniq -c | while read count pid; do
if [[ "$count" -gt "$THRESHOLD" ]]; then
cmd=$(ps -p "$pid" -o comm= 2>/dev/null)
if [ -n "$cmd" ]; then
message="! $DATE - PID $pid ($cmd) is using $count FDs (threshold: $THRESHOLD)"
send_telegram_message "$message"
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment