How to check the size of a file list

Viewed 973

With Ansible, I need to check if files in directory are bigger than 50M. I do a set_fact with result of ls and then I loop to stat all files. This works, but I am not able to parse the result to create a fail condition when files are bigger than 50M.

I do this :

  - shell: ls -1 "{{ logs_directory }}"*.log  
    register: list_logs
  - set_fact:
      list_logs: "{{ list_logs.stdout_lines }}"
  - debug:
      msg: "{{ list_logs}}"
  
  - name: Get size
    stat:
      path: "{{ item }}"
    with_items: "{{ list_logs }}"
    register: size_log

  - name: debug
    fail:
       msg: "Problem with log size > 50M"
    when: 'size_log.stat.size / 1024 / 1024 | int > 50'

It works if I have only 1 file, but with multiple servers and multiple files, it doesn't work... How to parse the size_log_result?

Here an example of output size_log :

ok: [192.168.1.2] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                        "path": "/var/logs/admin.log"
                    }
                },
                "item": "/var/logs/admin.log",
                "stat": {
                      "size": 21711,
                }
            },
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                          "path": "/var/logs/database.log"
                    }
                },
                "item": "/var/logs/database.log",
                "stat": {
                    "size": 11162,
                }          
            }
        ]
    }
}
ok: [192.168.1.5] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                             "path": "/var/logs/database.log"
                    }
                },
                "item": "/var/logs/database.log",
                "stat": {
                    "size": 128453958,
                }
            }
        ]
    }
}
1 Answers

It looks to me like you are reinventing the wheel here, when the find module seems to answer you use case perfectly already.

Given:

- hosts: localhost
  gather_facts: no

  tasks:
    ####
    ## You do not need this task, it is just to create a file
    ## big enough for demonstration purpose
    ####
    - community.general.filesize:
        path: /var/log/heavy.log
        size: 51m

    - find:
        paths: /var/log
        patterns: '*.log'
        size: 51m
      register: _logs

    - fail:
        msg: >- 
          Due to file(s): {{ 
            _logs.files | map(attribute='path') | join(', ') 
          }}
      when: _logs.files | length > 0

This will yield:

TASK [community.general.filesize] *********************************
ok: [localhost]

TASK [find] *******************************************************
ok: [localhost]

TASK [fail] *******************************************************
fatal: [localhost]: FAILED! => changed=false 
  msg: 'Due to file(s): /var/log/heavy.log'
Related