ansible-role-collect-logs/roles/collect_logs/tasks/collect.yml

210 lines
6.6 KiB
YAML

---
- become: true
ignore_errors: true
block:
- name: Ensure required rpms for logging are installed
package:
state: present
name: "{{ artcl_collect_pkg_list }}"
- name: Prepare directory with extra logs
file:
dest: /var/log/extra
state: directory
mode: 0755
- name: Create rsync filter file
template:
src: "odl_extra_logs.j2"
dest: "/tmp/odl_extra_logs.sh"
mode: 0644
- name: Determine commands to run
run_once: true
vars:
combined_cmds: "{{ artcl_commands | combine(artcl_commands_extras, recursive=True) }}"
# combines default dictionary with user defined one
# keeps only commands from groups mentioned in collect_log_types
flatten_nested_dict:
data: "{{ combined_cmds | dict2items|selectattr('key', 'in', collect_log_types) | list | items2dict }}"
register: artcl_commands_flatten
- name: install setools
ansible.builtin.package:
name:
- setools
- setroubleshoot
state: present
- name: install custom consolidation script
ansible.builtin.copy:
dest: /usr/local/bin/consolidate-avc.pl
src: consolidate-avc.pl
mode: 0555
- name: Run artcl_commands
# noqa 305
# noqa 102 :: No Jinja2 in when
vars:
capture_file: "{{ item.capture_file | default( item.name + '.txt') }}"
shell:
# redirection of output to log file, see https://ops.tips/gists/redirect-all-outputs-of-a-bash-script-to-a-file/
cmd: |
{% if not item.capture_disable | default(False) %}
exec >{% if not capture_file.startswith('/') %}/var/log/extra/{% endif %}{{ capture_file }} 2>&1
{% endif %}
{# do not put anything after the command #}
{{ item.cmd }}
warn: false
args:
chdir: /var/log/extra
executable: /bin/bash
changed_when: false
when: item.when | default(true)
loop: "{{ artcl_commands_flatten.data }}"
loop_control:
label: "{{ item.name }}"
# Change the collect_log_types if you don't want to collect
# some specific logs
- import_tasks: collect/container.yml
when: "'container' in collect_log_types"
- import_tasks: collect/system.yml
when: "'system' in collect_log_types"
- import_tasks: collect/network.yml
when: "'network' in collect_log_types"
- import_tasks: collect/monitoring.yml
when: "'monitoring' in collect_log_types"
- name: Set default collect list
set_fact:
collect_list: "{{ artcl_collect_list }} + {{ artcl_collect_list_append|default([]) }}"
- name: Override collect list
set_fact:
collect_list: "{{ artcl_collect_override[inventory_hostname] }}"
when:
- artcl_collect_override is defined
- artcl_collect_override[inventory_hostname] is defined
- name: Set default exclude list
set_fact:
artcl_exclude_list: "{{ artcl_exclude_list|default([]) }} + {{ artcl_exclude_list_append|default([]) }}"
- name: Create temp directory before gathering logs
file:
dest: "/tmp/{{ inventory_hostname }}"
state: directory
mode: 0755
- name: Create rsync filter file
template:
src: "rsync-filter.j2"
dest: "/tmp/{{ inventory_hostname }}-rsync-filter"
mode: 0644
when: artcl_rsync_collect_list|bool
# This task needs to be finished before generating find list of files
# to collect (Create find list file task) otherwise not all the container
# log files may be found and thus not collected later
- name: Wait for container logs collection if not finished yet
become: true
async_status:
jid: "{{ container_collection.ansible_job_id }}"
register: container_collection_result
until: container_collection_result.finished
delay: 10
retries: "{{ ((artcl_container_collect_timeout|int) / 10)|int }}"
when: "'container' in collect_log_types"
- name: Create find list file
become: true
shell: >
find {{ collect_list|join(' ') }}
-maxdepth {{ artcl_find_maxdepth }}
-type f \
-size -{{ artcl_find_max_size }}M
{% if artcl_exclude_list is defined %}
-not -path {{ artcl_exclude_list|map('quote')|join(' -not -path ') }}
{% endif %}
-print0 > /tmp/{{ inventory_hostname }}-rsync-list
failed_when: false
when: not artcl_rsync_collect_list|bool
- name: Gather the logs to /tmp
become: true
shell: >
set -o pipefail &&
rsync --quiet --recursive --copy-links --prune-empty-dirs --ignore-errors
{% if artcl_rsync_collect_list|bool %}
--filter '. /tmp/{{ inventory_hostname }}-rsync-filter'
{% else %}
--from0 --files-from=/tmp/{{ inventory_hostname }}-rsync-list
{% endif %}
/ /tmp/{{ inventory_hostname }};
find /tmp/{{ inventory_hostname }} -type d -print0 | xargs -0 chmod 755;
find /tmp/{{ inventory_hostname }} -type f -print0 | xargs -0 chmod 644;
find /tmp/{{ inventory_hostname }} -not -type f -not -type d -delete;
{# chown can fail with: chown: invalid spec: '0:' #}
chown -R {{ ansible_user | default(ansible_effective_user_id) }}: /tmp/{{ inventory_hostname }} || true;
args:
executable: /bin/bash
changed_when: true
# See README section 'Sanitizing Log Strings'
- name: Sanitize logs to remove sensitive details
include_tasks: sanitize_log_strings.yaml
loop: "{{ sanitize_lines }}"
loop_control:
loop_var: outer_item
when: sanitize_lines is defined and sanitize_lines|length
# it makes sense to compress the logs prior
# to sending them over the wire to the
# node where they are collected by infra.
# Regardless of the file size.
- name: Compress the collected files if configured
when: artcl_gzip | bool
shell: gzip -r ./{{ inventory_hostname }}
args:
chdir: /tmp
warn: false
changed_when: true
tags:
- skip_ansible_lint
- name: Create tar archive of logs for faster copying # noqa: command-instead-of-module
shell:
cmd: tar cf {{ inventory_hostname }}.tar {{ inventory_hostname }};
chdir: /tmp
changed_when: true
- name: Fetch log archive (tar)
fetch:
src: "/tmp/{{ inventory_hostname }}.tar"
dest: "{{ artcl_collect_dir }}/{{ inventory_hostname }}.tar"
flat: true
validate_checksum: false
- name: Delete temporary log directory after collection
file:
path: "/tmp/{{ inventory_hostname }}"
state: absent
ignore_errors: true # noqa ignore-errors
- name: Extract the logs archive
unarchive:
src: "{{ artcl_collect_dir }}/{{ inventory_hostname }}.tar"
dest: "{{ artcl_collect_dir }}"
remote_src: true
delegate_to: localhost
- name: Remove logs archive
file:
path: "{{ artcl_collect_dir }}/{{ inventory_hostname }}.tar"
state: absent
delegate_to: localhost