From 26db5b3b24d65edf1a2b1671c2b28471d260458a Mon Sep 17 00:00:00 2001 From: Tristan Cacqueray Date: Tue, 24 Oct 2023 20:22:09 +0000 Subject: [PATCH] Introduce LogJuicer roles This change adds new roles to run logjuicer in zuul jobs: https://github.com/logjuicer/logjuicer Change-Id: I02824a18285a16c8f0be6bb96b5404aa0d601c16 --- doc/source/logjuicer-roles.rst | 18 +++++++++++ doc/source/roles.rst | 1 + roles/report-logjuicer/README.rst | 25 +++++++++++++++ roles/report-logjuicer/tasks/main.yaml | 8 +++++ roles/run-logjuicer/README.rst | 28 ++++++++++++++++ roles/run-logjuicer/defaults/main.yaml | 9 ++++++ roles/run-logjuicer/tasks/install.yaml | 15 +++++++++ roles/run-logjuicer/tasks/main.yaml | 7 ++++ roles/run-logjuicer/tasks/run.yaml | 44 ++++++++++++++++++++++++++ test-playbooks/run-logjuicer.yaml | 13 ++++++++ zuul-tests.d/logs-jobs.yaml | 9 ++++++ 11 files changed, 177 insertions(+) create mode 100644 doc/source/logjuicer-roles.rst create mode 100644 roles/report-logjuicer/README.rst create mode 100644 roles/report-logjuicer/tasks/main.yaml create mode 100644 roles/run-logjuicer/README.rst create mode 100644 roles/run-logjuicer/defaults/main.yaml create mode 100644 roles/run-logjuicer/tasks/install.yaml create mode 100644 roles/run-logjuicer/tasks/main.yaml create mode 100644 roles/run-logjuicer/tasks/run.yaml create mode 100644 test-playbooks/run-logjuicer.yaml diff --git a/doc/source/logjuicer-roles.rst b/doc/source/logjuicer-roles.rst new file mode 100644 index 000000000..0cf2ba7f2 --- /dev/null +++ b/doc/source/logjuicer-roles.rst @@ -0,0 +1,18 @@ +LogJuicer Roles +=============== + +`LogJuicer `_ extracts anomalies from log files. + +You have two options to integrate LogJuicer in your Zuul job post-run phase: + +#. Deploy the `web-service `_ and use the :zuul:role:`report-logjuicer`. + +#. Use the :zuul:role:`run-logjuicer` to create the report locally: + + * For single-node job, the role can be used in untrusted playbooks. + * For multi-node job, the role must be used on localhost (the executor) between the :zuul:role:`fetch-output` and the log upload. Note that a future version may support merging reports produced on multi nodes through an untrusted playbooks. + +In both case, a new artifact named "LogJuicer Report" will be provided to access the build report. + +.. zuul:autorole:: report-logjuicer +.. zuul:autorole:: run-logjuicer diff --git a/doc/source/roles.rst b/doc/source/roles.rst index 8815c50db..151d92d29 100644 --- a/doc/source/roles.rst +++ b/doc/source/roles.rst @@ -29,3 +29,4 @@ Roles rust-roles system-roles translation-roles + logjuicer-roles diff --git a/roles/report-logjuicer/README.rst b/roles/report-logjuicer/README.rst new file mode 100644 index 000000000..0760fea89 --- /dev/null +++ b/roles/report-logjuicer/README.rst @@ -0,0 +1,25 @@ +Create a LogJuicer report link + +This role emits an artifact to create a report through a LogJuicer web service. +Add the following task to your job post-run phase: + +.. code-block:: yaml + + - when: not zuul_success | bool + include_role: + name: report-logjuicer + vars: + logjuicer_web_url: https://softwarefactory-project.io/logjuicer + zuul_web_url: https://zuul.opendev.org/t/{{ zuul.tenant }} + + +**Role Variables** + +.. zuul:rolevar:: logjuicer_web_url + + The http url of the LogJuicer web service. + +.. zuul:rolevar:: zuul_web_url + + The http url of zuul-web. + For multi-tenant deployment, add ``/t/{{ zuul.tenant }}``. diff --git a/roles/report-logjuicer/tasks/main.yaml b/roles/report-logjuicer/tasks/main.yaml new file mode 100644 index 000000000..aca3b374c --- /dev/null +++ b/roles/report-logjuicer/tasks/main.yaml @@ -0,0 +1,8 @@ +--- +- name: Return LogJuicer report url + zuul_return: + data: + zuul: + artifacts: + - name: "LogJuicer Report" + url: "{{ logjuicer_web_url }}/report/new?target={{ zuul_web_url }}/build/{{ zuul.build }}" diff --git a/roles/run-logjuicer/README.rst b/roles/run-logjuicer/README.rst new file mode 100644 index 000000000..e61e74c94 --- /dev/null +++ b/roles/run-logjuicer/README.rst @@ -0,0 +1,28 @@ +Create a LogJuicer report + +This role runs the `LogJuicer `_ tool +to create a report of the current build. +For single-node jobs, the role can be used on the test instance in the job post-run phase. + +.. code-block:: yaml + + - when: not zuul_success | bool + include_role: + name: run-logjuicer + vars: + zuul_web_url: https://zuul.opendev.org/ + +For multi-node jobs, the role must be used on localhost (the executor) +between the :zuul:role:`fetch-output` and the log upload. + + +**Role Variables** + +.. zuul:rolevar:: zuul_web_url + + The zuul-web URL, to lookup baselines. + +.. zuul:rolevar:: logjuicer_max_run_time + :default: 900 + + Maximum runtime in seconds. diff --git a/roles/run-logjuicer/defaults/main.yaml b/roles/run-logjuicer/defaults/main.yaml new file mode 100644 index 000000000..4474038fa --- /dev/null +++ b/roles/run-logjuicer/defaults/main.yaml @@ -0,0 +1,9 @@ +--- +# Update from https://github.com/logjuicer/logjuicer/releases +logjuicer_version: 0.9.6 + +# Enable logjuicer debug logs +logjuicer_debug: false + +# Maximum runtime in seconds +logjuicer_max_run_time: 900 diff --git a/roles/run-logjuicer/tasks/install.yaml b/roles/run-logjuicer/tasks/install.yaml new file mode 100644 index 000000000..3dd74698e --- /dev/null +++ b/roles/run-logjuicer/tasks/install.yaml @@ -0,0 +1,15 @@ +--- +- name: Install LogJuicer + shell: | + set -o pipefail + mkdir -p ~/.local/bin + curl -L https://github.com/logjuicer/logjuicer/releases/download/{{ logjuicer_version }}/logjuicer-x86_64-linux.tar.bz2 | tar -C ~/.local/ -xjvf - + tags: + # skip using file module to create the directory to keep this role short + - skip_ansible_lint + args: + executable: '/bin/bash' + +- name: Set logjuicer_cmd fact + set_fact: + logjuicer_cmd: "{% if logjuicer_debug %}env LOGJUICER_LOG=debug {% endif %}{{ ansible_env.HOME }}/.local/bin/logjuicer" diff --git a/roles/run-logjuicer/tasks/main.yaml b/roles/run-logjuicer/tasks/main.yaml new file mode 100644 index 000000000..85652c7a7 --- /dev/null +++ b/roles/run-logjuicer/tasks/main.yaml @@ -0,0 +1,7 @@ +--- +- name: Detect anomalies with logjuicer + block: + - name: Install logjuicer + include_tasks: install.yaml + - name: Run logjuicer + include_tasks: run.yaml diff --git a/roles/run-logjuicer/tasks/run.yaml b/roles/run-logjuicer/tasks/run.yaml new file mode 100644 index 000000000..bb2d46103 --- /dev/null +++ b/roles/run-logjuicer/tasks/run.yaml @@ -0,0 +1,44 @@ +--- +- name: Check for multi-node usages + when: ansible_play_hosts_all | length > 1 + fail: + msg: "Run logjuicer from the executor after the fetch-output for multi-node jobs" + +- name: Setup multi-node fact + when: inventory_hostname == "localhost" + set_fact: + _logs_path: "{{ zuul.executor.log_root }}" + +- name: Setup single-node + when: inventory_hostname != "localhost" + block: + - name: Setup fact + set_fact: + _logs_path: "{{ ansible_user_dir }}/zuul-output/logs" + + - name: Copy the console log and inventory for analysis on the test instance + copy: + src: "{{ zuul.executor.log_root }}/{{ zj_item }}" + dest: "{{ _logs_path }}/" + loop_control: + loop_var: zj_item + loop: + - "job-output.txt" + - "zuul-info" + +- name: Analyse the logs + command: > + timeout {{ logjuicer_max_run_time }}s {{ logjuicer_cmd }} + --report {{ _logs_path }}/logjuicer.{% if zuul_log_compress|default(false) %}gz{% else %}bin{% endif %} + zuul-build --api-url {{ zuul_web_url }} {{ _logs_path }}/ + ignore_errors: true + register: _logjuicer_run + +- name: Register the output + when: _logjuicer_run.rc == 0 + zuul_return: + data: + zuul: + artifacts: + - name: "LogJuicer Report" + url: "logjuicer.html" diff --git a/test-playbooks/run-logjuicer.yaml b/test-playbooks/run-logjuicer.yaml new file mode 100644 index 000000000..77435fb8b --- /dev/null +++ b/test-playbooks/run-logjuicer.yaml @@ -0,0 +1,13 @@ +--- +- hosts: all + tasks: + - name: Generate random data + command: "echo {{ log_line }}" + vars: + log_line: "{{ ['eventa occured today', 'eventb happened previously', 'eventc presently failed'] | random }}" + + - name: Run logjuicer + include_role: + name: run-logjuicer + vars: + zuul_web_url: https://zuul.opendev.org/ diff --git a/zuul-tests.d/logs-jobs.yaml b/zuul-tests.d/logs-jobs.yaml index 683199140..dd357954e 100644 --- a/zuul-tests.d/logs-jobs.yaml +++ b/zuul-tests.d/logs-jobs.yaml @@ -15,6 +15,14 @@ - test-playbooks/upload-logs-s3.yaml run: test-playbooks/upload-logs-s3.yaml +- job: + name: zuul-jobs-test-run-logjuicer + description: Test the run-logjuicer role + files: + - roles/run-logjuicer/.* + - test-playbooks/run-loreduce.yaml + run: test-playbooks/run-logjuicer.yaml + # -* AUTOGENERATED *- # The following project section is autogenerated by # tox -e update-test-platforms @@ -25,6 +33,7 @@ jobs: &id001 - zuul-jobs-test-local-log-download - zuul-jobs-test-upload-logs-s3 + - zuul-jobs-test-run-logjuicer gate: jobs: *id001 periodic-weekly: