Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog

LAMI DBA

Hello !

Je profite d'un cas pratique que j'ai récemment rencontré en production pour vous présenter deux méthodes permettant de générer des messages dans le fichier d'alert log d'une base de données.

En effet, comment vérifier la supervision d'une instance et particulièrement la supervision des erreurs Oracle dans l'alert.log ?

Il est possible d'attendre qu'une véritable erreur apparaisse, mais ce n'est pas vraiment très réactif..

On peut également provoquer une véritable erreur en base, mais la encore si nous sommes en production cela peut être soit impossible pour des raisons de pilotage, soit risqué en fonction de l'erreur qui aurait été générée, et de toute façon on ne joue pas sur une production..

Il reste donc la solution de générer directement des messages dans l'alert.log, et cela tombe bien car il y a deux méthodes possibles !

Bien sur, je ne parle pas ici du fichier d'alert en XML mais du bon vieux alert.log, généralement placé dans $ORACLE_BASE/diag/SID/trace.

Tout d'abord, nous pouvons utiliser la fonction bien connue "UTL_FILE" qui pourra permettre d'ajouter facilement une entrée dans l'alert.log, et nous avons ensuite la possibilité d'utiliser la procédure KSDWRT du package DBMS_SYSTEM.

Voyons voir comment faire en utilisant une petite procédure autour de UTL_FILE, en identifiant au préalable le répertoire où est stocké l'alert.log :

Note : Ma base se nomme HARLEY

 

SQL> select NAME,VALUE from v$diag_info where name ='Diag Trace';

NAME                   VALUE
----------------       ----------------
Diag Trace             /u01/app1/oracle/diag/rdbms/harley/HARLEY/trace


J'ai maintenant le PATH complet du fichier d'alert, et je vais créer un DIRECTORY dessus qui sera par la suite utilisé dans ma fonction.

 

SQL> create or replace directory DIR_ALERT as '/lun/app1/oracle/diag/rdbms/harley/HARLEY/trace';
Directory created.

SQL> declare
v_file_handle utl_file.file_type;
myalert       varchar2(4000):='alert_HARLEY.log';

begin
  v_file_handle := UTL_FILE.FOPEN('DIR_ALERT',myalert,'A');
  UTL_FILE.PUT_LINE(v_file_handle,'ORA-666 Test of UTL_FILE from MRS');
  UTL_FILE.FCLOSE(v_file_handle);
end;
/  

PL/SQL procedure successfully completed.

 

Attention à bien spécifier APPEND et non directement la valeur WRITE, sinon adieu le contenu du fichier d'alert.log.

Vérifions maintenant si mon message a bel et bien été inséré dans mon fichier d'alert.

Nous pouvons soit parcourir le fichier directement (si on y a accès, ce qui n'est pas forcément le cas dans un environnement cloud), soit en utilisant toujours UTL_FILE, ou encore en utilisant une table externe.

Avec UTL_FILE :

SQL>declare
v_file_handle utl_file.file_type;
myalert       varchar2(4000):='alert_HARLEY.log';
begin
  v_file_handle := utl_file.FOPEN('DIR_ALERT',myalert,'R');
  loop
    begin
    utl_file.GET_LINE(v_file_handle,myalert);
    dbms_output.put_line(myalert);
    EXCEPTION
        WHEN No_Data_Found
        then exit;
    end;
  end loop;
utl_file.FCLOSE(v_file_handle);
end;
/

 

En utilisant UTL_FILE, mieux vaut être sur que le fichier ne soit pas trop gros sinon le retour écran peut mettre un certain temps, ou encore le buffer ne sera pas assez taillé pour la variable "myalert".

Personnellement j'aime bien utiliser des tables externe et en plus je peux filtrer facilement sur ma ligne précédemment insérée :

SQL> create table myalert_log
(row_line varchar2(1024))
organization external
(type ORACLE_LOADER
        default directory DIR_ALERT
        access parameters (records delimited by newline
                           fields
                          (row_line char(1024)))
location ('alert_HARLEY.log')
);  

Table created.

SQL> select * from myalert_log where row_line like 'ORA-666%';

ROW_LINE
--------------------------------------------------------------------------------
ORA-666 Test of UTL_FILE from MRS


J'ai bien retrouvé ma ligne, voyons voir maintenant avec le package DBMS_SYSTEM.

pour son utilisation, rien de plus simple ! Deux paramètres sont nécessaire :

DBMS_System.ksdwrt(
n    integer,
message varchar2
);

 

N peut prendre les valeurs :

    1 - Écriture dans le fichier trace
    2 - Écriture dans l'alert.log
    3 - Écriture dans les 2 fichiers.

L'avantage de cette méthode c'est qu'il n'est pas nécessaire d'identifier le répertoire de l'alert.log, donc très pratique dans un environnement cloud.

J'utilise donc le paramètre 2 pour ajouter une entrée dans l'alert.log

SQL> exec SYS.DBMS_SYSTEM.KSDWRT(2,'ORA-888 Test of DBMS_SYSTEM.KSDWRT from MRS');

PL/SQL procedure successfully completed.


Je vérifie toujours en utilisant ma table externe :

SQL>  select * from myalert_log where row_line like 'ORA-888%';

ROW_LINE
--------------------------------------------------------------------------------
ORA-888 Test of DBMS_SYSTEM.KSDWRT from MRS


Pareil qu'avec la fonction UTL_FILE, nous retrouvons bien le message inséré !


Enjoy !

commentaires

Articles autour des SGBD Oracle, SQL Server & PostgreSQL

A propos de LAMI-DBA

Le Blog LAMI-DBA est la fusion de deux blogs existants, celui de LAurent (laodba) et celui de MIckael (dbafaq), deux DBA passionnés des sgbd, et particulièrement d'Oracle.

 

Laurent, 47 ans, Expert Oracle & MS SQL Server, Team Leader, dit "Le Taz", Certifié Expert RAC 11G, Exadata Implementation Specialist, OCA 11G, 

Profil Linkdin

 

 

 

Mickael, 37 ans, Expert Oracle, dit "Batman", Certifié Expert RAC 11G, OCP 11G, OCP 10G,

Profil Linkdin      

 

Hébergé par Overblog