PL/SQL日志记录 - 如何控制?

21

我希望在我们现有的Oracle应用程序中引入一个日志框架,来替换使用DBMS_OUTPUT。

该框架主要用于调试,包括记录开始x过程、参数详细信息、结束过程x等。它还应具有按程序单元打开或关闭功能,具有各种级别的跟踪功能,实际上是标准日志记录功能。

实现这些要求应该相对简单,但我需要你的帮助来确定如何最好地打开和关闭此功能。我的目标是在关闭跟踪时尽可能减少性能损失,这应该是大多数情况下都需要的!

由于应用程序使用10g release 2,起初我喜欢将日志机制包装在条件编译中,以便在正常运行期间甚至看不到日志框架。不幸的是,我不得不放弃这个想法,因为大多数应用程序都是使用独立的过程和函数构建的,因此打开日志功能可能会使大量代码无效。

我已经查看了几个现有的开源和其他框架/功能以获取灵感:

log4plsql (http://log4plsql.sourceforge.net/)

APC的评论here,特别是在可接受的影响下,让我感到担忧。

OraLog项目 (http://oralog.sourceforge.net)

自2007年以来没有更新

PL/VISION (here)

看起来很老,自Oracle 8i以来没有更改?

询问Tom的仪表化 (这里)

更新于2014年1月4日 Tom Kyte 现在推荐 Tyler Muth 的 Logger

如果您已经在Oracle应用程序中引入了某种形式的日志记录,我会非常感兴趣听听您的经验,包括您如何实现它以及尤其是如何控制它。


1
请问Tom的仪表链接出现了问题,能否请您修复一下? - Sathyajith Bhat
APC的评论被删除了吗?APC评论的链接在哪里? - Kuberchaun
2
Tom现在不推荐使用他以前的仪器了http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:54174245781686,所以他推荐使用https://github.com/tmuth/Logger---A-PL-SQL-Logging-Utility。 - Andrew Russell
@AndrewRussell 谢谢,我已经更新了我的问题。 - Ian Carpenter
1
@IanCarpenter Tyler Muth的日志记录器已经移动到https://github.com/OraOpenSource/Logger。 - TrojanName
显示剩余5条评论
4个回答

8

您提到舍弃条件编译的想法,因为可能会引起级联失效 - 如果您愿意触及需要记录/跟踪的 PL/SQL 源代码,则有一种类似的方法,无需重新编译即可启用。

您仍然可以向 PLSQL_CCFLAGS 添加自己选择的名称/值对,并使应用程序代码对 v$parameter 进行相对轻量级的查询,以确定是否“打开”日志记录。最简单的实现方式是一个名称/值对,但您可以将其扩展为具有不同对的特定于模块的对,以便更细粒度地打开日志记录。

[编辑] 以下是一个非常简单的示例,以回应您的评论/请求 - 显然,您希望在解析 PLSQL_CCFLAGS 字符串时变得更加复杂(以防它包含其他现有信息),或者将其封装成一个函数等:

create or replace procedure ianc_cc
is
cc_flag_val varchar2(4000);
begin 
-- need direct select grant on v_$parameter for this...
select value into cc_flag_val 
  from v$parameter where name = 'plsql_ccflags';
if (cc_flag_val = 'custom_logging:true') then
  dbms_output.put_line('custom logging is on'); 
else  
  dbms_output.put_line('custom logging is off'); 
end if;
end;
/

现在,作为一个有特权的用户可以发出ALTER SYSTEM命令:

ALTER SYSTEM set PLSQL_CCFLAGS='custom_logging:true';

通过以下命令切换回去:

ALTER SYSTEM set PLSQL_CCFLAGS='';


+1 感谢您的回复 - 有没有可能提供一个小演示来说明您的想法?我很难看到如何避免重新编译的问题。这是我一直在使用的过程(我已经为了空间原因“压缩”它):CREATE OR REPLACE PROCEDURE IANC_CC IS BEGIN $IF $$debug $THEN DBMS_OUTPUT.PUT_LINE('cc code is in place');$END DBMS_OUTPUT.PUT_LINE('normal execution');END;-- 打开 plsql 标志 alter procedure ianc_cc compile plsql_ccflags = 'debug:true' reuse settings;谢谢 Ian - Ian Carpenter
感谢您抽出时间提供示例,如果可以的话,我会更加赞同您的回答!再次感谢。 - Ian Carpenter

5

谢谢,我一直在等 Tyler 将这个放在 Github 上。 - Ian Carpenter

3
在我们的应用程序中,我们大量使用Ask Tom的debug.f工具来进行调试。我很快注意到的一件事是,“debugtab”被查询得太频繁了,以查看是否针对每个日志消息打开或关闭日志记录。我对它进行了修改,只在100条日志消息后才检查表格一次,现在它运行得非常好。
我的观点是尽量避免为每条日志消息检查一次表格,以查看是否应该输出。通常情况下,您希望在长时间运行的过程中打开日志记录功能,因此您可以这样做。在我的案例中,我决定可以等待几秒钟,直到经过100个日志调用后它才注意到已经打开了日志记录。

+1 感谢Stephen,特别是对TK仪器在实际使用中的反馈以及定制化提示。 - Ian Carpenter
嘿,@StephenODonnell,你可以提示数据库进行函数缓存,这样可以将结果缓存直到debugtab表使缓存失效。 - Andrew Russell
@AndrewRussell - 这可能是个不错的主意,我以前使用这个工具的时候没有尝试过(那已经是一段时间之前的事了),但下次我会试试看。 - Stephen ODonnell

1

设置一个上下文并添加一个名称-值对,这样不是更容易吗?您可以在debugtab表上使用触发器更改上下文中的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接