(BizRobo)MC上でスケジュール実行したロボットエラー情報をログデータベースから抽出する方法

<h2 name="f44197d6-4c33-4ade-be34-421af27fea81" id="f44197d6-4c33-4ade-be34-421af27fea81">概要</h2><p name="8bf72c68-7800-4d48-8eb5-abaf754db8c6" id="8bf72c68-7800-4d48-8eb5-abaf754db8c6">
※こちらの記事は以前noteで投稿していた記事の移植版です。

BizRobo!でロボットをMCで運用している方はエラーの発生等があったり稼働状況を確認する際、ログを見に行くと思います。<br>
こんな感じですね。</p><figure name="fed7ccc6-f015-4ad3-b738-7e1d933cacb4" id="fed7ccc6-f015-4ad3-b738-7e1d933cacb4"><img src="https://i.gyazo.com/d6c74f3656e4a36bb46bc6ba9d9b4a90.png" alt="画像1" width="620" height="106"><figcaption></figcaption></figure><p name="d2c514a2-9914-4e48-81d6-af90af22fb07" id="d2c514a2-9914-4e48-81d6-af90af22fb07">※v11.1の画面です。</p><p name="20c14a99-a03d-4bad-bde6-ee960c1ff4f7" id="20c14a99-a03d-4bad-bde6-ee960c1ff4f7">この画面からエラーメッセージとか発生日時とか確認していくわけですが、<br>
エラーログをスプレッドシートやシステムにその都度どんな対応をしたか等を書き溜めている方もいらっしゃるのではないでしょうか。<br>
いつ何のロボットでエラーが発生したかログを残しておくことで、このロボットはこの時間帯でよくエラーになるなぁとか傾向分析できますからね。<br>
私もやっていて、この時間だけエラーになるから稼働時間帯をずらそうとかの意思決定に利用したことがあります。</p><p name="d2fb88ea-2ffd-46db-bf20-97a163a876ab" id="d2fb88ea-2ffd-46db-bf20-97a163a876ab">その際、エラーが出るたびにいちいち手作業でエラー履歴を起票してメッセージ内容をコピペするのは大変だなぁと思っていたので、<br>
せっかくデータベースにログ記録しているのだから、SQL打ってデータを取り出してシステム転記するのをロボットにやらせてしまおう！<br>
となったわけです。</p><p name="427c96b2-c4b3-4384-88b2-b76538d65956" id="427c96b2-c4b3-4384-88b2-b76538d65956">さてここで問題になるのは、ログデータベースのテーブル名とカラム名って何が使われていてどのデータと紐づいているの？<br>
エラーになったロボットとならなかったロボットのログの違いって？<br>
スケジュールとの紐づけは？ってところです。<br>
これが分からないとどんな条件でどのデータを取り出せばいいのかわからないので、どうしようもないわけです。</p><p name="af7ceb61-1cc8-46c8-9e87-c8cc3328f72d" id="af7ceb61-1cc8-46c8-9e87-c8cc3328f72d"><br>
ということで、今回は必要になるテーブル名から、データの内容、実際のSQLの例、そしてロボットでの実装例までやっていきたいと思います。</p><p name="73dbd3e8-2962-4b43-b959-f772ddf061ec" id="73dbd3e8-2962-4b43-b959-f772ddf061ec">今回は、スケジュール実行ログをもとに、<br>
エラーが発生したロボットが存在するスケジュールから、<br>
エラーが起きたロボットの情報とエラーメッセージを抽出し、メール送信するのがゴールです。</p><p name="ba21c10e-d1b5-4d92-8016-4c8b476bc065" id="ba21c10e-d1b5-4d92-8016-4c8b476bc065">ロボットの手順としては以下のような形です。</p><p name="3cfc4768-97c5-4e5e-a076-14d7f550267b" id="3cfc4768-97c5-4e5e-a076-14d7f550267b">1 パラメータシートExcelを開く。<br>
2 各パラメータを変数に読み込む。<br>
3 エラー発生したスケジュールログを抽出する。<br>
4 スケジュールログをもとにロボットメッセージを抽出する。<br>
5 抽出したエラーログが重複していないか判定する。<br>
6 メール送信。<br>
7 実行IDをファイル名とした空ファイルを出力する。</p><h2 name="da60d85d-958b-48e8-8721-b070c6fd16c1" id="da60d85d-958b-48e8-8721-b070c6fd16c1">テーブル名</h2><p name="ec8721e3-e97c-47a2-89b2-e313ddae79f8" id="ec8721e3-e97c-47a2-89b2-e313ddae79f8">まずは対象になるテーブルですね。<br>
これが分からないとどこから取り出す？ということが分かりません。</p><p name="a76947de-0e81-4935-bb14-ffe1da2acb4f" id="a76947de-0e81-4935-bb14-ffe1da2acb4f">今回は取り出したいものとしては、大きく分けて2つのログになります。<br>
まず1つ目は、スケジュール実行ログ<br>
2つ目は、ロボットメッセージログになります。</p><p name="a4611a16-be72-4960-9344-18c304576d3f" id="a4611a16-be72-4960-9344-18c304576d3f">テーブル名としてはそれぞれ以下になります。</p><p name="b6e9d09e-ee41-4fdd-8543-9d3e9436934d" id="b6e9d09e-ee41-4fdd-8543-9d3e9436934d">スケジュール実行ログ：SCHEDULE_RUN<br>
ロボットメッセージログ：ROBOT_MESSAGE</p><p name="078f695e-4e16-492f-b415-2530c5a3a1c0" id="078f695e-4e16-492f-b415-2530c5a3a1c0">この2つからそれぞれ必要なデータを抽出します。</p><h2 name="ff94a31f-3ae3-448a-9117-7906d3e4a93f" id="ff94a31f-3ae3-448a-9117-7906d3e4a93f">カラム名</h2><p name="0a1838fd-c5e7-43e9-bf35-29470fb2f2bd" id="0a1838fd-c5e7-43e9-bf35-29470fb2f2bd">Excelでいうところのヘッダーにあたる箇所ですが、これが結構な数あります。<br>
ただ、必要なものはそれほど多くなく、今回はエラーが発生した際の以下の情報が分かれば十分だと思います。</p><p name="830defc2-9bbd-491d-8291-80cf0b1210b0" id="830defc2-9bbd-491d-8291-80cf0b1210b0">▼スケジュール<br>
スケジュール実行ID、プロジェクト名、スケジュール名</p><p name="5f4ec062-3693-4a36-98c0-7f27c3da3810" id="5f4ec062-3693-4a36-98c0-7f27c3da3810">▼ロボットメッセージ<br>
実行ID、ロボット名、ステップ名、ロケーションコード、ロボットメッセージ、エラー発生時刻</p><p name="e6da7492-0c9c-4db2-8456-7705f4610f16" id="e6da7492-0c9c-4db2-8456-7705f4610f16">エラーの対応時に見るのはおそらくここら辺の情報だと思いますが、<br>
もし必要であれば適宜調整します。</p><p name="58af7ca9-1ea5-48f3-87c8-e752a4c67e11" id="58af7ca9-1ea5-48f3-87c8-e752a4c67e11">ではそれぞれどのカラム名に相当するかというと…<br>
右側がDBのカラム名です。</p><p name="a75c833a-1b73-4893-a891-44212a4d1f0c" id="a75c833a-1b73-4893-a891-44212a4d1f0c">▼スケジュール<br>
スケジュール実行ID：ID<br>
プロジェクト名：PROJECTNAME<br>
スケジュール名：SCHEDULENAME</p><p name="74b64da2-dd6d-44ba-8557-7bbcd83f87a9" id="74b64da2-dd6d-44ba-8557-7bbcd83f87a9">▼ロボットメッセージ<br>
実行ID：EXECUTIONID<br>
ロボット名：ROBOTNAME<br>
ステップ名：STEPNAME<br>
ロケーションコード：LOCATIONCODE<br>
ロボットメッセージ：MESSAGE<br>
エラー発生時刻：TIME</p><p name="cc838e39-0889-4d6a-9374-8b1537cb5868" id="cc838e39-0889-4d6a-9374-8b1537cb5868">なかなか素直で分かりやすいカラム名でありがたいですね。<br>
各テーブルからこれらのカラムを抽出してきます。</p><p name="ca3a8601-67a6-440e-91a9-ccd3e8030433" id="ca3a8601-67a6-440e-91a9-ccd3e8030433">次はそのためのSQLを見ていきます。</p><h2 name="903d3e7c-c225-4faa-afa1-3b7541c2e41d" id="903d3e7c-c225-4faa-afa1-3b7541c2e41d">SQL</h2><p name="ad2e174d-fe60-4c29-860e-4d32c3e3fea4" id="ad2e174d-fe60-4c29-860e-4d32c3e3fea4">今回は、ロボットエラーが発生しているスケジュール情報を抜き出し、<br>
それに紐づき、かつエラーが発生しているロボットを抜き出します。<br>
そのため、まずはスケジュール情報を抽出してきます。</p><p name="aedb6d45-68c8-4c39-93f1-e1ab0b6534e8" id="aedb6d45-68c8-4c39-93f1-e1ab0b6534e8">たとえば、以下のように<br>
「SCHEDULE_RUN」テーブルからロボットエラーが発生していることを示す「RESULT = 1」の条件で、<br>
かつ終了時間「ENDTIME」が今(NOW)から1(DAY)日前までのデータを抽出、とします。</p><pre name="1e120f19-05b4-447a-ba4a-b42d0400b55f" id="1e120f19-05b4-447a-ba4a-b42d0400b55f">
<code>SELECT
*
FROM
SCHEDULE_RUN
WHERE
RESULT = 1
AND ENDTIME &gt; DATE_SUB(NOW(), INTERVAL 1 DAY)
ORDER BY ENDTIME ASC</code>
</pre><p name="f8ec84c3-89ca-49cd-8536-6c7fee461762" id="f8ec84c3-89ca-49cd-8536-6c7fee461762">こうすることで、1日前から現在までにロボットエラーが発生したスケジュール情報を抜き出せます。<br>
DAYの部分はhourでもminuteでも要件に合わせて好きに設定してください。</p><p name="866fa89e-c47e-4f29-bb25-ea6b2d5a1c52" id="866fa89e-c47e-4f29-bb25-ea6b2d5a1c52">ORDER BYは表示順を指定するのですが、今回はスケジュール終了時間の昇順にしています。<br>
早くスケジュールが完了したものから出す、ということです。</p><p name="fedfc86a-2054-41be-ae1e-086f72d976ee" id="fedfc86a-2054-41be-ae1e-086f72d976ee">では、次にロボットメッセージを取り出します。<br>
EXECUTIONID の前半部分をSCHEDULEIDで指定し「SEVERITY」が0ではない履歴を抽出します。<br>
</p><pre name="1143577b-7f6a-4fbe-8ce9-335abc6dcf3e" id="1143577b-7f6a-4fbe-8ce9-335abc6dcf3e"><code>SELECT

