You are browsing the archive for Logging.

创建ADFLogger配置文件

4:00 am in Oracle 融合中间件 by aronezhang

 

 

前面的文章记录了怎么使用ADFLogger日志记录器来记录和调试业务组件,但是在ADF应用开发中,很多代码是无法通过业务组件浏览器来进行测试的,

如控制层的代码,因此就无法通过前面介绍的方法来进行调试。

 

代码中使用ADFLogger来记录日志信息后,需要做如下的配置才可以将日志信息输出到JDeveloper控制台或者日志文件:

 

1,查找logging.xml文件的路径,logging.xml文件的位置找起来稍微有点麻烦

 

如果设置了环境变量JDEV_HOME,在JDEV_HOME目录下面会有一个system<version>的文件夹,如system11.1.1.0.31.51.56

如果没有设置环境变量JDEV_HOME,在JDeveloper的安装目录下有一个sytem/system<version>的文件夹,如system/system11.1.1.0.31.51.56

在system<version>目录下的DefaultDomain\config下就有是logging.xml文件了

 

2,修改logging.xml文件内容,配置哪些java 包中的日志信息需要打印

在此文件中配置哪些java包什么级别的日志信息将被打印,如下例子:

1
 

 

<logger name="oracleseeker.demo" level="INFO"/> 代表java包oracleseeker.demo中的级别高于INFO的日志信息都将被输出

<logger name="oracleseeker.sample" level="WARNING"/> 代码java包oracleseeker.sample中级别高于WARNING的日志信息将被输出

按照上面的语法,可以将自己开发的java包添加进去,当然最简单的一种方式是开启所有java包的日志,这是一种简便的方式,但不推荐使用。

<logger name="" level="WARNING"> 这样的就是将所有包的日志都打印出来

 

如果想输出ADF标准模块中的日志信息,可以添加如下的项即可

1
 

 

 

3,添加运行配置器的JVM选项

 

运行配置器的JVM选项中添加如下的选项

-Djbo.debugoutput=adflogger -Djbo.adflogger.level=FINE

添加了这个选项之后,JDeveloper控制台中也会打印出日志信息,如果希望将日志信息输出到一个日志文件,可以配置logging.xml文件,添加 log_handler 来输出重定向,具体可以看上面给出的示例

 

 

 

ADFLogger记录日志和调试ADF业务组件

12:13 pm in Oracle 融合中间件 by aronezhang

 

Oracle ADF 11g

 

 

一、基本知识

 

下面一段是摘自域于java.util.logging JDK说明文档中关于使用日志的四个主要目标:

  1. 由最终用户和系统管理员进行问题诊断。这由简单的常见问题日志组成,可在本地解决或跟踪这些问题,如资源不足、安全失败和简单的配置错误。
  2. 由现场服务工程师进行问题诊断。现场服务工程师使用的日志信息可以相当复杂和冗长,远超过系统管理员的要求。通常,这样的信息需要特定子系统中的额外日志记录。
  3. 由开发组织进行问题诊断。在现场出现问题时,必须将捕获的日志信息返回到原开发团队以供诊断。此日志信息可能非常详细,并且相当费解。这样的信息可能包括对特定子系统进行内部执行的详细跟踪。
  4. 由开发人员进行问题诊断。Logging API 还可以用来帮助调试正在开发的应用程序。这可能包括由目标应用程序产生的日志信息,以及由低级别的库产生的日志信息。但是要注意,虽然这样使用非常合理,但是 Logging API 并不用于代替开发环境中已经存在的调试和解析工具

 

本文主要基于第四点来描述如何利用JDeveloper 11g和ADFLogger来调试ADF应用中的业务组件。ADFLogger是ADF基于Java Logging API (java.util.logging.Logger)包装的日志工具。

 

 

java.util.logging.Level类中定义了一组可用来控制日志输出的标准日志级别。日志 Level 对象是有序的,并且是通过有序的整数来指定。

在给定的级别上启用日志记录也就启用了所有较高级别的日志记录,如下面的级别中,如果启用了INFO级别,那更高级别的SEVERE和WARNING也被启用了。

 

日志按严重性由高到低的顺序提供了如下的级别

  1. SEVERE 严重的错误,导致系统中止。期望这类信息能立即显示在状态控制台上
  2. WARNING 潜在问题的级别,它是不符合预期的状态但还不至于成为“错误”,例如使用了废弃的API等等。期望这类信息能立即显示在状态控制台上
  3. INFO 运行时产生的有意义的一些信息,主要用于报告消息的目的。期望这类信息能立即显示在状态控制台上
  4. CONFIG 静态配置消息,用来输出一些系统配置信息。期望这类信息仅被写入日志文件中
  5. FINE 指示提供跟踪信息,简单输出一些跟踪信息。期望这类信息仅被写入日志文件中
  6. FINER 指示提供一条相当详细的跟踪消息。期望这类信息仅被写入日志文件中
  7. FINEST 指示提供一条最详细的跟踪消息。期望这类信息仅被写入日志文件中

 

 

二、编写代码

 

