views:

63

answers:

3

Hi,

I am Kanagaraj. In our stored procedure, we are logging messages at 500 places and logs are stored in a table where we are having some performance issues. We need to split these messages into Debug, Info and Error messages. Based on the level, only limited messages should be logged. If necessary, we will be enabling the next level and see the more logs. What could be the effective way for introducing this level based logging in our procedure?.

Thanks in advance.

Kanagaraj.

+3  A: 

Something like this...

create or replace package logger as
  min_level number := 2;
  procedure ins_log(level number, message varchar2);
end;

create or replace package body logger as
  procedure ins_log(level number, message varchar2) is
    pragma autonomous_transaction;
  begin
    if level>=min_level then
      insert into loggin(ts, msg) values (sysdate, message);
    end if;
    commit; // autonomous_transaction requires that
  end;
end;

EDIT: Added pragma autonomous_transaction;, thanks Adam

ammoQ
Plus a procedure to adjust `min_level`. You could also have separate procedures for the different levels, so you'd call `logger.info(message)` etc. which would mean you didn't need to know the level values in the calling code.
Alex Poole
Alex: To make it as simple as possible, I've just made min_level public visible. A real-life implementation would be much more like the thing you are describing.
ammoQ
If you change the value of min_level, you have to recompile the package spec, which will cause all sessions that have already called ins_log to get ORA-04061. An option to consider is to store min_level in a context.
Jeffrey Kemp
or you just call begin logger.min_level := 4; end;
ammoQ
@ammoQ I missed you could just do that, for some reason read it as defined in the body. Understood it was a simple example though, just wanted to give a fairly straightforward extension (without stealing your thunder by making it a separate answer *8-)
Alex Poole
a logger or auditor procedure should use autonomous transactions; otherwise an rollback will eliminate the log records written.
Adam Musch
Good point, Adam.
ammoQ
If you use a global variable to hold the min_level value, that value will be held in each session until it is changed in that session (definitely a problem for session pooling). To get around this, use a system context instead. When a context is changed it is instantly visible across all sessions.
Allan
+1  A: 

There is a port of log4j for Oracle PL/SQL that can be found on sourceforge. This allows logging to be enabled/disabled at various levels, and for specific packages/functions/procedures simply be modifying a configuration. It also supports redirection to different destinations.

Mark Baker
A: 

Hi There

Check out PLJ-Logger at https://sourceforge.net/p/plj-logger/home/. Its really easy to implement and has your desired functionality and a lot more. Proper logging built into PL/SQL code will transform it.

P

pj