10. August 2015

Einfaches Logging und Debugging, Version 2.0

Jede Applikation braucht eine einfache Methode um Fehler zu speichern. Die folgende Technik kann desweiteren dazu benutzt werden um Forms, Reports und PL/SQL zu debuggen. In der neuen Version 2.0 wird nun auch der Username gespeichert und der Viewname hat sich leicht geändert.

Zuerst einmal erstellen wir die Tabelle, Sequence und eine View um die Logging-Information zu speichern:
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;

Als nächstes brauchen wir ein Package mit den Prozeduren, die für das Logging benötigt werden.
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;
/

Das Debugging wird mit INIT gestartet und endet mit DESTROY. Fehlermeldungen werden in die Tabelle festgeschrieben mit WRITE. Zum Beispiel:
pk_Debug.Init;
pk_Debug.Write ('Hello World - ' || V_Test);
pk_Debug.Destroy;

Teile des Debuggings können deaktiviert werden mit DISABLE, so dass von dieser Zeile Code an keine Logging-Informationen mehr geschrieben werden, bis man ENABLE startet.

Die View Logging_DESC_V zeigt die Logging-Daten, gruppiert nach der neuesten 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-------


Viel Spass damit
Gerd

Keine Kommentare: