В моем ansible playbook у меня есть задача, которая выполняет скрипт:
- name: Execute Update on selected databases
shell: "./script_update.sh server007 {{item}} {{bdd_config[item].updateFile }}"
with_items: "{{selected_DBS}}"
register: updateResult
результат этого скрипта может быть примерно таким:
INFO - ================================================================================
INFO - BEGIN 'script_update' ON ini99db1 AT 2019/05/22 12:22:06
INFO - ================================================================================
INFO - THE MySQL SERVER server007 EXISTS
INFO - THE MySQL SERVER server007 IS ON
INFO - THE DATABASE myDB EXISTS
INFO - FILE /opt/myscode_In_progress.sql EXISTS.
ERROR - ERROR 1064 (42000) at line 4 in file: '/opt/myscode_In_progress.sql': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'azdazdazdazdazd' at line 1
INFO - SCRIPT OUTPUT : SEE LOG FILE 1
INFO - THE DB HAS BEEN CORRECTLY UPDATED
INFO - --------------------------------------------------------------------------------
INFO - THE PROCESS TERMINATED SUCCESSFULLY
INFO - SEE THE LOG FILE /opt/mysql/log/app_20190522_12H22.log
При отображении вывода моей регистровой переменной (updateResult) это дает что-то вроде этого:
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "nomadisdb",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "./rcd_db_update.ksh myserver01 nomadisdb nomadisdb_In_progress.sql",
"delta": "0:00:12.786607",
"end": "2019-05-22 12:36:52.817077",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "./rcd_db_update.ksh myserver01 nomadisdb nomadisdb_In_progress.sql",
"_uses_shell": true,
"argv": null,
"chdir": "/opt/application/i99/current/sh",
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "nomadisdb",
"rc": 0,
"start": "2019-05-22 12:36:40.030470",
"stdout_lines": [
"\tINFO - ================================================================================",
"\tINFO - BEGIN 'rcd_db_update' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================",
"\tINFO - THE MySQL SERVER myserver01 EXISTS",
"\tINFO - THE MySQL SERVER myserver01 IS ON",
"\tINFO - THE DATABASE nomadisdb EXISTS",
"\tINFO - FILE /opt/application/i99/current/sql/nomadisdb_In_progress.sql EXISTS.",
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
"\tINFO - SCRIPT OUTPUT : SEE LOG FILE 1",
"\tINFO - THE DB HAS BEEN CORRECTLY UPDATED",
"\tINFO - --------------------------------------------------------------------------------",
"\tINFO - THE PROCESS TERMINATED SUCCESSFULLY",
"\tINFO - SEE THE LOG FILE /opt/mysql/log/rcd_db_update_myserver01_nomadisdb_20190522_12H36.log",
"\tINFO - ================================================================================",
"\tINFO - END 'rcd_db_update.ksh' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================"
]
}
]
}
}
Моя цель - просмотреть это выходное сообщение и найти любую строку ОШИБКА, например:
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
я могу выполнить поиск с помощью регулярное выражение, который ищет строки, начинающиеся с "ОШИБКА" и включающие "на линии" и "в файле"
Наконец, я должен получить всю эту строку в результате
Я пытался использовать регулярное выражение следующим образом:
- name: set regex
set_fact:
regExpOfSqlError: ' '
become_user: mysql
- set_fact:
errorLine: "{{ updateResult.results | regex_search(regExpOfSqlError, ' ') }}"
become_user: mysql
Но мне все еще интересно, какой регулярное выражение я должен поставить, чтобы искать эти строки и выводить их
Предложения ?
Простое решение — использовать фильтр json_query
.
Примечания:
json_query
зависит от jmespath
. Вам нужно будет pip(3) install jmespath
перед запуском примера.to_json | from_json
хак необходим для работа вокруг известной ошибки при использовании функции jmespath contains
в ansible. Для этого требуется модификация на стороне jmespath, все еще ожидающий утверждения/разработки.jmespath
документация для получения дополнительной информации, но вот краткое объяснение строки запроса в моем примере: создайте проекцию списка всех входных элементов (updateResults.result
), затем выберите все элементы в записи stdout_lines
, содержащей текст ERROR
, и, наконец, спроецируйте результат. в виде плоского списка.---
- name: SO Test
hosts: localhost
vars:
# This result var mimics your current captured result
# I only kept the relevant part for the example.
updateResult:
results:
- stdout_lines: [
"\tINFO - ================================================================================",
"\tINFO - BEGIN 'rcd_db_update' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================",
"\tINFO - THE MySQL SERVER myserver01 EXISTS",
"\tINFO - THE MySQL SERVER myserver01 IS ON",
"\tINFO - THE DATABASE nomadisdb EXISTS",
"\tINFO - FILE /opt/application/i99/current/sql/nomadisdb_In_progress.sql EXISTS.",
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
"\tINFO - SCRIPT OUTPUT : SEE LOG FILE 1",
"\tINFO - THE DB HAS BEEN CORRECTLY UPDATED",
"\tINFO - --------------------------------------------------------------------------------",
"\tINFO - THE PROCESS TERMINATED SUCCESSFULLY",
"\tINFO - SEE THE LOG FILE /opt/mysql/log/rcd_db_update_myserver01_nomadisdb_20190522_12H36.log",
"\tINFO - ================================================================================",
"\tINFO - END 'rcd_db_update.ksh' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================"
]
tasks:
- name: Capture a list of all lines containing an error in all results
set_fact:
error_lines: "{{ updateResult.results | to_json | from_json | json_query(\"[].stdout_lines[?contains(@, 'ERROR')][]\") }}"
- name: Show lines with errors
debug:
var: error_lines
Который дает:
PLAY [SO Test] *****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Capture a list of all lines containing an error in all results] **********
ok: [localhost]
TASK [Show lines with errors] **************************************************
ok: [localhost] => {
"error_lines": [
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'"
]
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
Это не должно быть проблемой. Я захватил соответствующий var только для экономии места.
@firasKoubaa Отредактировано с примером var, почти идентичным вашему захваченному выводу. Выражение jmespath в json_query захватит плоский список всех строк ошибок во всех результатах вашего захвата.
кажется, что json_query не работает: вам нужно установить \"jmespath\" перед запуском фильтра json_query"}
Да, это задокументировано в ссылке, которую я предоставил в моем последнем редактировании фильтра json_query. pip install jmespath
поможет вам. Я только что добавил это в свой ответ.
отлично, но мой "stdout_lines:", который вы установили, является выходом зарегистрированного var в моем случае @Zeitounator