Sanitized mirror from private repository - 2026-04-18 11:19:59 UTC
This commit is contained in:
311
ansible/automation/playbooks/disk_usage_report.yml
Normal file
311
ansible/automation/playbooks/disk_usage_report.yml
Normal file
@@ -0,0 +1,311 @@
|
||||
---
|
||||
# Disk Usage Report Playbook
|
||||
# Monitor storage usage across all hosts and generate comprehensive reports
|
||||
# Usage: ansible-playbook playbooks/disk_usage_report.yml
|
||||
# Usage: ansible-playbook playbooks/disk_usage_report.yml -e "alert_threshold=80"
|
||||
# Usage: ansible-playbook playbooks/disk_usage_report.yml -e "detailed_analysis=true"
|
||||
|
||||
- name: Generate Comprehensive Disk Usage Report
|
||||
hosts: "{{ host_target | default('all') }}"
|
||||
gather_facts: yes
|
||||
vars:
|
||||
alert_threshold: "{{ alert_threshold | default(85) }}"
|
||||
warning_threshold: "{{ warning_threshold | default(75) }}"
|
||||
detailed_analysis: "{{ detailed_analysis | default(false) }}"
|
||||
report_dir: "/tmp/disk_reports"
|
||||
include_docker_analysis: "{{ include_docker_analysis | default(true) }}"
|
||||
top_directories_count: "{{ top_directories_count | default(10) }}"
|
||||
|
||||
tasks:
|
||||
- name: Create report directory
|
||||
file:
|
||||
path: "{{ report_dir }}/{{ ansible_date_time.date }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Get basic disk usage
|
||||
shell: df -h
|
||||
register: disk_usage_basic
|
||||
changed_when: false
|
||||
|
||||
- name: Get disk usage percentages
|
||||
shell: df --output=source,pcent,avail,target | grep -v "Filesystem"
|
||||
register: disk_usage_percent
|
||||
changed_when: false
|
||||
|
||||
- name: Identify high usage filesystems
|
||||
shell: |
|
||||
df --output=source,pcent,target | awk 'NR>1 {gsub(/%/, "", $2); if ($2 >= {{ alert_threshold }}) print $0}'
|
||||
register: high_usage_filesystems
|
||||
changed_when: false
|
||||
|
||||
- name: Get inode usage
|
||||
shell: df -i
|
||||
register: inode_usage
|
||||
changed_when: false
|
||||
|
||||
- name: Analyze Docker storage usage
|
||||
shell: |
|
||||
echo "=== DOCKER STORAGE ANALYSIS ==="
|
||||
if command -v docker &> /dev/null; then
|
||||
echo "Docker System Usage:"
|
||||
docker system df 2>/dev/null || echo "Cannot access Docker"
|
||||
echo ""
|
||||
|
||||
echo "Container Sizes:"
|
||||
docker ps --format "table {{.Names}}\t{{.Size}}" 2>/dev/null || echo "Cannot access Docker containers"
|
||||
echo ""
|
||||
|
||||
echo "Image Sizes:"
|
||||
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 2>/dev/null | head -20 || echo "Cannot access Docker images"
|
||||
echo ""
|
||||
|
||||
echo "Volume Usage:"
|
||||
docker volume ls -q | xargs -I {} sh -c 'echo "Volume: {}"; docker volume inspect {} --format "{{.Mountpoint}}" | xargs du -sh 2>/dev/null || echo "Cannot access volume"' 2>/dev/null || echo "Cannot access Docker volumes"
|
||||
else
|
||||
echo "Docker not available"
|
||||
fi
|
||||
register: docker_storage_analysis
|
||||
when: include_docker_analysis | bool
|
||||
changed_when: false
|
||||
|
||||
- name: Find largest directories
|
||||
shell: |
|
||||
echo "=== TOP {{ top_directories_count }} LARGEST DIRECTORIES ==="
|
||||
|
||||
# Find largest directories in common locations
|
||||
for path in / /var /opt /home /volume1 /volume2; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "=== $path ==="
|
||||
du -h "$path"/* 2>/dev/null | sort -hr | head -{{ top_directories_count }} || echo "Cannot analyze $path"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
register: largest_directories
|
||||
when: detailed_analysis | bool
|
||||
changed_when: false
|
||||
|
||||
- name: Analyze log file sizes
|
||||
shell: |
|
||||
echo "=== LOG FILE ANALYSIS ==="
|
||||
|
||||
# System logs
|
||||
echo "System Logs:"
|
||||
find /var/log -type f -name "*.log" -exec du -h {} \; 2>/dev/null | sort -hr | head -10 || echo "Cannot access system logs"
|
||||
echo ""
|
||||
|
||||
# Docker logs
|
||||
echo "Docker Container Logs:"
|
||||
if [ -d "/var/lib/docker/containers" ]; then
|
||||
find /var/lib/docker/containers -name "*-json.log" -exec du -h {} \; 2>/dev/null | sort -hr | head -10 || echo "Cannot access Docker logs"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Application logs
|
||||
echo "Application Logs:"
|
||||
find /volume1 /opt -name "*.log" -type f -exec du -h {} \; 2>/dev/null | sort -hr | head -10 || echo "No application logs found"
|
||||
register: log_analysis
|
||||
when: detailed_analysis | bool
|
||||
changed_when: false
|
||||
|
||||
- name: Check for large files
|
||||
shell: |
|
||||
echo "=== LARGE FILES (>1GB) ==="
|
||||
find / -type f -size +1G -exec du -h {} \; 2>/dev/null | sort -hr | head -20 || echo "No large files found or permission denied"
|
||||
register: large_files
|
||||
when: detailed_analysis | bool
|
||||
changed_when: false
|
||||
|
||||
- name: Analyze temporary files
|
||||
shell: |
|
||||
echo "=== TEMPORARY FILES ANALYSIS ==="
|
||||
|
||||
for temp_dir in /tmp /var/tmp /volume1/tmp; do
|
||||
if [ -d "$temp_dir" ]; then
|
||||
echo "=== $temp_dir ==="
|
||||
du -sh "$temp_dir" 2>/dev/null || echo "Cannot access $temp_dir"
|
||||
echo "File count: $(find "$temp_dir" -type f 2>/dev/null | wc -l)"
|
||||
echo "Oldest file: $(find "$temp_dir" -type f -printf '%T+ %p\n' 2>/dev/null | sort | head -1 | cut -d' ' -f2- || echo 'None')"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
register: temp_files_analysis
|
||||
changed_when: false
|
||||
|
||||
- name: Generate disk usage alerts
|
||||
set_fact:
|
||||
disk_alerts: []
|
||||
disk_warnings: []
|
||||
|
||||
- name: Process disk usage alerts
|
||||
set_fact:
|
||||
disk_alerts: "{{ disk_alerts + [item] }}"
|
||||
loop: "{{ disk_usage_percent.stdout_lines }}"
|
||||
when:
|
||||
- item.split()[1] | regex_replace('%', '') | int >= alert_threshold | int
|
||||
vars:
|
||||
usage_percent: "{{ item.split()[1] | regex_replace('%', '') | int }}"
|
||||
|
||||
- name: Process disk usage warnings
|
||||
set_fact:
|
||||
disk_warnings: "{{ disk_warnings + [item] }}"
|
||||
loop: "{{ disk_usage_percent.stdout_lines }}"
|
||||
when:
|
||||
- item.split()[1] | regex_replace('%', '') | int >= warning_threshold | int
|
||||
- item.split()[1] | regex_replace('%', '') | int < alert_threshold | int
|
||||
|
||||
- name: Create comprehensive report
|
||||
copy:
|
||||
content: |
|
||||
📊 DISK USAGE REPORT - {{ inventory_hostname }}
|
||||
=============================================
|
||||
|
||||
📅 Generated: {{ ansible_date_time.iso8601 }}
|
||||
🖥️ Host: {{ inventory_hostname }}
|
||||
💿 OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
|
||||
⚠️ Alert Threshold: {{ alert_threshold }}%
|
||||
⚡ Warning Threshold: {{ warning_threshold }}%
|
||||
|
||||
🚨 CRITICAL ALERTS (>={{ alert_threshold }}%):
|
||||
{% if disk_alerts | length > 0 %}
|
||||
{% for alert in disk_alerts %}
|
||||
❌ {{ alert }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
✅ No critical disk usage alerts
|
||||
{% endif %}
|
||||
|
||||
⚠️ WARNINGS (>={{ warning_threshold }}%):
|
||||
{% if disk_warnings | length > 0 %}
|
||||
{% for warning in disk_warnings %}
|
||||
🟡 {{ warning }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
✅ No disk usage warnings
|
||||
{% endif %}
|
||||
|
||||
💾 FILESYSTEM USAGE:
|
||||
{{ disk_usage_basic.stdout }}
|
||||
|
||||
📁 INODE USAGE:
|
||||
{{ inode_usage.stdout }}
|
||||
|
||||
🧹 TEMPORARY FILES:
|
||||
{{ temp_files_analysis.stdout }}
|
||||
|
||||
{% if include_docker_analysis and docker_storage_analysis.stdout is defined %}
|
||||
🐳 DOCKER STORAGE:
|
||||
{{ docker_storage_analysis.stdout }}
|
||||
{% endif %}
|
||||
|
||||
{% if detailed_analysis %}
|
||||
{% if largest_directories.stdout is defined %}
|
||||
📂 LARGEST DIRECTORIES:
|
||||
{{ largest_directories.stdout }}
|
||||
{% endif %}
|
||||
|
||||
{% if log_analysis.stdout is defined %}
|
||||
📝 LOG FILES:
|
||||
{{ log_analysis.stdout }}
|
||||
{% endif %}
|
||||
|
||||
{% if large_files.stdout is defined %}
|
||||
📦 LARGE FILES:
|
||||
{{ large_files.stdout }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
💡 RECOMMENDATIONS:
|
||||
{% if disk_alerts | length > 0 %}
|
||||
- 🚨 IMMEDIATE ACTION REQUIRED: Clean up filesystems above {{ alert_threshold }}%
|
||||
{% endif %}
|
||||
{% if disk_warnings | length > 0 %}
|
||||
- ⚠️ Monitor filesystems above {{ warning_threshold }}%
|
||||
{% endif %}
|
||||
- 🧹 Run cleanup playbook: ansible-playbook playbooks/cleanup_old_backups.yml
|
||||
- 🐳 Prune Docker: ansible-playbook playbooks/prune_containers.yml
|
||||
- 📝 Rotate logs: ansible-playbook playbooks/log_rotation.yml
|
||||
- 🗑️ Clean temp files: find /tmp -type f -mtime +7 -delete
|
||||
|
||||
📊 SUMMARY:
|
||||
- Total Filesystems: {{ disk_usage_percent.stdout_lines | length }}
|
||||
- Critical Alerts: {{ disk_alerts | length }}
|
||||
- Warnings: {{ disk_warnings | length }}
|
||||
- Docker Analysis: {{ 'Included' if include_docker_analysis else 'Skipped' }}
|
||||
- Detailed Analysis: {{ 'Included' if detailed_analysis else 'Skipped' }}
|
||||
|
||||
dest: "{{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.txt"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create JSON report for automation
|
||||
copy:
|
||||
content: |
|
||||
{
|
||||
"timestamp": "{{ ansible_date_time.iso8601 }}",
|
||||
"hostname": "{{ inventory_hostname }}",
|
||||
"thresholds": {
|
||||
"alert": {{ alert_threshold }},
|
||||
"warning": {{ warning_threshold }}
|
||||
},
|
||||
"alerts": {{ disk_alerts | to_json }},
|
||||
"warnings": {{ disk_warnings | to_json }},
|
||||
"filesystems": {{ disk_usage_percent.stdout_lines | to_json }},
|
||||
"summary": {
|
||||
"total_filesystems": {{ disk_usage_percent.stdout_lines | length }},
|
||||
"critical_count": {{ disk_alerts | length }},
|
||||
"warning_count": {{ disk_warnings | length }},
|
||||
"status": "{% if disk_alerts | length > 0 %}CRITICAL{% elif disk_warnings | length > 0 %}WARNING{% else %}OK{% endif %}"
|
||||
}
|
||||
}
|
||||
dest: "{{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.json"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Display summary
|
||||
debug:
|
||||
msg: |
|
||||
|
||||
📊 DISK USAGE REPORT COMPLETE - {{ inventory_hostname }}
|
||||
================================================
|
||||
|
||||
{% if disk_alerts | length > 0 %}
|
||||
🚨 CRITICAL ALERTS: {{ disk_alerts | length }}
|
||||
{% for alert in disk_alerts %}
|
||||
❌ {{ alert }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if disk_warnings | length > 0 %}
|
||||
⚠️ WARNINGS: {{ disk_warnings | length }}
|
||||
{% for warning in disk_warnings %}
|
||||
🟡 {{ warning }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if disk_alerts | length == 0 and disk_warnings | length == 0 %}
|
||||
✅ All filesystems within normal usage levels
|
||||
{% endif %}
|
||||
|
||||
📄 Reports saved to:
|
||||
- {{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.txt
|
||||
- {{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.json
|
||||
|
||||
🔍 Next Steps:
|
||||
{% if disk_alerts | length > 0 %}
|
||||
- Run cleanup: ansible-playbook playbooks/cleanup_old_backups.yml
|
||||
- Prune Docker: ansible-playbook playbooks/prune_containers.yml
|
||||
{% endif %}
|
||||
- Schedule regular monitoring via cron
|
||||
|
||||
================================================
|
||||
|
||||
- name: Send alert if critical usage detected
|
||||
debug:
|
||||
msg: |
|
||||
🚨 CRITICAL DISK USAGE ALERT 🚨
|
||||
Host: {{ inventory_hostname }}
|
||||
Critical filesystems: {{ disk_alerts | length }}
|
||||
Immediate action required!
|
||||
when:
|
||||
- disk_alerts | length > 0
|
||||
- send_alerts | default(false) | bool
|
||||
Reference in New Issue
Block a user