2023年12月18日月曜日

APEX 23.2のAPEXワークフローの実行ログを確認する

Oracle APEX 23.2で追加されたワークフローの実行ログは、ビューAPEX_WORKFLOW_AUDITAPEX_DEBUG_MESSAGESより確認できます。ビューAPEX_DEBUG_MESSAGESはAPEX 23.2以前よりあるデバッグ・ログを参照するビューですが、APEX 23.2より列WORKFLOW_INSTANCE_IDが追加されています。

ビューAPEX_WORKFLOW_AUDITAPEX_DEBUG_MESSAGESを参照する、以下のような簡単なAPEXアプリケーションを作成してみました。



新しいAPEXワークフローの実行ログの確認方法について開発者に確認したところ、いくつかの方法を教えていただきました。

最初の方法です。

タスクの詳細ページに含まれている履歴より、ワークフロー・インスタンスIDがわかるので、それを使ってビューAPEX_DEBUG_MESSAGESを検索する、というものです。

履歴のソースはビューAPEX_WORKFLOW_AUDITです。


履歴より取得したワークフロー・インスタンスIDを使って、以下の検索を実施します。
select message
from apex_debug_messages 
where workflow_instance_id = [ワークフロー・インスタンスID]
order by message_timestamp;

もうひとつの方法です。

デバッグ・メッセージのページより、ページ・フィルタを除いて、ユーザーnobodyで検索すると、ワークフロー関連のメッセージが表示されるとのことです。


ただし、デバッグ・メッセージのページはビューAPEX_DEBUG_MESSAGESがソースです。ビューAPEX_DEBUG_MESSAGESには、すでに列WORKSPACE_INSTANCE_IDが追加されています。デバッグ・メッセージのページの対話モード・レポートに列WORKSPACE_INSTANCE_IDが含まれていない点については、不具合として登録されています。

また、ギャラリにあるサンプル・アプリケーションSample Workflow, Approvals, and Tasksにデバッグ・メッセージを表示するページが含まれています。


ナビゲーション・メニューWorkflow Debug Messagesから表示されるページに、ビューAPEX_DEBUG_MESSAGESのレポートが実装されています。


対話モード・レポートのソースとして、以下のSELECT文が記述されています。
select message_timestamp,
       elapsed_time,
       execution_time,
       message,
       page_id,
       workflow_instance_id,
       session_id,
       message_level,
       trim(replace(call_stack,'%')) as call_stack
 from apex_debug_messages
where application_id = :APP_ID
and apex_user = 'nobody'
and call_stack like '%\%WORKFLOW.%' escape '\'
and message_level < 9
order by message_timestamp desc

サンプル・アプリケーションSample Workflow, Approvals, and Tasksのインストールにあたって、注意することがあります。このサンプル・アプリケーションの初期データに含まれている日付データが、17-DEC-80といった形式になっています。アプリケーション・ビルダーが日本語になっているとORA-01843: 指定した月が無効です。が発生し、初期データのロードに失敗します。

その結果、Loginのページが以下のように表示されます。


初期データが正しくロードされていると、以下のように表示されます。


アプリケーション・ビルダーの言語を英語に切り替えたのち、サンプル・アプリケーションをインストールするか、もしくは、英語に切り替えた上でSQLコマンドよりプロシージャeba_demo_appr_data.install_sample_dataを実行することで、初期データを正しくロードすることができます。
begin
    eba_demo_appr_data.install_sample_data;
end;
/

以下より、今回作成したAPEXアプリケーションの説明を行います。

APEXワークフローのメタデータおよびランタイム・データを保存しているビューについて、ArchitectのRalf Muellerさんがブログ記事APEX Workflow Development Lifecycle and Managementの最後にER図を載せています。以下に引用します。


APEXアプリケーションの共有コンポーネントとしてワークフローは作成されるため、ビューAPEX_APPLICATIONS(上の図には含まれていません)とビューAPEX_APPL_WORKFLOWSには親子関係があります。ワークフロー・バージョンのビューAPEX_APPL_WORKFLOW_VERSIONSはビューAPEX_APPL_WORKFLOWSの子になります。

ワークフローのインスタンスはワークフロー・バージョンでの定義に従って、それが開始したインスタンスになります。これはビューAPEX_WORKFLOWSから参照できます。ビューAPEX_APPL_WORKFLOW_VERSIONSAPEX_WORKFLOWSには親子関係があります。ビューAPEX_WORKFLOWSWORKFLOW_VERSION_IDAPEX_APPL_WORKFLOW_VERSIONSVERSION_IDがジョインに使うキーになります。

