Skip to main content

Command Palette

Search for a command to run...

Using APEX_DEBUG Without an APEX Session

Updated
3 min read

Check out APEX Instant Tips episode 178 for more information on this topic.

Code instrumentation is key to developing maintainable and testable applications. The APEX_DEBUG PL/SQL API has everything I need and a lot of features under the covers that most home-grown systems lack (like flood control). Despite initial appearances, you can use APEX_DEBUG without being in the context of an APEX application, though it takes just a little extra. Below are a few steps that will give you all of the features of APEX_DEBUG without needing an APEX session.

Create the following table

This will allow you to control the debug level when you don’t have an APEX context. You can add additional columns to support additional requirements. For example, you could add a column to indicate a particular database session for which you want to set the debug level. If you alter the table below you will need to change the corresponding package (further below) to meet your needs.

CREATE TABLE  "XXTLN_DEBUG" 
   (    "DEBUG_LEVEL" NUMBER
   )
/

Add 1 row to the table

In this case we are just going to set the debug level for ALL sessions that do not have an APEX context.

insert into xxtln_debug (debug_level) values (1);

Create the following package

This package just handles setting the APEX security group id (aka workspace id). Setting that allows you to see the contents of the APEX debug message log.

create or replace package XXTLN_DEBUG_util as

-- Set how often you would like to check for a change to the debug level.
-- Note: do NOT set this while things are running...you should set it to what you want it to be all the time and leave it alone.
-- It is reasonable to set it 1 so that it always check, but you may decide to check less fequently.
gc_workspace_name               constant    varchar2(256) := 'ANTON';

g_check_every_n_calls           number := 1;
g_count_since_debug_checked     number := g_check_every_n_calls + 1;
g_debug_level                   number;

procedure setup;

end;
/

create or replace package body XXTLN_DEBUG_UTIL as

procedure setup is

l_sg_id         number;
l_debug_level   number;
begin
    -- Make sure we always have a workspace ID so that errors and "forced messages" are visible.
    if sys_context('APEX$SESSION','WORKSPACE_ID') is null then
        apex_util.set_security_group_id(
            p_security_group_id => apex_util.find_security_group_id(p_workspace => gc_workspace_name)
            );
    end if;

    -- If we are NOT in an APEX application session set the "no APEX session" debug level.
    if sys_context('APEX$SESSION','APP_ID') is null then
        -- only check every n calls
        if g_count_since_debug_checked >= g_check_every_n_calls then
            -- Get the current "no APEX session" debug level
            select max(debug_level) into l_debug_level
              from xxtln_debug;

            -- Set the debug level if it has changed.
            if nvl(g_debug_level, -1) != nvl(l_debug_level, -1) then

                if l_debug_level is not null then
                    apex_debug.enable(l_debug_level);
                else
                    apex_debug.disable;
                end if;

                g_debug_level := l_debug_level;                
            end if;

            g_count_since_debug_checked := 1;
        else
            g_count_since_debug_checked := g_count_since_debug_checked + 1;
        end if;
    end if;
end setup;

end XXTLN_DEBUG_UTIL;
/

Add the following line of code to the beginning of all of your public functions and procedures within your PL/SQL code

xxtln_debug_util.setup;