Files
Gitea Mirror Bot e7652c8dab
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m3s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-04-20 01:32:01 UTC
2026-04-20 01:32:01 +00:00

250 lines
10 KiB
YAML

---
# Container Logs Collection Playbook
# Collect logs from multiple containers for troubleshooting
# Usage: ansible-playbook playbooks/container_logs.yml -e "service_name=plex"
# Usage: ansible-playbook playbooks/container_logs.yml -e "service_pattern=immich"
# Usage: ansible-playbook playbooks/container_logs.yml -e "collect_all=true"
- name: Collect Container Logs
hosts: "{{ host_target | default('all') }}"
gather_facts: yes
vars:
target_service_name: "{{ service_name | default('') }}"
target_service_pattern: "{{ service_pattern | default('') }}"
target_collect_all: "{{ collect_all | default(false) }}"
target_log_lines: "{{ log_lines | default(100) }}"
target_log_since: "{{ log_since | default('1h') }}"
output_dir: "/tmp/container_logs/{{ ansible_date_time.date }}"
target_include_timestamps: "{{ include_timestamps | default(true) }}"
target_follow_logs: "{{ follow_logs | default(false) }}"
tasks:
- name: Validate input parameters
fail:
msg: "Specify either service_name, service_pattern, or collect_all=true"
when:
- target_service_name == ""
- target_service_pattern == ""
- not (target_collect_all | bool)
- name: Check if Docker is running
systemd:
name: docker
register: docker_status
failed_when: docker_status.status.ActiveState != "active"
- name: Create local log directory
file:
path: "{{ output_dir }}/{{ inventory_hostname }}"
state: directory
mode: '0755'
delegate_to: localhost
- name: Create remote log directory
file:
path: "{{ output_dir }}/{{ inventory_hostname }}"
state: directory
mode: '0755'
- name: Get specific service container
shell: 'docker ps -a --filter "name={{ target_service_name }}" --format "{%raw%}{{.Names}}{%endraw%}"'
register: specific_container
when: target_service_name != ""
changed_when: false
- name: Get containers matching pattern
shell: 'docker ps -a --filter "name={{ target_service_pattern }}" --format "{%raw%}{{.Names}}{%endraw%}"'
register: pattern_containers
when: target_service_pattern != ""
changed_when: false
- name: Get all containers
shell: 'docker ps -a --format "{%raw%}{{.Names}}{%endraw%}"'
register: all_containers
when: target_collect_all | bool
changed_when: false
- name: Combine container lists
set_fact:
target_containers: >-
{{
(specific_container.stdout_lines | default([])) +
(pattern_containers.stdout_lines | default([])) +
(all_containers.stdout_lines | default([]) if target_collect_all | bool else [])
}}
- name: Display target containers
debug:
msg: |
📦 CONTAINER LOG COLLECTION
===========================
🖥️ Host: {{ inventory_hostname }}
📋 Target Containers: {{ target_containers | length }}
{% for container in target_containers %}
- {{ container }}
{% endfor %}
📏 Log Lines: {{ target_log_lines }}
⏰ Since: {{ target_log_since }}
- name: Fail if no containers found
fail:
msg: "No containers found matching the criteria"
when: target_containers | length == 0
- name: Get container information
shell: |
docker inspect {{ item }} --format='
Container: {{ item }}
Image: {%raw%}{{.Config.Image}}{%endraw%}
Status: {%raw%}{{.State.Status}}{%endraw%}
Started: {%raw%}{{.State.StartedAt}}{%endraw%}
Restart Count: {%raw%}{{.RestartCount}}{%endraw%}
Health: {%raw%}{{if .State.Health}}{{.State.Health.Status}}{{else}}No health check{{end}}{%endraw%}
'
register: container_info
loop: "{{ target_containers }}"
changed_when: false
- name: Collect container logs
shell: |
echo "=== CONTAINER INFO ===" > {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
docker inspect {{ item }} --format='
Container: {{ item }}
Image: {%raw%}{{.Config.Image}}{%endraw%}
Status: {%raw%}{{.State.Status}}{%endraw%}
Started: {%raw%}{{.State.StartedAt}}{%endraw%}
Restart Count: {%raw%}{{.RestartCount}}{%endraw%}
Health: {%raw%}{{if .State.Health}}{{.State.Health.Status}}{{else}}No health check{{end}}{%endraw%}
' >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
echo "" >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
echo "=== CONTAINER LOGS ===" >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
{% if target_include_timestamps | bool %}
docker logs {{ item }} --since={{ target_log_since }} --tail={{ target_log_lines }} -t >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log 2>&1
{% else %}
docker logs {{ item }} --since={{ target_log_since }} --tail={{ target_log_lines }} >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log 2>&1
{% endif %}
loop: "{{ target_containers }}"
ignore_errors: yes
- name: Get container resource usage
shell: 'docker stats {{ target_containers | join(" ") }} --no-stream --format "table {%raw%}{{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}{%endraw%}"'
register: container_stats
when: target_containers | length > 0
ignore_errors: yes
- name: Save container stats
copy:
content: |
Container Resource Usage - {{ ansible_date_time.iso8601 }}
Host: {{ inventory_hostname }}
{{ container_stats.stdout }}
dest: "{{ output_dir }}/{{ inventory_hostname }}/container_stats.txt"
when: container_stats.stdout is defined
- name: Check for error patterns in logs
shell: |
echo "=== ERROR ANALYSIS ===" > {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
echo "Host: {{ inventory_hostname }}" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
echo "Timestamp: {{ ansible_date_time.iso8601 }}" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
echo "" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
for container in {{ target_containers | join(' ') }}; do
echo "=== $container ===" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
# Count error patterns
error_count=$(docker logs $container --since={{ target_log_since }} 2>&1 | grep -i -E "(error|exception|failed|fatal|panic)" | wc -l)
warn_count=$(docker logs $container --since={{ target_log_since }} 2>&1 | grep -i -E "(warn|warning)" | wc -l)
echo "Errors: $error_count" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
echo "Warnings: $warn_count" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
# Show recent errors
if [ $error_count -gt 0 ]; then
echo "Recent Errors:" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
docker logs $container --since={{ target_log_since }} 2>&1 | grep -i -E "(error|exception|failed|fatal|panic)" | tail -5 >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
fi
echo "" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
done
when: target_containers | length > 0
ignore_errors: yes
- name: Create summary report
copy:
content: |
📊 CONTAINER LOG COLLECTION SUMMARY
===================================
🖥️ Host: {{ inventory_hostname }}
📅 Collection Time: {{ ansible_date_time.iso8601 }}
📦 Containers Processed: {{ target_containers | length }}
📏 Log Lines per Container: {{ target_log_lines }}
⏰ Time Range: {{ target_log_since }}
📋 CONTAINERS:
{% for container in target_containers %}
- {{ container }}
{% endfor %}
📁 LOG FILES LOCATION:
{{ output_dir }}/{{ inventory_hostname }}/
📄 FILES CREATED:
{% for container in target_containers %}
- {{ container }}.log
{% endfor %}
- container_stats.txt
- error_summary.txt
- collection_summary.txt (this file)
🔍 QUICK ANALYSIS:
Use these commands to analyze the logs:
# View error summary
cat {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
# Search for specific patterns
grep -i "error" {{ output_dir }}/{{ inventory_hostname }}/*.log
# View container stats
cat {{ output_dir }}/{{ inventory_hostname }}/container_stats.txt
# Follow live logs (if needed)
{% for container in target_containers[:3] %}
docker logs -f {{ container }}
{% endfor %}
dest: "{{ output_dir }}/{{ inventory_hostname }}/collection_summary.txt"
- name: Display collection results
debug:
msg: |
✅ LOG COLLECTION COMPLETE
==========================
🖥️ Host: {{ inventory_hostname }}
📦 Containers: {{ target_containers | length }}
📁 Location: {{ output_dir }}/{{ inventory_hostname }}/
📄 Files Created:
{% for container in target_containers %}
- {{ container }}.log
{% endfor %}
- container_stats.txt
- error_summary.txt
- collection_summary.txt
🔍 Quick Commands:
# View errors: cat {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
# View stats: cat {{ output_dir }}/{{ inventory_hostname }}/container_stats.txt
==========================
- name: Archive logs (optional)
archive:
path: "{{ output_dir }}/{{ inventory_hostname }}"
dest: "{{ output_dir }}/{{ inventory_hostname }}_logs_{{ ansible_date_time.epoch }}.tar.gz"
remove: no
when: archive_logs | default(false) | bool
delegate_to: localhost