Założenia:
- Poniższy pakiet to prosta wariacja na temat Log4j stworzona jako pakiet PL/SQL..
- Do instalacji wymagane są następujące uprawnienia: CREATE TABLE, CREATE PROCEDURE, CREATE SEQUENCE
- Tabele, sekwencja i pakiet powinny znajdować się w jednym schemacie...
- Dostęp do tabeli logów powinien być read only dla osób trzecich
- Wszystkie rekordy zapisywane są w transakcjach autonomicznych - jest to rozwiązanie niewrażliwe na użyty przez użytkownika mechanizm do obsługi transakcji. Każdy zapis to osobna transakcja autonomiczna
- Pakiet ma dwie procedury – każda w pięciu wariantach. Procedury PDB_SetLevelLoging służą do ustawienia poziomu logowania (Level przyjmuje wartości od Debug po Fatal), analogicznie procedury PDB_Level… służą do zapisu informacji i ewentualnie komentarza jako parametru opcjonalnego…
- W przypadku umieszczenia procedur w sekcji obsługi wyjątków do tabeli logu zapisywany jest kod i opis błędu oraz stos wywołania łącznie z linią kodu, w której wystąpił błąd (to powinna być informacja szczególnie przydatna dla programistów).
- Kod był testowany dla Oracle w wersji 11g R2
- Logger dobrze radzi sobie z zapisywaniem logów z triggerów- instrukcje DCL w triggerach powodują błędy kompilacji
- Kod pakietu jest tak łopatologiczny, że pominę wszelki komentarz…
- Autor nie ponosi odpowiedzialności za działanie kodu, można ów kod dowolnie zmieniać i wykorzystywać do celów amatorskich i komercyjnych. Będę wdzięczny za wszelkie uwagi odnośnie poprawności, wydajności itp. ... Użytkownik za pomocą instrukcji SUBSTR może dopasować wszelkie zmienne tekstowe do wielkości pól w tabeli logów..
CREATE TABLE TBL_DICT_LOGGING_LEVEL
(
ID NUMBER(1) NOT NULL,
DESCRIPTION VARCHAR2(50 CHAR) NOT NULL
);
CREATE UNIQUE INDEX PK_DICT_LOGGING_ID ON TBL_DICT_LOGGING_LEVEL
(ID) LOGGING NOPARALLEL;
ALTER TABLE TBL_DICT_LOGGING_LEVEL ADD (
CONSTRAINT PK_DICT_LOGGING_ID
PRIMARY KEY (ID)USING INDEX );
CREATE SEQUENCE SEQ_ERROR_LOG
START WITH 1
MAXVALUE 999999999999999999999999 MINVALUE 1 NOCYCLE
CACHE 20 NOORDER;
Insert into TBL_DICT_LOGGING_LEVEL (ID, DESCRIPTION)
Values (1, 'Debug logging');
Insert into TBL_DICT_LOGGING_LEVEL(ID, DESCRIPTION)
Values (2, 'Info logging');
Insert into TBL_DICT_LOGGING_LEVEL(ID, DESCRIPTION)
Values(3, 'Warning logging');
Insert into TBL_DICT_LOGGING_LEVEL(ID, DESCRIPTION)
Values(4, 'Error logging');
Insert into TBL_DICT_LOGGING_LEVEL(ID, DESCRIPTION)
Values(5, 'Fatal logging');
COMMIT;
CREATE TABLE TBL_LOGGING
(
ID NUMBER(12) NOT NULL,
MESSAGE VARCHAR2(200 CHAR) NOT NULL,
COMMENTS VARCHAR2(200 CHAR),
OSUSER VARCHAR2(30 CHAR),
MACHINE VARCHAR2(64 CHAR),
PROGRAM VARCHAR2(64 CHAR),
ID_LOGGING_LEVEL NUMBER(1) NOT NULL,
SID NUMBER(6) NOT NULL,
ERROR_STACK VARCHAR2(4000 CHAR),
ERROR_MESSAGE VARCHAR2(1000 CHAR),
USER_NAME VARCHAR2(30 CHAR) DEFAULT USER NOT NULL,
INSERTION_DATE DATE DEFAULT SYSDATE NOT NULL
);
--
ALTER TABLE TBL_LOGGING ADD (
CONSTRAINT FK_LOOGING_ID_LOG
FOREIGN KEY (ID_LOGGING_LEVEL)
REFERENCES TBL_DICT_LOGGING_LEVEL (ID));
CREATE OR REPLACE PACKAGE PCKG_Logging IS
PROCEDURE PDB_TEST;
PROCEDURE PDB_SetDebugLogging;
PROCEDURE PDB_SetInfoLogging;
PROCEDURE PDB_SetWarningLogging;
PROCEDURE PDB_SetErrorLogging;
PROCEDURE PDB_SetFatalLogging;
PROCEDURE PDB_Debug( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2 DEFAULT NULL );
PROCEDURE PDB_Info( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2 DEFAULT NULL);
PROCEDURE PDB_Warning( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2 DEFAULT NULL);
PROCEDURE PDB_Error( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2 DEFAULT NULL);
PROCEDURE PDB_Fatal( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2 DEFAULT NULL);
---------------------------
END ;
/
CREATE OR REPLACE PACKAGE BODY PCKG_Logging IS
cn_Debug CONSTANT NUMBER(1) :=1;
cn_Info CONSTANT NUMBER(1) :=2;
cn_Warning CONSTANT NUMBER(1) :=3;
cn_Error CONSTANT NUMBER(1) :=4;
cn_Fatal CONSTANT NUMBER(1) :=5;
vn_CurrentLevel NUMBER(1);
vc_SID NUMBER;
vc_UserName TBL_LOGGING.USER_NAME%TYPE;
vc_OSUser TBL_LOGGING.osuser%TYPE;
vc_Program TBL_LOGGING.program%TYPE;
vc_Machine TBL_LOGGING.machine%TYPE;
---------------------------------------------
PROCEDURE PDB_TEST
IS
vn_A NUMBER(8);
BEGIN
vn_A := 1/0;
EXCEPTION WHEN OTHERS THEN
FOr lp IN 1..10000
LOOP
PDB_Fatal('błąd');
PDB_Error('błąd');
END LOOP;
END;
---------------------------
PROCEDURE PDB_WriteToLog( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2, pn_LoggingLevel IN NUMBER)AS PRAGMA AUTONOMOUS_TRANSACTION;
vc_Sqlerrm tbl_Logging.ERROR_MESSAGE%TYPE;
BEGIN
INSERT INTO TBL_LOGGING (
ID, MESSAGE, COMMENTS,
OSUSER, MACHINE, PROGRAM,
ID_LOGGING_LEVEL,SID,ERROR_MESSAGE,
ERROR_STACK, USER_NAME,
INSERTION_DATE)
VALUES
( SEQ_ERROR_LOG.nextval,SUBSTR(pc_Message, 1,200) , SUBSTR(pc_Comments, 1,200) ,
vc_OSUser,vc_Machine, vc_Program,
pn_LoggingLevel, vc_Sid,SUBSTR(vc_Sqlerrm,1,1000), SUBSTR(DBMS_UTILITY.format_error_backtrace, 1, 4000),
USER, SYSDATE );
COMMIT; EXCEPTION WHEN OTHERS then
ROLLBACK;
END;
--------------------------------------------------
PROCEDURE PDB_Debug( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2) IS
BEGIN
IF vn_CurrentLevel <= cn_Debug THEN
PDB_WriteToLog( pc_Message, pc_Comments, cn_Debug);
END IF;
END;
--------------------------------------------------
PROCEDURE PDB_Info( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2) IS
BEGIN
IF vn_CurrentLevel <= cn_Info THEN
PDB_WriteToLog( pc_Message, pc_Comments, cn_Info);
END IF;
END;
--------------------------------------------------
PROCEDURE PDB_Warning( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2) IS
BEGIN
IF vn_CurrentLevel <= cn_Info THEN
PDB_WriteToLog( pc_Message, pc_Comments, cn_Warning);
END IF;
END;
--------------------------------------------------
PROCEDURE PDB_Error( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2) IS
BEGIN
IF vn_CurrentLevel <= cn_Error THEN
PDB_WriteToLog( pc_Message, pc_Comments, cn_Error);
END IF;
END;
--------------------------------------------------
PROCEDURE PDB_Fatal( pc_Message IN VARCHAR2, pc_Comments IN VARCHAR2) IS
BEGIN
IF vn_CurrentLevel <= cn_Fatal THEN
PDB_WriteToLog( pc_Message, pc_Comments, cn_Fatal);
END IF;
END;
---------------------------
PROCEDURE PDB_SetDebugLogging IS
BEGIN
vn_CurrentLevel := cn_Debug;
END;
-----------------------------
PROCEDURE PDB_SetInfoLogging IS
BEGIN
vn_CurrentLevel := cn_Info;
END;
---------------------------
PROCEDURE PDB_SetWarningLogging IS
BEGIN
vn_CurrentLevel := cn_Warning;
END;
-----------------------------
PROCEDURE PDB_SetErrorLogging IS
BEGIN
vn_CurrentLevel := cn_Error;
END;
---------------------------
PROCEDURE PDB_SetFatalLogging IS
BEGIN
vn_CurrentLevel := cn_Fatal;
END;
---------------------------
BEGIN
vn_CurrentLevel := cn_Debug;
SELECT USERENV('sid') INTO vc_SID FROM DUAL;
SELECT USER, sys_context('USERENV','OS_USER'), sys_context('USERENV','MODULE'), sys_context('USERENV','TERMINAL')
INTO vc_UserName, vc_OSUser, vc_Program, vc_Machine
FROM DUAL ;
END ;
/