はじめに
ジョブスケジューラのRundeck便利なんだけど、ジョブ実行履歴を調べるのにActivityの画面だと、この時間帯に動いてたジョブを調べたいみたいなときに地味に困る。実行間隔の短いジョブが混ざってると、Activityの画面で大量のジョブ実行履歴をページングするのはつらい。
例えばシステムメンテナンスでジョブを一時停止したいときの影響範囲を調べたり、Rundeck自体の障害で起動できなかった可能性のあるジョブを調べたりするのに、先週とか先月の同じ時間帯に動いてたジョブの実行履歴をいい感じに調べたい。いいかんじとはジョブ実行履歴じゃなくて、欲しいのはジョブ定義でユニークに集約した情報だったりする。
WebのUIはなくてもジョブ実行履歴とジョブ定義自体はRundeckがメタデータとして持ってるはずなんで、メタデータのDBから直接SQLで抽出すればなんかできそうな予感。
というわけでやってみた。
稼働確認したのは以下のバージョン。
- Rundeck: 2.9.3
- MySQL: 5.7
Rundeckのメタデータはバージョン上がると変わるかもしれない&バックエンドがMySQL以外の場合は、適宜読み替えて下さい。
テーブル定義を確認する
とりあえずテーブル一覧を見てみる。
mysql> SHOW tables;
+----------------------------+
| Tables_in_rundeck |
+----------------------------+
| auth_token |
| base_report |
| execution |
| job_file_record |
| log_file_storage_request |
| node_filter |
| notification |
| orchestrator |
| plugin_meta |
| project |
| rdoption |
| rdoption_values |
| rduser |
| report_filter |
| scheduled_execution |
| scheduled_execution_filter |
| storage |
| workflow |
| workflow_step |
| workflow_workflow_step |
+----------------------------+
20 rows in set (0.00 sec)
execution
テーブルってのがジョブ実行履歴で、 date_started
にジョブ開始日時、 date_completed
にジョブ終了日時が入ってる。
時刻はRundeckのプロセスを動かしてるタイムゾーンなので、JSTならJSTで保存されてます。
mysql> DESC execution;
+------------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| abortedby | varchar(255) | YES | | NULL | |
| arg_string | longtext | YES | | NULL | |
| cancelled | bit(1) | NO | | NULL | |
| date_completed | datetime | YES | MUL | NULL | |
| date_started | datetime | YES | MUL | NULL | |
| do_nodedispatch | bit(1) | YES | | NULL | |
| execution_type | varchar(30) | YES | | NULL | |
| failed_node_list | longtext | YES | | NULL | |
| filter | longtext | YES | | NULL | |
| loglevel | varchar(255) | YES | | NULL | |
| node_exclude | longtext | YES | | NULL | |
| node_exclude_name | longtext | YES | | NULL | |
| node_exclude_os_arch | longtext | YES | | NULL | |
| node_exclude_os_family | longtext | YES | | NULL | |
| node_exclude_os_name | longtext | YES | | NULL | |
| node_exclude_os_version | longtext | YES | | NULL | |
| node_exclude_precedence | bit(1) | YES | | NULL | |
| node_exclude_tags | longtext | YES | | NULL | |
| node_filter_editable | bit(1) | YES | | NULL | |
| node_include | longtext | YES | | NULL | |
| node_include_name | longtext | YES | | NULL | |
| node_include_os_arch | longtext | YES | | NULL | |
| node_include_os_family | longtext | YES | | NULL | |
| node_include_os_name | longtext | YES | | NULL | |
| node_include_os_version | longtext | YES | | NULL | |
| node_include_tags | longtext | YES | | NULL | |
| node_keepgoing | bit(1) | YES | | NULL | |
| node_rank_attribute | varchar(255) | YES | | NULL | |
| node_rank_order_ascending | bit(1) | YES | | NULL | |
| node_threadcount | int(11) | YES | | NULL | |
| orchestrator_id | bigint(20) | YES | MUL | NULL | |
| outputfilepath | longtext | YES | | NULL | |
| project | varchar(255) | NO | | NULL | |
| retry | longtext | YES | | NULL | |
| retry_attempt | int(11) | YES | | NULL | |
| retry_execution_id | bigint(20) | YES | MUL | NULL | |
| scheduled_execution_id | bigint(20) | YES | MUL | NULL | |
| server_nodeuuid | varchar(36) | YES | | NULL | |
| status | varchar(255) | YES | | NULL | |
| succeeded_node_list | longtext | YES | | NULL | |
| timed_out | bit(1) | YES | | NULL | |
| timeout | longtext | YES | | NULL | |
| rduser | varchar(255) | NO | | NULL | |
| will_retry | bit(1) | YES | | NULL | |
| workflow_id | bigint(20) | YES | MUL | NULL | |
| retry_delay | varchar(255) | YES | | NULL | |
| success_on_empty_node_filter | bit(1) | YES | | NULL | |
| user_role_list | longtext | YES | | NULL | |
+------------------------------+--------------+------+-----+---------+----------------+
50 rows in set (0.00 sec)
scheduled_execution
テーブルってのがジョブのスケジュール定義で、ジョブ名とかいつ起動するかのcrontabの情報が入っている。
mysql> DESC scheduled_execution;
+------------------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------------+---------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| arg_string | longtext | YES | | NULL | |
| date_created | datetime | NO | | NULL | |
| day_of_month | varchar(255) | YES | | NULL | |
| day_of_week | varchar(255) | YES | | NULL | |
| description | longtext | YES | | NULL | |
| do_nodedispatch | bit(1) | YES | | NULL | |
| exec_count | bigint(20) | YES | | NULL | |
| execution_enabled | bit(1) | YES | | NULL | |
| filter | longtext | YES | | NULL | |
| group_path | varchar(2048) | YES | | NULL | |
| hour | varchar(255) | YES | | NULL | |
| job_name | varchar(1024) | NO | | NULL | |
| last_updated | datetime | NO | | NULL | |
| log_output_threshold | varchar(256) | YES | | NULL | |
| log_output_threshold_action | varchar(256) | YES | | NULL | |
| log_output_threshold_status | varchar(256) | YES | | NULL | |
| loglevel | varchar(255) | YES | | NULL | |
| minute | varchar(255) | YES | | NULL | |
| month | varchar(255) | YES | | NULL | |
| multiple_executions | bit(1) | YES | | NULL | |
| next_execution | datetime | YES | | NULL | |
| node_exclude | longtext | YES | | NULL | |
| node_exclude_name | longtext | YES | | NULL | |
| node_exclude_os_arch | longtext | YES | | NULL | |
| node_exclude_os_family | longtext | YES | | NULL | |
| node_exclude_os_name | longtext | YES | | NULL | |
| node_exclude_os_version | longtext | YES | | NULL | |
| node_exclude_precedence | bit(1) | YES | | NULL | |
| node_exclude_tags | longtext | YES | | NULL | |
| node_filter_editable | bit(1) | YES | | NULL | |
| node_include | longtext | YES | | NULL | |
| node_include_name | longtext | YES | | NULL | |
| node_include_os_arch | longtext | YES | | NULL | |
| node_include_os_family | longtext | YES | | NULL | |
| node_include_os_name | longtext | YES | | NULL | |
| node_include_os_version | longtext | YES | | NULL | |
| node_include_tags | longtext | YES | | NULL | |
| node_keepgoing | bit(1) | YES | | NULL | |
| node_rank_attribute | varchar(255) | YES | | NULL | |
| node_rank_order_ascending | bit(1) | YES | | NULL | |
| node_threadcount | int(11) | YES | | NULL | |
| nodes_selected_by_default | bit(1) | YES | | NULL | |
| orchestrator_id | bigint(20) | YES | MUL | NULL | |
| project | varchar(255) | NO | | NULL | |
| retry | longtext | YES | | NULL | |
| schedule_enabled | bit(1) | YES | | NULL | |
| scheduled | bit(1) | NO | | NULL | |
| seconds | varchar(255) | YES | | NULL | |
| server_nodeuuid | varchar(36) | YES | | NULL | |
| timeout | longtext | YES | | NULL | |
| total_time | bigint(20) | YES | | NULL | |
| rduser | varchar(255) | YES | | NULL | |
| user_role_list | longtext | YES | | NULL | |
| uuid | varchar(255) | YES | | NULL | |
| workflow_id | bigint(20) | YES | MUL | NULL | |
| year | varchar(255) | YES | | NULL | |
| retry_delay | longtext | YES | | NULL | |
| success_on_empty_node_filter | bit(1) | YES | | NULL | |
| time_zone | varchar(256) | YES | | NULL | |
+------------------------------+---------------+------+-----+---------+----------------+
61 rows in set (0.01 sec)
指定の時間帯に動いてたジョブを特定する
executionから指定の時間帯に開始、または終了したジョブ、または指定の範囲でずっと動いてたジョブを抽出して、
scheduled_executionとJOINして、
scheduled_executionでSELECT DISTINCTして必要な情報を引っ張り出してあげればよさそう。
あとは多少見やすいように文字列加工。
完成品はこちらです。
SET @from = '2018-08-06 02:00:00', @to = '2018-08-06 03:00:00';
SELECT DISTINCT
s.uuid,
LEFT(CONCAT(s.project, '/', s.group_path, '/', s.job_name), 64) AS job,
LEFT(SUBSTRING_INDEX(s.description, '\n', 1), 10) AS description,
s.filter, CONCAT(s.seconds, ' ', s.minute, ' ', s.hour, ' ', s.day_of_month, ' ', s.month, ' ', s.day_of_week, ' ', s.year) AS schedule,
s.next_execution AS next
FROM
execution AS e
LEFT JOIN scheduled_execution AS s
ON e.scheduled_execution_id = s.id
WHERE
(e.date_started BETWEEN @from AND @to)
OR (e.date_completed BETWEEN @from AND @to)
OR (e.date_started < @from AND e.date_completed > @to)
ORDER BY job;
実行結果は多少ぼかしてしか貼れないけど、雰囲気だけお伝えするとこんなかんじ。
+------+-------------------+-------------+-------------+-----------------+---------------------+
| uuid | job | description | filter | schedule | next |
+------+-------------------+-------------+-------------+-----------------+---------------------+
| xxxx | proj1/group1/job1 | job1 | name: batch | 0 3 * * * ? * | 2018-09-05 13:03:00 |
| xxxx | proj1/group1/job2 | job2 | name: batch | 0 33 * * * ? * | 2018-09-05 12:33:00 |
これでRundeck職人に頼らずに機械的に対象のジョブが特定できますね。
どうぞご利用下さい。