2022年6月6日月曜日

APEXセッションのデバッグ情報取得スクリプトのADB対応

 最近、問題があってOracle APEXのセッションに関する情報を取得する必要がありました。こちらからダウンロードできるOracle APEXのダウンロード・メディア(ZIPファイル)の、apex/utilities/debug以下に、デバッグ情報を取得するためのスクリプトが含まれています。

情報取得のためのスクリプトは、以下の5つです。

activity.sqld0.sqld1.sqld2.sqlds.sql

スクリプトの使用方法は、Oracle CorporationでOracle APEXを開発しているChristian Neumuellerさんが、彼のブログで説明しています。

Debugging APEX Authentication Issues

https://chrisonoracle.wordpress.com/2020/04/03/debugging-apex-authentication-issues/

元スクリプトはAPEXのスキーマに直接アクセスしているため、そのままではADBでは動きません。また、activity.sqlについては、内部表を公開している標準ビューに列DEBUG_PAGE_VIEW_IDが含まれていないため、ADBに対応させることができません。

それ以外のスクリプトは少々の変更で、ADBで動作させることができました。

d0.sqlシステム・パラメータSYSTE_DEBUG_LEVELを9に設定する(またはデバッグを解除する)スクリプトです。ADBの管理者ユーザーADMINで、変更無しで実行できます。すべてのAPEXセッションで完全トレースが取られるため、全体のパフォーマンスが大幅に低下します。そのため、完全トレースの設定はできる限りセッション単位で行なうべきです(以前に、セッションを選んでデバッグ・レベルを設定するAPEXアプリを作成しています)。ただし、ソーシャル・サインインで使用されるapex_authentication.callback(およびSAML認証で使用されるapex_authentication.saml_callback)のデバッグ・メッセージを取得する方法は、これ以外にはありません。

SQL> @d0

Changed debug level from "" to "9"


SQL> 

d1.sqlをADBで動作させるための差分は以下です。patchコマンドを使って、差分を適用します。

--- d1.sql 2022-06-06 12:55:24.000000000 +0900
+++ d1_p.sql 2022-06-06 12:58:10.000000000 +0900
@@ -54,23 +54,21 @@
end) request,
min(case when message like '%apex_error_code: %' then regexp_substr(message, 'apex_error_code:(.*)',1,1,null,1)
end) error_code,
- min(flow_id)||
- case when min(flow_id) <> max(flow_id) then '-'||max(flow_id) end flow_id,
+ min(application_id)||
+ case when min(application_id) <> max(application_id) then '-'||max(application_id) end flow_id,
min(page_id)||
case when min(page_id)<>max(page_id) then '-'||max(page_id) end page_id,
min(session_id)||
case when min(session_id)<>max(session_id) then '-'||max(session_id) end session_id,
- min(ws.short_name)||
- case when min(ws.short_name)<>max(ws.short_name) then '-'||max(ws.short_name) end workspace,
+ min(ws.workspace)||
+ case when min(ws.workspace)<>max(ws.workspace) then '-'||max(ws.workspace) end workspace,
min(apex_user)||
case when min(apex_user)<>max(apex_user) then '-'||max(apex_user) end apex_user,
row_number() over (order by d.page_view_id desc) r#
- from (select * from wwv_flow_debug_messages
- union all
- select * from wwv_flow_debug_messages2
+ from (select * from apex_debug_messages
) d,
- wwv_flow_companies ws
- where d.security_group_id = ws.provisioning_company_id
+ apex_workspaces ws
+ where d.workspace_id = ws.workspace_id
group by page_view_id )
where r# < 31
order by r# desc
view raw d1.patch.txt hosted with ❤ by GitHub

SESSION_IDds.sqlPAGE_VIEW_IDd2.sqlに渡して、さらに詳細のデータを取得します。

d2.sqlをADBで動作させるための差分は以下です。

--- d2.sql 2022-06-06 12:55:24.000000000 +0900
+++ d2_p.sql 2022-06-06 13:04:28.000000000 +0900
@@ -42,15 +42,14 @@
extract(second from (message_timestamp-first_value(message_timestamp) over (order by id))) secs,
message_level,
message,
- flow_id,
+ application_id flow_id,
page_id,
substr(session_id,1,7)||'~' sid,
regexp_replace(apex_user,'([[:alnum:]_]{1,3})[^@]*(@.*)','\1\2') apex_user,
- substr(security_group_id,1,7)||'~' sgid,
+ substr(workspace_id,1,7)||'~' sgid,
rtrim(call_stack,CR||':2') call_stack
- from (select * from wwv_flow_debug_messages
- union all
- select * from wwv_flow_debug_messages2),
+ from (select * from apex_debug_messages
+ ),
consts
where page_view_id=^1
order by id )
view raw d2.patch.txt hosted with ❤ by GitHub

ds.sqlをADBで動作させるための差分は以下です。

--- ds.sql 2022-06-06 12:55:25.000000000 +0900
+++ ds_p.sql 2022-06-06 13:03:45.000000000 +0900
@@ -31,11 +31,7 @@
with page_views1 as (
select page_view_id
- from wwv_flow_debug_messages
- where session_id=^1 ),
-page_views2 as (
- select page_view_id
- from wwv_flow_debug_messages2
+ from apex_debug_messages
where session_id=^1 )
select page_view_id,
to_char(start_timestamp,'hh24:mi:ss') started,
@@ -55,25 +51,22 @@
when message like 'A C C E P T:%' then 'accept'
end) show_accept,
to_char(extract(second from max(message_timestamp)-min(message_timestamp)),'90D99') secs,
- min(flow_id)||
- case when min(flow_id) <> max(flow_id) then '-'||max(flow_id) end flow_id,
+ min(application_id)||
+ case when min(application_id) <> max(application_id) then '-'||max(application_id) end flow_id,
min(page_id)||
case when min(page_id)<>max(page_id) then '-'||max(page_id) end page_id,
min(session_id)||
case when min(session_id)<>max(session_id) then '-'||max(session_id) end session_id,
- min(ws.short_name)||
- case when min(ws.short_name)<>max(ws.short_name) then '-'||max(ws.short_name) end workspace,
+ min(ws.workspace)||
+ case when min(ws.workspace)<>max(ws.workspace) then '-'||max(ws.workspace) end workspace,
min(apex_user)||
case when min(apex_user)<>max(apex_user) then '-'||max(apex_user) end apex_user,
row_number() over (order by d.page_view_id) r#
- from (select * from wwv_flow_debug_messages
+ from (select * from apex_debug_messages
where page_view_id in (select page_view_id from page_views1)
- union all
- select * from wwv_flow_debug_messages2
- where page_view_id in (select page_view_id from page_views2)
) d,
- wwv_flow_companies ws
- where d.security_group_id = ws.provisioning_company_id
+ apex_workspaces ws
+ where d.workspace_id = ws.workspace_id
group by page_view_id )
order by r#
/
view raw ds.patch.txt hosted with ❤ by GitHub


activity.sqlについては、以下のように手順を変えて情報を取得します。

APEX_ACTIVITY_LOGはAPEXセッションが生成されていないとデータが検索できないため、最初にAPEX_SESSION.CREATE_SESSIONを呼び出します。ユーザーは管理者ロールを持っている必要があります。

exec apex_session.create_session(アプリケーションID,ページID,'ユーザー名');
select * from apex_activity_log where session_id = セッションID order by time_stamp desc;


以上になります。