*

FROM

ROBOT_MESSAGE

WHERE

EXECUTIONID like '[SCHEDULEID]-%'

AND SEVERITY &lt;&gt; 0</code></pre><p name="4f46e2b3-4d5e-4cdf-8ec8-a0a0312b96ed" id="4f46e2b3-4d5e-4cdf-8ec8-a0a0312b96ed">[SCHEDULEID]の部分は、スケジュールログの方から変数で置き換えるようにします。<br>
なぜEXECUTIONIDをスケジュールの実行IDから指定しているかというと、<br>
スケジュールで実行したロボットの実行IDの「-」より前の数字はスケジュールのIDに紐づくからなのです。<br>
たとえば、スケジュールのIDが「3」だった場合、ロボットの方は「3-8-22c19b6da4」といった値になります。<br>
そのため、最初の数字をスケジュールのIDで指定し、それ以下の値を「like」で指定してあいまい検索をしているわけです。<br>
後半は分からないけど、とにかくその値に紐づく情報ちょうだいって言っているわけです。</p><p name="d30e4517-53d1-42c0-9697-dfa5c6e71a6f" id="d30e4517-53d1-42c0-9697-dfa5c6e71a6f">これで、エラーが発生したロボットメッセージを取り出せます。<br>
ちなみに、ロボットエラーを全部取り出すとエラーが100件とか出ているときに大変なので、<br>
ロボット実装する際は値判定とかで停止させましょう。<br>
本当に大変な目に遭います。</p><h2 name="257ddea7-0e48-43a7-a6f5-b5f38c38127f" id="257ddea7-0e48-43a7-a6f5-b5f38c38127f">ロボット実装</h2><p name="9ed9663b-d96e-4597-835e-3ef704e182b1" id="9ed9663b-d96e-4597-835e-3ef704e182b1">ようやくロボットでの実装例です。<br>
フローとしてはこんな感じ</p><figure name="dd4524d9-3895-4f3b-b8c8-d92e69b81b74" id="dd4524d9-3895-4f3b-b8c8-d92e69b81b74"><img src="https://i.gyazo.com/a420ce3bf2a97b847a758ce27fc75ebd.png" alt="画像2" width="620" height="41"><figcaption></figcaption></figure><p name="6a645fac-52e6-4006-b196-3c2fc7108873" id="6a645fac-52e6-4006-b196-3c2fc7108873">1 パラメータシートExcelを開く。<br>
2 各パラメータを変数に読み込む。<br>
3 エラー発生したスケジュールログを抽出する。<br>
4 スケジュールログをもとにロボットメッセージを抽出する。<br>
5 抽出したエラーログが重複していないか判定する。<br>
6 メール送信。<br>
7 実行IDをファイル名とした空ファイルを出力する。<br>
</p><p name="0045bea0-4d3d-45b5-8d81-525f6916c0b4" id="0045bea0-4d3d-45b5-8d81-525f6916c0b4">先ほどの大変なことになるのを防ぐため、値判定でループ回数制限かけています。<br>
なので最初の一件しか取らない前提です。<br>
経験上たいていの場合最初の一件が問題なのでそれ以降は適宜自分で取り出しましょう。</p><p name="bb34f468-3c4a-4f6b-b601-f8f627bc9ba4" id="bb34f468-3c4a-4f6b-b601-f8f627bc9ba4">SQLの取得期間やスケジュールIDの置き換えは、エクスプレッションのreplaceText関数を利用できます。</p><figure name="153a5094-92c1-41be-9aa6-6f4a5cfeaf74" id="153a5094-92c1-41be-9aa6-6f4a5cfeaf74"><img src="https://i.gyazo.com/d02619393aba69a59208261bc5ca75ac.png" alt="画像4" width="616" height="490"><figcaption></figcaption></figure><pre name="1eddcc80-5210-4b78-84f1-975c84e5f805" id="1eddcc80-5210-4b78-84f1-975c84e5f805"><code>replaceText(infoログ抽出.スケジュール取得SQL,&gt;&gt;取得期間&lt;&lt;,infoログ抽出.取得期間)</code></pre><p name="f471b2c1-3609-4d6d-bd41-40847c9d5d7c" id="f471b2c1-3609-4d6d-bd41-40847c9d5d7c">&nbsp;​<br>
</p><figure name="0f9a9037-2be8-4877-a330-32cf4f4d5c3f" id="0f9a9037-2be8-4877-a330-32cf4f4d5c3f"><img src="https://i.gyazo.com/d8ab8b6a008d001c71e24dba84e07d41.png" alt="画像4" width="620" height="494"><figcaption></figcaption></figure><pre name="72d320c0-3816-44df-9240-21b0ed0aece8" id="72d320c0-3816-44df-9240-21b0ed0aece8"><code>replaceText(infoログ抽出.ロボットメッセージ取得SQL,&gt;&gt;SCHEDULEID&lt;&lt;,スケジュールログ.ID)</code></pre><p name="6e7af81f-4560-45a8-9091-144e132cc2d4" id="6e7af81f-4560-45a8-9091-144e132cc2d4">あとはこんな感じでファイル有無判定とファイル出力を駆使してファイルを出力したりファイル有無確認して重複処理しないようにします。</p><figure name="3b55fb04-0c43-4dda-ae38-abc66978f5f0" id="3b55fb04-0c43-4dda-ae38-abc66978f5f0"><img src="https://i.gyazo.com/3b92c3e638c077ded41499c942d1d140.png" alt="画像5" width="586" height="289"><figcaption></figcaption></figure><p name="1194c890-538d-4ca5-8e0b-6d32862500eb" id="1194c890-538d-4ca5-8e0b-6d32862500eb">あとはひな形として作成しておいた件名とメール本文の一部をデータベースから抽出した変数で置き換えると、こんなメールを送ることもできます。</p><figure name="55f25cf7-0fab-4c6a-b736-bed995f40fa5" id="55f25cf7-0fab-4c6a-b736-bed995f40fa5"><img src="https://i.gyazo.com/c8f788dcf9eaa729feeaf2923161a6ba.png" alt="画像6" width="620" height="306"><figcaption></figcaption></figure><p name="209aca99-7c81-40fe-b58f-7b911feb4492" id="209aca99-7c81-40fe-b58f-7b911feb4492">今回はメール送信にしましたが、私は実際の業務ではエラー対応履歴を記載するためのKintoneアプリを作成し、そちらにロボットで転記後、Slack通知、ということをしていました。</p><p name="65d78df4-adf0-4ab4-841a-c0f49b2b6da9" id="65d78df4-adf0-4ab4-841a-c0f49b2b6da9">データベースからのログ抽出をマスターすると、各ロボットの実行時間を抽出し、各時間帯やロボット毎のKCU Waitの割合を算出したり、ロボットがどれぐらい働いてくれているか等の分析にも利用できると思います。</p><h2 name="b63c7d5a-4022-4472-857e-e0cec24fb4f5" id="b63c7d5a-4022-4472-857e-e0cec24fb4f5">サンプルロボット</h2><p name="94025bbf-540d-4f5d-8bfe-55aff7034ac5" id="94025bbf-540d-4f5d-8bfe-55aff7034ac5">今回のロボットをサンプル化してRobot-Hubにアップロードしました。<br>
無料でダウンロードできますのでアレンジして使ってみてください。<br>
<a href="https://robot-hub.bizrobo.com/products/view/5157746f4e476331526c686d57467059626b4647634535456458457a4c307430556e4e4664544a734e6e417a4e47357a6148633950513d3d" target="_blank" rel="nofollow noopener">【サンプル】MCロボットエラーログデータベース抽出</a></p><p name="39513b0d-83c3-4249-8629-34300e96e854" id="39513b0d-83c3-4249-8629-34300e96e854"><br>
</p>