在ADF代码中根据需求记录日志信息,确保日志信息在内容上和反应问题的严重程度上的准确而且恰当,是程序员需要做好的重要任务。

如下是在一个EO的实现类AfwkModulesVlEOImpl中记录日志信息的代码:

首先是创建一个日志记录器;然后输出日志信息。

 

1
2
3
private static ADFLogger logger = ADFLogger.createADFLogger(AfwkModulesVlEOImpl.class);
logger.log(Level.INFO,&quot;select language_code, installed_flag from afwk_languages where installed_flag in ('I', 'B')&quot;);
//logger.info(&quot;select language_code, installed_flag from afwk_languages where installed_flag in ('I', 'B')&quot;);

 

代码中记录日志信息可以采取两种办法:

  1. 使用log方法,通过指定Level参数来决定日志信息反映为哪个级别的严重程度。如上面代码中logger.log方法
  2. 使用日志级别的方法,什么严重程度的级别就使用什么样的输出方法。如上面代码中被注释掉的logger.info方法就是用来输出INFO级别的日志信息

 

日志记录方法划分为 5 个主要类别:

  1. 一系列的 "log" 方法,这种方法带有日志级别、消息字符串,以及可选的一些消息字符串参数。
  2. 一系列的 "logp" 方法(即 "log precise"),其与 "log" 方法相似,但是带有显式的源类名称和方法名称。
  3. 一系列的 "logrb" 方法(即 "log with resource bundle"),其与 "logp" 方法相似,但是带有显式的在本地化日志消息中使用的资源包名称。
  4. 还有跟踪方法条目("entering" 方法)、方法返回("exiting" 方法)和抛出异常("throwing" 方法)的便捷方法。
  5. 最后,还有一系列在非常简单的情况下(如开发人员只想为给定的日志级别记录一条简单的字符串)使用的便捷方法。这些方法按标准级别名称命名("severe"、"warning"、"info" 等等),并带有单个参数,即一个消息字符串。

 

如severe级别的方法有如下:

  1. severe(java.lang.String msg)
  2. severe(java.lang.String message, java.lang.Object param)
  3. severe(java.lang.String message, java.lang.Object[] params)
  4. severe(java.lang.String sourceClass, java.lang.String sourceMethod, java.lang.String msg)
  5. severe(java.lang.String sourceClass, java.lang.String sourceMethod, java.lang.String msg, java.lang.Object param1)
  6. severe(java.lang.String sourceClass, java.lang.String sourceMethod, java.lang.String msg, java.lang.Object[] params)
  7. severe(java.lang.String message, java.lang.Throwable t)
  8. severe(java.lang.Throwable t)

 

其它的方法和方法的详细信息可以查看Java Doc

 

 

三、调试程序

 

通过应用模块(Application Module)的上下文菜单选择Run或者Debug来测试运行业务组件,并根据实际组件进行数据操作:

 

obcb_test

 

操作之后查看Log Window的输出信息:

adflogger_log_window

 

注意上图中输出的日志信息:

1,绿色的日志信息属于系统运行输出的

2,红色字体的日志信息则是在程序代码中记录的。而红色的日志中,带日期时间、包名和方法的那行是我们程序中输出日志所属的上下文信息,

而以“信息:”打头的才是真正我们代码中输出的日志信息,如红色框所框住的信息就是第二部分示例代码所输出的日志信息。

 

注意:这种方式下,Log Window窗口中只输出消息级别高于INFO的日志信息,要查看低于这个级别的日志信息,需要配置ADFLogger的logging.xml文件

 

使用ADFLogger日志工具来进行程序的调试,这样避免了在程序中使用System.out.println方法来打印信息,也可以在产品交付的时候通过系统选项来控制

什么样级别的信息需要输出,而不是将任何程序的调试信息也一并输出。

 

如果我们希望除了看到程序中的日志信息,还希望查看一下运行时的诊断信息,可以启用诊断日志来输出相关信息。

在运行配置器的JVM选项中添加:

-Djbo.debugoutput=console

 

这样日志窗口中就会打印出很详细的诊断信息,主要包括

  1. 操作系统信息
  2. Java虚拟机信息
  3. 创建BindingContext信息
  4. 装载BC4J属性
  5. 创建数据库连接信息
  6. 创建业务实体信息

 

这样的信息可以帮助我们进行一些疑难杂症的解决。

 

在Oracle ADF应该开发过程中,JDeveloper 11g开发工具提供了很多的调试方式和工具,随着后续学习的深入,将记录更多的调试方法。

 

 

EBS开发中记录日志信息

1:10 pm in Oracle EBS二次开发 by aronezhang

 

 

Oracle EBS 11i or higher

 

对于任何一个应用开发架构,提供一个灵活方便的日志消息记录机制都是必须的,Oracle EBS提供了一套完整的日志框架,它为调试、错误报告和错误提醒等提供了一个完整的机制。

我们在Oracle EBS环境中进行二次开发的时候,需要充分利用日志框架提供的功能来记录各种日志信息,方便程序的维护的调试。

 

本文主要描述在Oralce EBS环境下进行PLSQL程序开发时如何利用这套日志框架来进行日志信息的记录。

 

