pl/sqlからsyslogへ出力

2009年 10月 30日

ログ出力の種類として、syslogへの出力も欲しい。作成中のログ出力プログラムは出力する対象によりオブジェクトを用意するようになっているため、syslog出力用のオブジェクトも書いてみた。

------------------------------------
-- logger_syslog_typ
-- syslog出力型
------------------------------------
CREATE OR REPLACE TYPE logger_syslog_typ UNDER logger_typ
 (
 OVERRIDING MEMBER PROCEDURE write( MSG IN logmsg_typ )
 ) NOT final;
/

CREATE OR REPLACE TYPE BODY logger_syslog_typ AS
 OVERRIDING MEMBER PROCEDURE write( MSG IN logmsg_typ ) IS
     v_job_name varchar2(100);    --JOB NAME編集用
     v_action   varchar2(1000); --外部プログラム
 BEGIN
     v_job_name := 'SYSLOG' || to_char(systimestamp,'ff6');
     v_action := cb.GET_CONFIG_VALUE('SYS_LOG_PRG');

     DBMS_SCHEDULER.CREATE_JOB (
                                                   job_name =>v_job_name,
                                                   job_type =>'EXECUTABLE',
                                                   job_action =>v_action,
                                                   number_of_arguments => 1,
                                                   auto_drop => true
                                                   );

 DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(v_job_name,1, MSG.LOG_MSG);

 DBMS_SCHEDULER.ENABLE(v_job_name);

 EXCEPTION
      WHEN OTHERS THEN
               DBMS_OUTPUT.PUT_LINE(SQLCODE);
               DBMS_OUTPUT.PUT_LINE(SQLERRM);
 END;

そもそも、PLSQLからsyslogへ出力するには外部プログラム経由で出力しなければならない。(それしか方法を知らない)

外部プログラムに出力したい内容を渡して、そのプログラムがsyslogへ出力するという流れになる。外部プログラムはloggerを使ってもいいのだが、今回は自前perlで作成した。

#!/usr/bin/perl
use Sys::Syslog qw(:DEFAULT setlogsock);
setlogsock('unix');

openlog("ORACLE", 'ndelay', 'user');
syslog(LOG_ERR, $ARGV[0]);
closelog();

ほとんど、雑プログラムのレベルだ・・・。(loggerの方が良かったかも)

pl/sqlから外部プログラムを呼び出すにはcreate_jobすれば良い訳だが、ちゃんと権限を与えておかないとエラーになる。

  • create any job システム権限
  • create external job システム権限
  • create job システム権限

これらをユーザへ与えておかないと実行時に権限が無いと怒られる。

CREATE_JOBに与えるjob_nameだが、本当は固定値で与えたいところだが、連続して呼び出された場合に、前のJOBが残っており、2回目以降のCREATE_JOBがエラーとなってしまう。そのため、timestampを使い、job_nameをユニークになるようにしている。出力先がsyslogの場合はやたらと出力せずに何か致命的なケースなどに出力する使い方を期待するとしよう。

追伸)やはり、syslogへの出力は他と比べて遅い。よって通常のログ出力オブジェクトと同列に扱うのはまずいので、syslogは特別に専用メソッドで扱うことにした方が良さそうである。

 

広告