2

I tried to start JBoss service via Ansible and use wai_for module to wait till the JBoss started. However, the JBoss service started, however, the wait_for still progressing until there is time out then hit error. Below is my code

- name: Get the contents of the last line from log
  command: "tail -n 1 /home/nityo/application.log"
  register: tail_output

- name: Create a variable with a meaningful name, just for clarity
  set_fact:
    last_line_of_the_log_file: "{{ tail_output.stdout }}"

- name: JBoss service starting
  service:
    name: "jboss.service"
    state: started
  become: yes
  become_user: root

- name:Wait for server started
  wait_for:
    path: "//home/nityo/application.log"
    search_regex: "{{ last_line_of_the_log_file }}\r(.*\r)*.*JBoss EAP.*started.*"
    timeout: 600

Besides that can we combine all thsi into 1 task rrather than having multiple task

Sample output log

2020-10-11 01:13:42,009 INFO  [org.jboss.as] JBoss EAP 7.2 (WildFly Core) running in 100281ms - service to be running
2020-10-11 01:13:42,005 INFO  [org.jboss.as] processing data
2020-10-11 01:13:43,009 INFO  [org.jboss.as] JBoss EAP 7.2 (WildFly Core) stopped in 100281ms - service to be stopped
-
-
-
-
-
-
-
2020-10-11 01:13:48,009 INFO  [org.jboss.as] JBoss EAP 7.2 (WildFly Core) started in 100281ms - service to be started
salelne
  • 35
  • 5
  • Can you add an example `last_line_of_the_log_file`, does that line change? If it does, then chances of matching that in `wait_for` are remote. – seshadri_c Oct 11 '20 at 11:23
  • Yea. The first task will get the last line. After that, server restarts. when server restart there are output being generasted roughtly takes 5 minutes but it depends. can be longer sometimes. So basically the output keep on changing – salelne Oct 11 '20 at 12:11

2 Answers2

1

It will never match in the last task, because you are searching for the last logfile line plus some extra stuff. You are using a variable in your regex, which contains a string that never matches if you add some other staff at the end of it.

So skip the first and second task and change your search_regex Parameter of the last task.

You could use the ansible fact ansible_date_time (described in Ansible date variable) and use parts of date, time and/or epoch-seconds to build your regex via set_fact module. So your regex will match the logfile line with a timestamp not older then 10 minutes.

With date you could create a timestamp for a specific hour. The playbook could look like this:

---
- name: check logfile last 10 Minutes
  hosts:
  - localhost
  gather_facts: no
  tasks:
  - name: set now timestring
    command: 'date +"%Y-%m-%d %H"'
    register: date_now
  - name: set_now
    set_fact:
      now: "{{ date_now.stdout }}"
  - name: set 10 minutes ago timestring
    command: 'date +"%Y-%m-%d %H" -d "10 minutes ago"'
    register: date_10min_ago
  - name: set 10min_ago
    set_fact:
      ten_min_ago: "{{ date_10min_ago.stdout }}"
  - name: debug
    debug:
      msg: "({{ now }}|{{ ten_min_ago }}).*JBoss EAP.*started.*"
  - name: Wait for server started
    wait_for:
      path: "//home/nityo/application.log"
      search_regex: "({{ now }}|{{ ten_min_ago }}).*JBoss EAP.*started"
      timeout: 600

The Timestamps are totally different if the daliy limit is reached. In the middle of an hour, it seems superfluous. Debug-Output how the regex looks like this:

TASK [debug] **********************
ok: [localhost] => {
    "msg": "(2020-10-12 08|2020-10-12 08).*JBoss EAP.*started.*"
}
Oliver Gaida
  • 1,722
  • 7
  • 14
  • then how i can differentiate. as sometimes the server started twice a day. then how it can know it needs to look for the latest value. That the reason i come out to check last line then after that to restart the server and after that if matched that pattern then to stop as it means jboss server already started – salelne Oct 11 '20 at 12:13
  • you have some sample. i am not able to visualize what can be done – salelne Oct 11 '20 at 15:38
1

What you are storing in last_line_of_the_log_file variable might not be getting matched at the default interval in which wait_for module checks by the time it reaches this task.

Checking service status by parsing a log file can be tricky. However I think the cleanest way will be to match the pattern JBoss EAP.*started.* in the log file. However for this to work reliably, it would be better to start with an empty log file before starting the service.

# Backup the log file with date/time stamp
- shell: cat /home/nityo/application.log >> /home/nityo/application-$(date %b-%d-%H-%M).log

# Empty the file contents before starting service
- command: truncate -s 0 /home/nityo/application.log

- wait_for:
    path: "/home/nityo/application.log"
    search_regex: "JBoss EAP.*started.*"
    timeout: 600

Parsing log files can be hit-or-miss if the logs generate differently in a given span of time. You can tweak the time, retries, and search pattern to get more consistent results.

Update:

It would be good to wait for some time to roll beyond the default lines (10) fetched by tail command, to avoid matching a previous startup. Then use egrep:

# Pause and wait for logs to roll beyond 10 lines fetched by 'tail'
- pause:
    seconds: 30

- shell: tail /home/nityo/application.log | grep -e "JBoss EAP.*started"
  register: file_tail
  until: file_tail is success
  # use appropriate values as per the rate of logging
  retries: 30
  delay: 20
seshadri_c
  • 6,906
  • 2
  • 10
  • 24
  • 1
    i think i could not do the empty the file suggestions. I will give a try with the next solution you have provided – salelne Oct 11 '20 at 15:41
  • If file contents of the log file is a concern, it can be backed up and then emptied. Good luck with the other option! – seshadri_c Oct 11 '20 at 16:15
  • i tried however, it stopped before the word started in JBoss EAP appears – salelne Oct 11 '20 at 16:25
  • within few seconds it stop. it didnt wait for it to execute fully. i am suspecting because we didnt give time input like from current time it should get the value from tail – salelne Oct 11 '20 at 16:34
  • There could be any `started` word in the log file. Can you try `until: "'started' in file_tail.stdout`? – seshadri_c Oct 11 '20 at 16:51
  • yea. there are more than 1 started in the log file however, JBoss EAP 7.2 * started will be only once. and sometimes got few words appended after the started. as i observed, even through terminal i did tail grep jboss, it was still showing the previous value of started – salelne Oct 12 '20 at 00:57
  • 1
    your earlier answer is good, however, there should timestamp included to check after that time stamp shpould grep the words. I also figuring it out. saw soemthing egrep. checking on it – salelne Oct 12 '20 at 01:02
  • Adding logic to compare time stamps can make this Ansible playbook a little complex though. Good luck with that. Just `egrep` after waiting for some time might help (updated). – seshadri_c Oct 12 '20 at 01:39
  • Thanks. AS I observed, tail /home/nityo/application.log | grep "JBoss EAP", previously got data after i stop and then start and then stop and when starting time before the word "JBoss EAP" came, i did manually check in termianl the data was already there. Now i checked the data not there. wondering what happened – salelne Oct 12 '20 at 01:59
  • can help to add this in ur answer. cat /home/nityo/application.log | grep -e 'JBoss EAP.*started.*' | awk -F'[:, ]' '$2 >= 10 && $3 >= 41 && $4 >=42 && $5 >= 526 { print }'. before that need set the current execution time and date and then use it to compare. let me know if this is wrong approach – salelne Oct 12 '20 at 03:07
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222881/discussion-between-seshadri-c-and-salelne). – seshadri_c Oct 12 '20 at 03:41