Betrifft Eigene Ausgaben direkt in ALERT.LOG und Tracefiles schreiben Autor Jens-Uwe Petersen ([email protected]) Art der Info Technische Background Info (Juli 2003) Quellen DBMS_SYSTEM - "missing" section from the PL/SQL supplied packages manual (Garry Robinson, Jens-Uwe Petersen; OraFAQ Paper) Was Sie schon immer zum Thema dbms_system wissen wollten! (Peter Jensch; Trivadis Publikation) Einleitung Immer wieder tritt der Wunsch auf, dass man gerne eigene Fehlermeldungen im ALERT.LOG der Datenbank einfügen würde, um die Meldungen zentral an einer Stelle auflaufen zu lassen, weil dort beispw. die Eskalationsmechanismen für den Fehlerfall definiert sind. Die Standardantwort von Oracle bei solchen Anfragen lautet immer, entweder eigene Logfiles mit UTL_FILE erzeugen und diese dann ebenfalls auf Fehler überwachen oder die Eskalation aus der Datenbank heraus per Mail realisieren. Es geht aber auch viel einfacher und das sogar mit Prozeduren, die Oracle bereits mitliefert, aber nicht öffentlich macht. Das Oracle-Package DBMS_SYSTEM Das Package verfügt über insgesamt 12 Prozeduren, die allesamt seit Oracle 8.0 verfügbar sind. Die für unseren Zweck benötigten 4 Prozeduren möchte ich Ihnen nun vorstellen (die anderen werden in den oben angeführten Quellen detailliert beschrieben): Prozedur Write: KSDWRT Beschreibung Schreibt Messages ins ALERT.LOG/Tracefile KSDWRT (DEST TST IN IN Parameter: 1 – Schreibe ins Tracefile 2 – Schreibe ins ALERT.LOG 3 – Schreibe in beide Message DEST TST Indent: Timestamp: KSDIND KSDDDT BINARY_INTEGER, VARCHAR2) Druckt das Zeichen ":", so oft wie in Parameter LVL übergeben. Der nächste KSDWRT-Aufruf schreibt in die gleiche Zeile. KSDIND (LVL IN BINARY_INTEGER) Parameter: [0..30] LVL Schreibt Zeitstempel ins Tracefile, wird für das ALERT.LOG nicht berücksichtigt KSDDDT Flush: KSDFLS Forciert das Schreiben des Buffers KSDFLS Berechtigungen Falls das Package noch nicht installiert sein sollte, müssen zuerst unter dem Benutzer SYS die Skripte DBMSUTIL.SQL und PRVTUTIL.PLB ausgeführt werden. Da standardmäßig für dieses Package keine Berechtigungen vergeben sind, muss für die Verwendung entweder als SYS gearbeitet werden oder selektiv privilegierten Benutzern das Execute-Recht dafür gegranted werden. Ein erster Test Nachfolgend nun eine kleine Testprozedur, die die verschiedenen Funktionen aufruft und parallel dazu die entsprechenden Ausgaben im ALERT.LOG und im Tracefile. SQL*Plus declare -- Beim ersten Aufruf einer der ksd-- Funktionen erfolgt automatisch immer -- Timestamp-Eintrag begin -- Leerzeile zu Beginn sys.dbms_system.ksdwrt(3, ' '); -- Anfangskennung sys.DBMS_System.ksdwrt(3, '- Start -'); -- Timestamp ausgeben sys.dbms_system.ksdddt; -- Erste Meldung sys.dbms_system.ksdwrt(3, 'Test Msg1'); -- Timestamp ausgeben sys.dbms_system.ksdddt; -- Einrueckungen (n-mal ":", kein CR) sys.dbms_system.ksdind(5); -- Zweite Meldung -- (in gleiche Zeile wie ksdind) sys.DBMS_System.ksdwrt(3, 'Test Msg2'); -- Timestamp ausgeben sys.dbms_system.ksdddt; -- Dritte Meldung -- (keine Einrueckung mehr) sys.dbms_system.ksdwrt(3,' Test Msg3'); -- 25-mal ":" sys.dbms_system.ksdind(25); -- Timestamp ausgeben -- (nicht mit ksdind kombinierbar) sys.dbms_system.ksdddt; -- Endekennung sys.DBMS_System.ksdwrt(3, '- Ende -'); -- Leerzeile zum Abschluss sys.DBMS_System.ksdwrt(3, ' '); end; / ALERT.LOG ORAxxxx.trc Mon Mar 10 21:23:17 2003 *** 2003-03-10 21:23:17.000 - Start - - Start *** 2003-03-10 21:23:17.000 Test Msg1 Test Msg1 *** 2003-03-10 21:23:17.000 :::::Test Msg2 :::::Test Msg2 *** 2003-03-10 21:23:17.000 Test Msg3 Test Msg3 ::::::::::::::::::::::::: *** 2003-03-10 21:23:17.000 - Ende - - Ende - In Tools zum Auswerten von ALERT.LOGs wie z.B. AlertView (www.zephyrus.com) werden die Einträge mit aufgelistet. Die Ausgaben im Tracefile finden sich nur im unformatierten Tracefile, da tkprof damit nichts anfängt, werden sie einfach überlesen. Dennoch ist es eine nützliche Möglichkeit um auf schnelle und einfache Art Debuginformationen wegzuschreiben, ohne extra Tracing an- und auszuschalten oder mit UTL_FILE eine Datei öffnen und schließen zu müssen. Beispiel Zu guter Letzt nun der in der Einleitung erwähnte Anwendungsfall. Beispielhaft wird hier jeder aufgetretene "Snapshot too old"-Fehler im ALERT.LOG mitprotokolliert. CREATE OR REPLACE TRIGGER servererror_trg AFTER SERVERERROR ON DATABASE DECLARE BEGIN -- ORA-01555: Snapshot too old / Rollback Segment too small IF ( is_servererror(1555) ) THEN sys.dbms_system.ksdwrt(2, 'User: '|| ora_login_user ||' ;' || 'IP: ' || ora_client_ip_address); FOR i IN 1..ora_server_error_depth LOOP sys.dbms_system.ksdwrt(2, ora_server_error(i) || '->' || ora_server_error_msg(i)); END LOOP; END IF; END servererror_trg; / Zusammenfassung Die Möglichkeit selber direkt ins ALERT.LOG oder in Tracefiles schreiben zu können, ist oftmals sehr nützlich. Man sollte aber darauf achten, dass die eigenen Meldungen immer klar von den Oracle-Meldungen unterschieden werden können, da ansonsten ziemliche Verwirrung gestiftet werden kann. Das dürfte vermutlich auch einer der Hauptgründe sein, warum Oracle diese Funktionalität bisher nicht öffentlich verfügbar gemacht hat. Wie immer bei undokumentierten Features gilt natürlich, dass Oracle in neueren Versionen diese Funktionalitäten ohne weitere Ankündigung ändern oder entfernen kann und außerdem die Verwendung unsupported ist und komplett auf eigenes Risiko erfolgt. Andererseits gibt es aber mehrere Beispiele von Oracle auf Metalink z.B. HOUT.SQL (Note:101468.1), in dem diese Funktionalität verwendet wird. Falls Sie gerne noch weitere praxiserprobte Tipps und Tricks kennenlernen möchten, würde es uns freuen, Sie in einem unserer Oracle-Kurse begrüßen zu dürfen. Trivadis GmbH Jens-Uwe Petersen Max-Lang-Strasse 56 70771 Leinfelden-Echterdingen Mail: [email protected] Tel: +49 711 903 63 230 Fax: +49 711 903 63 259 Internet: http://www.trivadis.com