August 10, 2015

Easy logging and debugging, version 2.0

Each application needs a simple way to log errors and find them. The following technique can also be used to debug Forms, Reports and PL/SQL. This version 2.0 has an important change. The username ist stored in the debugging-data and the viewname has changed a little bit.

First create the table, sequence and view to store the logging-information:

CREATE TABLE Logging (
  ID                         NUMBER(9) NOT NULL,
  SESSION_ID                 NUMBER(9),
  INSERT_DATE                DATE NOT NULL,
  INSERT_USER                VARCHAR2(30) NOT NULL,
  TEXT                       VARCHAR2(2000) NOT NULL);

CREATE SEQUENCE Logging_SEQ;

CREATE OR REPLACE VIEW Logging_desc_V
         (ID, SESSION_ID, INSERT_DATE, INSERT_USER, TEXT)
AS SELECT ID, SESSION_ID, INSERT_DATE, INSERT_USER, TEXT
     FROM Logging
    ORDER BY SESSION_ID DESC, ID DESC;

You need also a package with some functions to start the logging-process
CREATE OR REPLACE PACKAGE PK_DEBUG IS
  FUNCTION Debug_allowed RETURN BOOLEAN;
  FUNCTION Next_ID       RETURN NUMBER;

  PROCEDURE Disable;
  PROCEDURE Enable;
  PROCEDURE Destroy;
  PROCEDURE Init  (P_Debug_allowed IN BOOLEAN DEFAULT TRUE);
  PROCEDURE Write (P_Text IN VARCHAR2,
                   P_Session_ID IN NUMBER DEFAULT NULL);

  G_Debug_allowed BOOLEAN := TRUE;
  G_Session_ID    NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY PK_DEBUG IS
FUNCTION Debug_allowed RETURN BOOLEAN IS
BEGIN
  RETURN (G_Debug_allowed);
END;

FUNCTION Next_ID RETURN NUMBER IS
  V_ID NUMBER;
BEGIN
  SELECT Logging_SEQ.nextval
    INTO V_ID
    FROM DUAL;
  RETURN (V_ID);
END;

PROCEDURE Disable IS
BEGIN
  G_Debug_allowed := FALSE;
END;

PROCEDURE Enable IS
BEGIN
  G_Debug_allowed := TRUE;
END;

PROCEDURE Destroy IS
BEGIN
  Write ('----------------------stopp '
    || to_char (G_Session_ID) || '--');
  G_Session_ID := NULL;
END;

PROCEDURE Init (
  P_Debug_allowed IN BOOLEAN DEFAULT TRUE) IS
BEGIN
  G_Debug_allowed := P_Debug_allowed;
  G_Session_ID := Next_ID;
  Write ('--start ' || to_char (G_Session_ID)
    || '----------------------');
END;

PROCEDURE Write (
  P_Text       IN VARCHAR2,
  P_Session_ID IN NUMBER DEFAULT NULL) IS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  IF Debug_allowed THEN
    IF G_Session_ID IS NULL THEN
      Init;
    END IF;
    INSERT INTO Logging (ID,
      Session_ID,
      Insert_Date,
      Insert_User,
      Text)
    VALUES (Next_ID,
      NVL (P_Session_ID, G_Session_ID),
      Sysdate,
      User,
      P_Text);
    COMMIT;
  END IF;
END;
END;
/

You start a debugging-session with INIT and stop it with DESTROY. Error-Messages are logged using WRITE. For example:
pk_Debug.Init;
pk_Debug.Write ('Hello World - ' || V_Test);
pk_Debug.Destroy;

Parts of your debugging can be deactivated with DISABLE and from this point on nothing will be written into the logging-table until you start ENABLE.

The view Logging_DESC_V shows you the debugging-information, group by the newest session-id.
ID Session Insert-Date     Text
============================================
24    21   10.09.-12:38:48 -------stopp 21--
23    21   10.09.-12:38:48 Hello World - 42
22    21   10.09.-12:38:48 --start 21-------


Try it
Gerd

2 comments:

Martin D'Souza said...

Hi Gerd,

We already have a very feature rich open source logging platform for PL/SQL called Logger. Can you please list this at the top of your blog post to let people know about it? One of the goals of the project is to not duplicate logging platforms in the community. If you have any questions please email me ( at )

Martin

Gerd Volberg said...

Hi Martin,

my package is not a competitor for open source logging tools like logger. It is only a very small and easy to use utility, which you can install in less than a minute and another minute to read the documentation on my blog.

If a user needs more functionality than my write()-procedure, then he should use Open-Source like your Logger or packages from Steven Feuerstein or all the other cool utilities, out there.

But I learned over the years (and my package is 15 years old and since 8 years published through my blog) that a little utility is sometimes for customers the best solution, when they have nothing. The bigger the software is, the faster the customer refuses it.

Gerd