一、基本概念

 

1,日志的生命周期

 

记录日志:在程序代码中根据日志的级别记录日志信息

日志需求:程序产生错误或者问题,开发人员需要查看一些辅助信息

日志输出:在不更改程序的前提下,运行程序,将日志信息输出,根据日志信息定位或调试问题

清除日志:如果日志信息已使用结束,可以将其清除

 

 

2,日志的级别

 

在程序代码中,不同类型的日志信息可能表示不同严重性,开发人员也会给予不同的关注度,因此在程序中输出日志信息时需要将其分出不同的等级输出,

方便后续根据不同的需求进行必要的查看和调试

 

1-STATEMENT:很少使用这个级别来记录日志信息

2-PROCEDURE:一般在PLSQL程序中,如果希望打印一些参数值或者运行过程中的中间值都采用这个级别

3-EVENT:在PLSQL程序中很少使用

4-EXCEPTION:程序发生异常的时候,输出一些异常信息的时候使用,因此在PLSQL的Exception部分往往需要采用这个级别

5-ERROR:当发生某些可预知错误的时候使用这个级别,因此在PLSQL的Exception部分,一些可以预知的错误分支采用这个级别

6-UNEXPECTED:当发生某些不可预知错误的时候使用这个级别,因此在PLSQL的Exception部分,不可以预知的错误分支采用这个级别

 

数字越大代表问题的严重性越大,意味着这样的日志信息也越少,因此程序编码中需要根据情况输出不同级别的日志信息。

 

3,预制文件

 

Oracle EBS系统中,通过以下几个预制文件来控制是否开启日志记录、输出哪些级别的日志信息、输出哪些模块相关的日志信息等等。

 

AFLOG_ENABLED:用来指定是否开启日志记录功能,默认是NULL(不开启)

AFLOG_LEVEL:指定日志记录的级别,默认是NULL(Log.UNEXPECTED),这个值代表了日志输出的最低级别,只要是级别比它高的日志信息都将被输出

AFLOG_MODULE:指定要开启哪个模块的日志记录,默认是NULL(%,所有模块)

AFLOG_FILENAME:指定应用服务器的文件地址和名称,用来写入日志信息

 

 

二、PLSQL开发中记录日志信息的步骤

 

1,记录日志信息

 

在PLSQL代码中按照日志信息的级别输出日志信息,编写如下的PLSQL代码:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
G_MODULE_PREFIX     VARCHAR2(100) := 'cux.plsql.PACKAGE_NAME';
l_procedure_name    VARCHAR2(30):= 'PROCEDURE_NAME';
 
PROCEDURE log
(p_level   IN VARCHAR2
,p_module  IN VARCHAR2
,p_message IN VARCHAR2)
IS
BEGIN
  IF(p_level &gt;= FND_LOG.G_CURRENT_RUNTIME_LEVEL)
  THEN
  fnd_log.STRING(LOG_LEVEL =&gt; p_level
                ,MODULE    =&gt; p_module
                ,MESSAGE   =&gt; p_message
                );
  END IF;
END;
 
IF(FND_LOG.LEVEL_PROCEDURE &gt;= FND_LOG.G_CURRENT_RUNTIME_LEVEL)
THEN
  log(FND_LOG.LEVEL_PROCEDURE,G_MODULE_PREFIX || l_procedure_name, 'some logging information......');
END IF;

 

上面代码中fnd_log.string的三个参数:

  1. LOG_LEVEL:将日志信息记录为什么级别,只有开启日志级别比它高的时候才会打印出日志信息,否则不打印
  2. MODULE:将日志信息记录到哪个模块,模块的命名规范为:<模块简称>.<语言>.<包名>,如 cux.plsql.PACKAGE_NAME
  3. MESSAGE:需要输出的日志信息

 

FND_LOG.G_CURRENT_RUNTIME_LEVEL这个全局变量则是目前Oracle EBS环境启用的消息级别是多少?它的值来至于预知文件AFLOG_LEVEL的设置

 

 

2,输出日志信息

 

需要输出日志的时候,只要首先开启相关的预知文件,然后运行程序,根据设置察看日志信息即可。

 

设置相关的预制文件,设置预知文件的值最好遵循以下规则:

  1. 设置在用户层
  2. 日志级别尽量高,减少日志输出信息
  3. 指定日志输出模块,尽量少使用代表全部模块的(%)

 

曾经在我们的系统中,由于在系统层启用了所有模块的日志信息,发现第二天就将近2G的数据库空间吃光了!!!

 

如果设置了AFLOG_FILENAME,即日志信息写入的文件,那请查看文件的内容;

而如果没有没有设置日志文件路径,日志信息写入数据库表:FND_LOG_MESSAGES,而PLSQL程序最方便的方式就是将日志信息写入到数据库表中

如下的查询:

1
2
3
4
SELECT message_text
  FROM fnd_log_messages
 WHERE module LIKE 'fnd.framework.webui%'
 ORDER BY log_sequence

 

 

 

更多关于Oracle EBS 日志信息的内容可查看相关文档。