21

I'm currently developing an Ansible script to build and deploy a Java project.

So, I can set the log_path like below

log_path=/var/log/ansible.log

But, it is hard to look up build history.

Is it possible to append datetime to log file name?

For example,

ansible.20150326145515.log
U880D
  • 8,601
  • 6
  • 24
  • 40
Ickhyun Kwon
  • 1,675
  • 4
  • 13
  • 17

7 Answers7

14

I don't believe there is a built-in way to generate the date on the fly like that but one option you have is to use a lookup which can shell out to date. Example:

log_path="/var/log/ansible.{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}.log"
jarv
  • 5,338
  • 24
  • 26
  • 5
    Does this actually work for you? For me, running 2.3.2.0, the quotes are escaped by the interpreter, resulting in the `log_path` being invalid; never even attempting to execute the lookup. – Darrel Holt Oct 09 '17 at 21:28
  • 2
    Sorry, it creates files named `ansible-log.{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}.log` instead of doing something useful. Putting quotes around the whole path makes ansible append `pwd` to it. – styrofoam fly Jul 19 '18 at 19:40
  • This doesnt work for me:ansible 2.7.8 config file = /root/scripts/ansible/affinities/ansible.cfg configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/lib/python3.5/dist-packages/ansible executable location = /usr/local/bin/ansible python version = 3.5.2 (default, Nov 12 2018, 13:43:14) [GCC 5.4.0 20160609] – user3746195 Apr 01 '19 at 17:23
  • 4
    How does this have 17 upvotes? It does not work. Just tried it on Ansible 2.9.7. – EM0 May 06 '20 at 08:34
  • @EM0 have you find any solution? – Rahul kuchhadia Feb 09 '21 at 15:32
  • According to https://docs.ansible.com/ansible/latest/user_guide/playbooks_lookups.html, this syntax only works with Ansible >= 3.5. – wmbolle Feb 24 '21 at 08:02
10

Here is an option using ANSIBLE_LOG_PATH environment variable thanks to Bash shell alias:

alias ansible="ANSIBLE_LOG_PATH=ansible-\`date +%Y%m%d%H%M%S\`.log ansible"

Feel free to use an absolute path if you prefer.

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
  • +1 Didn't know about the env vars. This seems to be the way to set the log path when running from a *sh script using `export ANSIBLE_LOG_PATH=...`. – kub1x Mar 09 '18 at 13:26
5

I found it.

just add task to copy(or mv command) log locally

- name: Copy ansible.log
  connection: local
  command: mv ./logs/ansible.log ./logs/ansible.{{ lookup('pipe', 'date %Y%M%d%H%M%S') }}.log
  run_once: true

thanks to @jarv

Ickhyun Kwon
  • 1,675
  • 4
  • 13
  • 17
  • 1
    Be careful that your date format is missing the `+` sign from @jarv's answer. – Matt Sep 01 '17 at 15:37
  • I tested that this works. I started by deleting the existing log; making a playbook to: execute a debug task to begin writing to the log, execute the command task to move/rename the log, execute another task to see if Ansible still correctly writes to the log. The result is a success – the log was created by ansible, written to, renamed, and written to again after moving/renaming. – Darrel Holt Oct 10 '17 at 17:30
2

How about this:

- shell: date +%Y%m%d%H%M%S
  register: timestamp

- debug: msg="foo.{{timestamp.stdout}}.log"

Output:

TASK [command] *****************************************************************
changed: [blabla.example.com]

TASK [debug] *******************************************************************
ok: [blabla.example.com] => {
    "msg": "foo.20160922233847.log"
}
Ali Ok
  • 716
  • 1
  • 8
  • 23
  • I think you were down voted because he needs to change the log file dynamically – which involves modifying the log_path – not just use the debug module to show that you can do the `date` command with Ansible. – Darrel Holt Oct 09 '17 at 21:56
2

I have faced a similar problem while trying to set dynamic log paths for various playbooks.

A simple solution seems to be to pass the log filename dynamically to the ANSIBLE_LOG_PATH environment variable. Checkout -> https://docs.ansible.com/ansible/latest/reference_appendices/config.html

In this particular case just export the environment variable when running the intended playbook on your terminal:

export ANSIBLE_LOG_PATH=ansible.`date +%s`.log; ansible-playbook test.yml

Else if the intended filename cannot be generated by the terminal, you can always use a runner playbook which runs the intended playbook from the within:

    ---
- hosts:
    - localhost
  gather_facts: false
  ignore_errors: yes
  tasks:
    - name: set dynamic variables
      set_fact:
        task_name: dynamic_log_test
        log_dir: /path/to/log_directory/
    - name: Change the working directory and run the ansible-playbook as shell command
      shell: "export ANSIBLE_LOG_PATH={{ log_dir }}log_{{ task_name|lower }}.txt; ansible-playbook test.yml"
      register: shell_result

This should log the result of test.yml to /path/to/log_directory/log_dynamic_log_test.txt

Hope you find this helpful!

1

According to the nice folks at the #ansible freenode IRC, this can be accomplished with a custom callback plugin.

I haven't done it yet because I can't install the Ansible Python library on this machine. Specifically, Windows 7 can't have directory names > 260 chars in length, and pip tries to make lengthy temporary paths. But if someone gets around to it, please post it here.

Darrel Holt
  • 870
  • 1
  • 15
  • 39
1

Small improvement on @ickhyun-kwon answer:

- name: "common/_ansible_log_path.yml: rename ansible.log"
  connection: local
  shell: |
    mkdir -vp {{ inventory_dir }}/logs/{{ svn_deploy.release }}/ ;
    mv    -vf {{ inventory_dir }}/logs/ansible.log {{ inventory_dir }}/logs/{{ svn_deploy.release }}/ansible.{{ svn_deploy.release }}.{{ lookup('pipe', 'date +%Y-%m-%d-%H%M') }}.log      args:
    executable: /bin/bash
    chdir: "{{ inventory_dir }}"
  run_once: True
  ignore_errors: True

This has separate log directories per svn release, ensures the log directory actually exists before the mv command.

Ansible interprets ./ as the current playbook directory, which may or may not be the root of your ansible repository, whereas mine live in ./playbooks/$project/$role.yml. For me {{ inventory_dir }}/logs/ happens to correspond to the ~/ansible/log/ directory, though alternative layout configurations do not guarantee this.

I am unsure the correct way to formally extract the absolute ansible.cfg::log_path variable

Also the date command for month is +%m and not %M which is Minute

James McGuigan
  • 7,542
  • 4
  • 26
  • 29