ビューAPEX_WORKFLOWSの列WORKFLOW_IDは、ワークフロー・インスタンスIDになります。ビューAPEX_APPL_WORKFLOWS(およびAPEX_APPL_WORKFLOW_VERSIONS)の列WORKFLOW_IDとは異なります。APEX_APPL_WORKFLOWSWORKFLOW_IDとのジョインに使う列はWORKFLOW_DEF_IDです。

ビューAPEX_WORKFLOW_AUDITWORKFLOW_IDはワークフロー・インスタンスIDのなので、ビューAPEX_WORKFLOWSの列WORKFLOW_IDとジョインできます。また、ビューAPEX_DEBUG_MESSAGESの列WORKFLOW_INSTANCE_IDも同じ扱いになります。

以上を踏まえた上で、ビューAPEX_WORKFLOW_AUDITをソースとした対話モード・レポートのページと、ビューAPEX_DEBUG_MESSAGESをソースとした対話モード・レポートのページを作成します。


アプリケーションを選択するためのページ・アイテムをP1_APPLICATION_IDとして作成します。タイプ選択リストです。ラベルアプリケーションとします。

LOVタイプSQL問合せとし、SQL問合せとして以下を記述します。
select application_name d, application_id r from apex_applications where workspace_id = :WORKSPACE_ID


ワークフローを選択するためのページ・アイテムをP1_WORKFLOW_IDとして作成します。タイプ選択リストです。ラベルワークフローとします。

LOVタイプSQL問合せとし、SQL問合せとして以下を記述します。
select name d, workflow_id r from apex_appl_workflows where application_id = :P1_APPLICATION_ID
カスケードLOV親アイテムとしてP1_APPLICATION_IDを指定します。


ワークフロー・バージョンを選択するためのページ・アイテムをP1_VERSION_IDとして作成します。タイプ選択リストです。ラベルバージョンとします。

LOVタイプSQL問合せとし、SQL問合せとして以下を記述します。
select workflow_version d, version_id r from apex_appl_workflow_versions where workflow_id = :P1_WORKFLOW_ID
カスケードLOV親アイテムとしてP1_WORKFLOW_IDを指定します。


ワークフロー・インスタンスを選択するためのページ・アイテムをP1_INSTANCE_IDとして作成します。タイプ選択リストです。ラベルインスタンスとします。

LOVタイプSQL問合せとし、SQL問合せとして以下を記述します。
select title || ' - ' || to_char(start_time,'YYYY-MM-DD HH24:MI') d, workflow_id r from apex_workflows where workflow_version_id = :P1_VERSION_ID order by start_time desc
カスケードLOV親アイテムとしてP1_VERSION_IDを指定します。


ビューAPEX_WORKFLOW_AUDITをソースとする対話モード・レポートWHERE句として以下を指定します。

workflow_id = :P1_INSTANCE_ID

送信するページ・アイテムP1_INSTANCE_IDを指定します。


ワークフロー・インスタンスの選択が変更されたときに対話モード・レポートがリフレッシュされるように、ページ・アイテムP1_INSTANCE_ID動的アクションを作成します。

動的アクションが起動するタイミングイベントは、ページ・アイテムのデフォルトの変更です。


TRUEアクションリフレッシュ影響を受ける要素としてリージョンAPEX_WORKFLOW_AUDITを選択します。


ビューAPEX_DEUB_MESSAGESをソースとする対話モード・レポートのページを作成します。

ページ・アイテムP2_WORKFLOW_INSTANCE_IDを作成します。レポートのWHERE句の条件に使用する値を保持します。


対話モード・レポートのソースはAPEX_DEBUG_MESSAGESです。WHERE句として以下を記述します。

workflow_instance_id = :P2_WORKFLOW_INSTANCE_ID


最後にAPEX_WORKFLOW_AUDITの列WORKFLOW_ID(実際はワークフロー・インスタンスのID)からAPEX_DEBUG_MESSAGESのレポートを開く設定を行います。

WORKFLOW_ID識別タイプリンクに変更します。


リンク・ビルダーを開き、ページ・アイテムP2_WORKFLOW_INSTANCE_IDに列WORKFLOW_IDの値が渡されるように、アイテムの設定名前P2_WORKFLOW_INSTANCE_ID#WORKFLOW_ID#を設定します。


以上でアプリケーションは完成です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/apex-workflow-monitor.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。