本文的完成感谢葛严大神授权使用LogUtil类,其次感谢Tavor大神的EBS OAF开发日志(见: EBS OAF开发中日志(Logging) )。

日志的使用是一门极大的学问,若读者有兴趣,可以自行选择阅读以下参考:

最佳日志实践(v2.0)

Java 日志管理最佳实践

Logging 最佳实践

首先,尽量不要在代码中使用System.out.println()方法直接打印日志,虽然这在开发过程中极其便捷,但是也带来了以下影响

1.大量的 sop  将产生大量的IO操作   同时在生产环境中 无法合理的控制是否需要输出

2.专门的日志框架可以合理的控制日志 实现 文件  DB 控制分片容量 Email预警等。

OAF 框架本身也提供了日志级别,同时提供了日志输出方法fnd_log.STRING和writeDiagnostics方法,但是我觉得不太好用,日志级别倒是极好用的。

参考:Logging in OAF Pages – A Technical Note!

OAF: How to add logging / debug messages in Oracle Application Framework(需翻|墙)

writeDiagnostics() method of OAF(需翻|墙)

所以,只需要开启了FND 诊断(配置文件:FND 诊断),在地址栏输入 &AFLOG_LEVEL=ERROR(或其他日志级别)

如:http://devapp.xxxxxx.com:8080/OA_HTML/OAHOMEPAGE&AFLOG_LEVEL=ERROR即可在网页下方看到输出的日志了,在网页中显示日志使用的writeDiagnostics()方法。

关于JDeveloper集成log4j可参考我的另一篇博客:(OAF)jdeveloper集成log4j并将日志输出到指定文件并写入数据库

集成Logback同理,两种方式需要的配置文件也自行百度。

LogUtil类如下

package cux.oracle.apps.cux.common.util;

import java.sql.CallableStatement;
import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.Date; import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.OAFwkConstants;
import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.server.OAEntityImpl;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;
import oracle.apps.fnd.framework.server.OAViewRowImpl;
import oracle.apps.fnd.framework.webui.OAPageContext; import oracle.jbo.ApplicationModule;
import oracle.jbo.Row;
import oracle.jbo.ViewObject; /**
* LogUtil 实现Log输出的核心逻辑,它可以在CO,AM,EO,VO中,以及
* 任何可以获得OADBTransaction的地方使用。
*
* 静态工程方法of负责初始化log的内容,内容分为类名称和详细内容,详细内容
* 可以是一个String,也可以是一个二维数组。内容经过格式化后,通过print输出。
* print方法在输出的时候,必须依靠LogContext参数,来确定输出方式和输出层次上。
*
* 对于LogContext参数,传入的是一个实现了LogContext接口的一个calss,通常,
* 对于特定的功能开发最好新建一个这样的calss,这样此功能开发的log输出就可以
* 很好地和其他log输出分离,且可以独立地控制输出方式和输出层次。
*
* Log内容包含三种信息:类名称,必须具有。方法名称和变量的值,非必须。
*
* GEYAN 2010-01-06
*/ /**
* 2010-06-05 改进建议:
* 是否命令行输出,可通过 isDeveloperMode;诊断输出也没有必要依靠一个开关,因为它本身就具有开关。
* 因而完全可以将 LogUtil 和 LogContext 构成的手柄模式合并为单类,或者至少可以进一步简化。
*/ /**
* 2010-06-08
* 新的版本不再依赖 LogContext ,代之以 logLevel 默认值,以及可以改变此默认值的 Builder 模式实现。
* 而输出开关则依赖Oracle本身的机制,isDeveloperMode 和 isLoggingEnabled ,
* 这样更加合理,且不会影响性能。
*
*/
public class LogUtil
{ private String[][] output = new String[1][2];
private String className; //private final static org.slf4j.Logger logger = LoggerFactory.getLogger(LogUtil.class.getName()); /**
* 输出层次定义, logLevel,
* 是 oracle.apps.fnd.framework.OAFwkConstants 的六个常量, 值依次从1到6.
* OAFwkConstants.STATEMENT
* OAFwkConstants.PROCEDURE
* OAFwkConstants.EVENT
* OAFwkConstants.EXCEPTION
* OAFwkConstants.ERROR
* OAFwkConstants.UNEXPECTED
*
* 系统中默认的是 OAFwkConstants.UNEXPECTED,故默认层次不能选择UNEXPECTED。
*
* 这里默认为 OAFwkConstants.ERROR,通过logLevel方法来更改其所需的值。
*
* &aflog_level=ERROR
*/
private int logLevel = OAFwkConstants.ERROR; private LogUtil(String str,
Object object)
{
output = new String[1][2];
output[0][0] = str; this.className = getClassName(object);
} private LogUtil(String[][] stra,
Object object)
{
output = new String[stra.length][2];
System.arraycopy(stra, 0, output, 0, output.length); this.className = getClassName(object);
} public LogUtil logLevel(int logLevel)
{
this.logLevel = logLevel;
return this;
} /**
* object的作用是得到类的名称,它可以是this指针,也可以是String形式的类名称。
*
* 通常object的参数的值是this,通过this.getClass().getName()来获取类名称。
* 但是在static方法里,this指针不可用,只有以String形式传入类名称。
*/
private static String getClassName(Object object)
{
if (java.lang.String.class.equals(object.getClass()))
{
return object.toString();
}
return object.getClass().getName();
} /**
* 两个静态工厂方法of,分别构造单个字符串和二维字符串数组类型的 LogUtil 实例。
*
* object参数应该传入当前调用所在的类的this指针,通过this得到类名称。
* 在static方法中,则以String形式传入类名称。
*/
public static LogUtil of(String str,
Object object)
{
return new LogUtil(str, object);
} public static LogUtil of(String[][] stra,
Object object)
{
return new LogUtil(stra, object);
} private String getCurrentTime()
{
Date currentTime = new Date(System.currentTimeMillis());
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(currentTime);
} private String getOutput()
{
// String result =
// "\n-------------------------------------------------> log : [" + getCurrentTime() + "]\n";
//
// result = result + " & " + "class" + " is " + "[" + className + "]\n";
//
// if (output.length == 1 && (output[0][1] == null || "".equals(output[0][1])))
// {
// return result + " " + output[0][0] + "\n";
// }
//
// for (int i = 0; i < output.length; i++)
// {
// if (output[i] != null)
// {
// result = result + " & " + output[i][0] + " is " + output[i][1] + "\n";
// }
// }
//
// return result;
StringBuffer result = new StringBuffer();
result.append("\n-------------------------------------------------> log : ["
+ getCurrentTime() + "]\n"); result.append(" & " + "class" + " is " + "[" + className + "]\n"); //等价
// StackTraceElement[] trace = new Throwable().getStackTrace();
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int len=0; len<trace.length; len++){
// trace的长度为从函数入口到print方法执行过的函数层数
// 下标为0的元素是上一行语句的信息, 下标为1的才是调用print的地方的信息
StackTraceElement tmp = trace[len]; if(tmp.getClassName().length()>=6 && "oracle".equals(tmp.getClassName().substring(0,6)))
//函数的入口为java.lang.Thread.run
//中间的层次结构太长
//故循环到标准方法即停止,仅显示客户化调用
break; result.append(" & "+ tmp.getClassName() + "." + tmp.getMethodName()
+ "(" + tmp.getFileName() + ":" + tmp.getLineNumber() + ")\n" );
} if (output.length == 1 && (output[0][1] == null || "".equals(output[0][1]))) {
return result + " " + output[0][0] + "\n";
} for (int i = 0; i < output.length; i++) {
if (output[i] != null) {
result.append(" & " + output[i][0] + " is "
+ output[i][1] + "\n");
}
} return result.toString(); } // /**
// * 2010-06-08
// * 不再推荐以下的委托LogContext对象的几个版本,推荐使用不带LogContext的版本。
// *
// * 提供在CO,AM,VO,EO,中常用的版本,和一个通用版本OADBTransaction tsn。
// *
// * */
// public void print(OAPageContext pageContext, LogContext logContext)
// {
// String output = getOutput();
//
// if(logContext.isCommandLineLog())
// {
// System.out.print(output);
// }
//
// if(logContext.isDiagnosticLog())
// {
// if(pageContext.isLoggingEnabled(logContext.getLogLevel()))
// {
// pageContext.writeDiagnostics(this.className, output, logContext.getLogLevel());
// }
// }
//
// }
//
// public void print(OADBTransaction tsn, LogContext logContext)
// {
// String output = getOutput();
//
// if (logContext.isCommandLineLog())
// {
// System.out.print(output);
// }
//
// if(logContext.isDiagnosticLog())
// {
// if(tsn.isLoggingEnabled(logContext.getLogLevel()))
// {
// tsn.writeDiagnostics(this.className, output, logContext.getLogLevel());
// }
// }
//
// }
//
// public void print(OAApplicationModule am, LogContext logContext)
// {
// OADBTransaction tsn = am.getOADBTransaction();
// print(tsn, logContext);
// }
//
// public void print(OAViewObjectImpl vo, LogContext logContext)
// {
// OADBTransaction tsn = (OADBTransaction)vo.getDBTransaction();
// print(tsn, logContext);
// }
//
// public void print(OAViewRowImpl voRow, LogContext logContext)
// {
// OAViewObjectImpl vo = (OAViewObjectImpl)voRow.getViewObject();
// OADBTransaction tsn = (OADBTransaction)vo.getDBTransaction();
// print(tsn, logContext);
// }
//
// public void print(OAEntityImpl eo, LogContext logContext)
// {
// OADBTransaction tsn = (OADBTransaction)eo.getDBTransaction();
// print(tsn, logContext);
// } /**
* 2010-06-08 推荐使用以下几个不带LogContext的版本。
*
* 提供在 CO,AM,VO,EO,中常用的版本,和一个通用版本 OADBTransaction tsn。
*/
public void print(OAPageContext pageContext)
{
OADBTransaction tsn = pageContext.getRootApplicationModule().getOADBTransaction();
print(tsn);
} public void print(OADBTransaction tsn)
{
String output = getOutput(); //开发者模式
if (tsn.isDeveloperMode())
{ System.out.print(output); //Update By hongbo
//不再使用System.out.print方法,代之以LogBack
// logger.info(className);
//System.out.println("className is "+className);
// logger.info(output); // org.slf4j.Logger log = LoggerFactory.getLogger(className);
// log.info(output);
//End } if (tsn.isLoggingEnabled(this.logLevel))
{
tsn.writeDiagnostics(this.className, output, this.logLevel);
cux_log_messages(tsn, output); }
//Add By hongbo,20160525
//此处使用集成slf4j实现日志输出,具体实现可自行百度
//将Logback或者log4j相关jar包引入工程目录 (服务器放入$JAVA_TOP目录)
//并配置相关配置文件logback.xml或log4j.propertites 放入工程根目录,即myprojects目录
// org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(className);
// log.info(output);
//此处直接使用log4j实现日志输出
// org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(className);
// logger.info(output);
//End // /*
// * 通过配置文件 CUX_LOG_MESSAGES_FILE,取得log文件的全路径。
// * 例如 /usr/tmp/user_log_temp.log,再将日志写入此文件。
// */
// String logFile = tsn.getProfile("CUX_LOG_MESSAGES_FILE");
// if (logFile != null && !"".equals(logFile))
// {
// FileUtil.write(logFile, getOutput());
// } } private void cux_log_messages(OADBTransaction tsn,
String output)
{
try
{
//cux_common_util_pkg各位自己去实现,此处就不罗列了
String sql =
"begin cux_common_util_pkg.cux_log_messages(p_log_sequence => :1,\n" + " p_module => :2,\n" +
" p_log_level => :3,\n" +
" p_message_text => :4); end;"; CallableStatement cs = tsn.createCallableStatement(sql, 1);
cs.setLong(1, System.currentTimeMillis());
cs.setString(2, this.className);
cs.setInt(3, this.logLevel);
cs.setString(4, output);
cs.execute();
cs.close();
}
catch (SQLException e)
{
throw OAException.wrapperException(e);
}
} public void print(ApplicationModule am)
{
OADBTransaction tsn = (OADBTransaction) am.getTransaction();
print(tsn);
} public void print(ViewObject vo)
{
OADBTransaction tsn = (OADBTransaction) ((OAViewObjectImpl) vo).getDBTransaction();
print(tsn);
} public void print(Row row)
{
OAViewObjectImpl vo = (OAViewObjectImpl) ((OAViewRowImpl) row).getViewObject();
OADBTransaction tsn = (OADBTransaction) vo.getDBTransaction();
print(tsn);
} public void print(OAEntityImpl eo)
{
OADBTransaction tsn = (OADBTransaction) eo.getDBTransaction();
print(tsn);
} public void printScreen(OAPageContext pageContext) {
OADBTransaction tsn =
pageContext.getRootApplicationModule().getOADBTransaction();
printScreen(tsn);
} public void printScreen(ApplicationModule am) {
OADBTransaction tsn = (OADBTransaction)am.getTransaction();
printScreen(tsn);
} public void printScreen(OADBTransaction tsn) {
String output = getOutput(); if (tsn.isDeveloperMode()) {
System.out.print(output);
} if (tsn.isLoggingEnabled(this.logLevel)) {
tsn.writeDiagnostics(this.className, output, this.logLevel);
}
}
}

调用方法如下:

CO中LogUtil.of(stringContent or String[][] , this ).print(pageContext);

其他如EO,AM,VO等直接LogUtil.of(String or String[][], this).print(this);

网页显示日志在开启诊断之后在地址栏后加入 &aflog_level=error(日志级别自定义)即可。

VO对象常用类:ModelUtil

package cuxA.oracle.apps.cux.common.util;

import java.sql.SQLException;

import oracle.apps.fnd.common.MessageToken;
import oracle.apps.fnd.framework.OAApplicationModule;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.OANLSServices;
import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;
import oracle.apps.fnd.framework.webui.OAPageContext; import oracle.jbo.ApplicationModule;
import oracle.jbo.Row;
import oracle.jbo.ViewLink;
import oracle.jbo.ViewObject; /**
* 提供mvc之Model端的常用工具。
*
* geyan 2010-01-06
*/
public class ModelUtil {
private ModelUtil() {
} public static final String CLASS_NAME =
"com.ncgc.oracle.apps.cux.por.util.ModelUtil"; /**
* 以一种简短的方式获得 OANLSServices,进而获得OANLSServices提供的一系列服务。
*/
public static OANLSServices getNls(OAApplicationModule am) {
return am.getOADBTransaction().getOANLSServices();
} public static OANLSServices getNls(OADBTransaction tsn) {
return tsn.getOANLSServices();
} public static oracle.jbo.domain.Number stringToNumber(String str) {
try {
return new oracle.jbo.domain.Number(str);
} catch (SQLException e) {
throw OAException.wrapperException(e);
}
} public static void clearVoCache(ViewObject vo) {
vo.clearCache();
vo.setMaxFetchSize(-1);
vo.setWhereClauseParams(null);
vo.setWhereClause("1=2");
vo.executeQuery();
} public static void clearVoCache(ApplicationModule am, String voName) {
ViewObject vo = findVo(am, voName);
clearVoCache(vo);
} public static ApplicationModule getChildAm(ApplicationModule parentAm,
String childAmName) {
String[] amNames = parentAm.getApplicationModuleNames();
for (int i = 0; i < amNames.length; i++) {
if (amNames[i].endsWith(childAmName)) {
return parentAm.findApplicationModule(amNames[i]);
} else {
ApplicationModule childAm =
parentAm.findApplicationModule(amNames[i]);
ApplicationModule am = getChildAm(childAm, childAmName);
if (am != null) {
return am;
}
}
} return null;
} public static ApplicationModule getChildAm(OAPageContext pageContext,
String childAmName) {
ApplicationModule parentAm = pageContext.getRootApplicationModule();
return ModelUtil.getChildAm(parentAm, childAmName);
} public static ViewObject findVo(ApplicationModule am, String voName) {
ViewObject vo = am.findViewObject(voName); if (vo == null) {
MessageToken[] errTokens =
{ new MessageToken("OBJECT_NAME", voName), };
throw new OAException("AK", "FWK_TBX_OBJECT_NOT_FOUND", errTokens);
} return vo;
} public static ApplicationModule findAm(ApplicationModule parentAm,
String amName) {
ApplicationModule am = parentAm.findApplicationModule(amName); if (am == null) {
MessageToken[] errTokens =
{ new MessageToken("OBJECT_NAME", amName), };
throw new OAException("AK", "FWK_TBX_OBJECT_NOT_FOUND", errTokens);
} return am;
} /**
* 此方法返回 vo 当前 fetch 的所有行。
*/
public static Row[] getVoFetchedRows(ApplicationModule am, String voName) {
ViewObject vo = findVo(am, voName);
return getVoFetchedRows(vo);
} public static Row[] getVoFetchedRows(ViewObject vo) {
String[][] stra =
{ { "method", "getVoFetchedRows" }, { "vo.getName()", vo.getName() },
{ "vo.isExecuted()", vo.isExecuted() + "" },
{ "vo.getFetchedRowCount()", vo.getFetchedRowCount() + "" }, };
LogUtil.of(stra, CLASS_NAME).print(vo); if (!vo.isExecuted()) {
return new Row[0];
} vo.setRangeStart(0);
vo.setRangeSize(-1); return vo.getAllRowsInRange() != null ? vo.getAllRowsInRange() :
new Row[0];
} /**
* 通过 attributeValue 删除Vo当前Fetch到的行,一行或多行。
*/
public static void removeVoFetchedRow(ViewObject vo, String attributeName,
String attributeValue) {
Row[] rows = getVoFetchedRows(vo); String[][] stra =
{ { "method", "removeVoFetchedRow" }, { "attributeName",
attributeName },
{ "attributeValue", attributeValue },
{ "rows.length", rows.length + "" }, };
LogUtil.of(stra, CLASS_NAME).print(vo); for (int i = 0; i < rows.length; i++) {
String value$row = rows[i].getAttribute(attributeName).toString();
if (value$row.equals(attributeValue)) {
rows[i].remove();
}
}
} public static void removeVoFetchedRow(ApplicationModule am, String voName,
String pkAttributeName,
String pkValue) {
ViewObject vo = findVo(am, voName);
removeVoFetchedRow(vo, pkAttributeName, pkValue);
} /**
* 返回 "多选框"选择的行。
* 此方法简化了"未选择行","返回行为空"的处理。
*/
public static Row[] getVoFilteredRows(ApplicationModule am, String voName,
String attribute) {
ViewObject vo = findVo(am, voName);
return getVoFilteredRows(vo, attribute);
} /**
* 返回 "多选框"选择的行。
* 此方法简化了"未选择行","返回行为空"的处理。
*/
public static Row[] getFilteredRows(OAApplicationModule am, String voName,
String attribute) {
ViewObject vo = findVo(am, voName); // 若vo尚无任何行,则返回 0长度数组
vo.reset();
if (!vo.hasNext()) {
return new Row[0];
} Row[] rows = vo.getFilteredRows(attribute, "Y"); return rows != null && rows.length > 0 ? rows : new Row[0];
} public static Row[] getVoFilteredRows(ViewObject vo, String attribute) {
// 若vo尚无任何行,则返回 0长度数组
vo.reset();
if (!vo.hasNext()) {
return new Row[0];
} Row[] rows = vo.getFilteredRows(attribute, "Y"); return rows != null && rows.length > 0 ? rows : new Row[0];
} public static Row getVoFirstFilteredRow(ApplicationModule am,
String voName, String attribute) {
OAViewObjectImpl vo = (OAViewObjectImpl)findVo(am, voName);
return getVoFirstFilteredRow(vo, attribute);
} public static Row getVoFirstFilteredRow(OAViewObjectImpl vo,
String attribute) {
return vo.getFirstFilteredRow(attribute, "Y");
} /**
* remove当前am中的一个vo。
*/
public static void removeVo(ApplicationModule am, String voName) {
ViewObject vo = findVo(am, voName);
vo.remove();
} /**
* 返回"下一个"序号,给定当前VO和其序号所在的列,返回现有列最大值加1的数字。
*/
public static Integer getNextSeqNum(ViewObject vo, String attributeName) {
Row[] rows = getVoFetchedRows(vo);
if (rows == null || rows.length == 0) {
return 1;
} // 否则,依次比较并返回 "最大值 + 1"
int result = 0;
for (int i = 0; i < rows.length; i++) {
Object seqNum$row = rows[i].getAttribute(attributeName);
if (seqNum$row == null) {
continue;
} int seqNumRowInt = Integer.valueOf(seqNum$row.toString());
result = seqNumRowInt > result ? seqNumRowInt : result;
} return result + 1;
} public static Integer getNextSeqNum(ApplicationModule am, String voName,
String attributeName) {
ViewObject vo = ModelUtil.findVo(am, voName);
return getNextSeqNum(vo, attributeName);
} public static void commit(OAApplicationModule am, boolean isClearEoCache) {
OADBTransaction tsn = am.getOADBTransaction();
commit(tsn, isClearEoCache);
} public static void commit(OADBTransaction tsn, boolean isClearEoCache) {
boolean isClearCacheOnCommit = tsn.isClearCacheOnCommit(); // ClearCacheOnCommit
tsn.setClearCacheOnCommit(isClearEoCache);
try {
tsn.commit();
} catch (OAException e) {
throw e;
} // 恢复原先设置
tsn.setClearCacheOnCommit(isClearCacheOnCommit);
} public static void rollback(OAApplicationModule am,
boolean isClearEoCache) {
OADBTransaction tsn = am.getOADBTransaction();
rollback(tsn, isClearEoCache);
} public static void rollback(OADBTransaction tsn, boolean isClearEoCache) {
boolean isClearCacheOnRollback = tsn.isClearCacheOnRollback(); // ClearCacheOnRollback
tsn.setClearCacheOnRollback(isClearEoCache);
if (tsn.isDirty()) {
tsn.rollback();
} // 恢复原先设置
tsn.setClearCacheOnRollback(isClearCacheOnRollback);
} public static ViewObject createVo(ApplicationModule am, String voName,
String voDefine) {
ViewObject vo = am.findViewObject(voName);
if (vo != null) {
return vo;
} return am.createViewObject(voName, voDefine);
} public static Object[] getVoWhereClauseParams(ViewObject vo) {
Object[] objects = vo.getWhereClauseParams();
if (objects == null) {
return null;
} Object[] result = new Object[objects.length];
for (int i = 0; i < objects.length; i++) {
if (objects[i].getClass().isArray()) {
Object[] params = (Object[])objects[i];
Object param$index = params[0];
Object param$value = params[1]; result[i] = param$value;
} else {
Object param$value = objects[i]; result[i] = param$value;
}
} return result;
} public static void outputVo(ViewObject vo) {
String[][] stra =
{ { "method", "outputVo" }, { "vo.getName()", vo.getName() },
{ "vo.getFullName()", vo.getFullName() },
{ "vo.getDefFullName()", vo.getDefFullName() },
{ "vo.isExecuted()", vo.isExecuted() + "" },
{ "vo.getRangeSize()", vo.getRangeSize() + "" },
{ "vo.getRangeStart()", vo.getRangeStart() + "" },
{ "vo.getFetchedRowCount()", vo.getFetchedRowCount() + "" },
{ "vo.getCurrentRowIndex()", vo.getCurrentRowIndex() + "" },
{ "vo.getMaxFetchSize()", vo.getMaxFetchSize() + "" },
{ "vo.getWhereClause()", vo.getWhereClause() },
{ "getVoWhereClauseParams(vo)",
arrayToString(getVoWhereClauseParams(vo)) },
{ "vo.getOrderByClause()", vo.getOrderByClause() },
{ "vo.getQuery()", vo.getQuery() }, };
LogUtil.of(stra, CLASS_NAME).print(vo);
} public static void outputVo(ApplicationModule am, String voName) {
ViewObject vo = ModelUtil.findVo(am, voName);
outputVo(vo);
} public static String arrayToString(Object[] arrary) {
if (arrary == null || arrary.length == 0) {
return null;
} String result = "";
for (int i = 0; i < arrary.length; i++) {
result = result + arrary[i] + " , ";
} return " [ " + result + " ] ";
} public static void displayModels(ApplicationModule am) {
String[] ams = am.getApplicationModuleNames();
for (int i = 0; i < ams.length; i++) {
ApplicationModule am$i = am.findApplicationModule(ams[i]);
String[][] stra =
{ { "method", "displayModels" }, { "for", i + " --> display ApplicationModule" },
{ "parent AM", am.getFullName() },
{ "child AM Name", am$i.getName() },
{ "child AM FullName", am$i.getFullName() },
{ "child AM DefFullName", am$i.getDefFullName() }, };
LogUtil.of(stra, CLASS_NAME).print(am);
} String[] vos = am.getViewObjectNames();
for (int i = 0; i < vos.length; i++) {
ViewObject vo$i = am.findViewObject(vos[i]);
String[][] stra =
{ { "method", "displayModels" }, { "for", i + " --> display ViewObject" },
{ "parent AM", am.getFullName() },
{ "child VO Name", vo$i.getName() },
{ "child VO FullName", vo$i.getFullName() },
{ "child VO DefFullName", vo$i.getDefFullName() }, };
LogUtil.of(stra, CLASS_NAME).print(am);
} String[] vls = am.getViewLinkNames();
for (int i = 0; i < vls.length; i++) {
ViewLink vl$i = am.findViewLink(vls[i]);
String[][] stra =
{ { "method", "displayModels" }, { "for", i + " --> display ViewLink" },
{ "parent AM", am.getFullName() },
{ "child VL Name", vl$i.getName() },
{ "child VL FullName", vl$i.getFullName() },
{ "child VL DefFullName", vl$i.getDefFullName() }, };
LogUtil.of(stra, CLASS_NAME).print(am);
} for (int i = 0; i < ams.length; i++) {
displayModels(am.findApplicationModule(ams[i]));
}
} }

输出VO对象信息:ModelUtil.outputVo(voInstance);

OAF日志使用总结的更多相关文章

  1. (OAF)jdeveloper集成log4j并将日志输出到指定文件并写入数据库

    参考: How to configure Log4j in JDev 11g Ever wanted to use log4j in your adf project ? Well though Or ...

  2. .NetCore中的日志(2)集成第三方日志工具

    .NetCore中的日志(2)集成第三方日志工具 0x00 在.NetCore的Logging组件中集成NLog 上一篇讨论了.NetCore中日志框架的结构,这一篇讨论一下.NetCore的Logg ...

  3. .NetCore中的日志(1)日志组件解析

    .NetCore中的日志(1)日志组件解析 0x00 问题的产生 日志记录功能在开发中很常用,可以记录程序运行的细节,也可以记录用户的行为.在之前开发时我一般都是用自己写的小工具来记录日志,输出目标包 ...

  4. Logstash实践: 分布式系统的日志监控

    文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...

  5. SQLServer事务同步下如何收缩日志

    事务同步是SQLServer做读写分离的一种常用的方式. 随着业务数据的不断增长,数据库积攒了大量的日志,为了腾出硬盘空间,需要对数据库日志进行清理 订阅数据库的日志清理 因为订阅数据库所有的数据都来 ...

  6. 如何正确使用日志Log

    title: 如何正确使用日志Log date: 2015-01-08 12:54:46 categories: [Python] tags: [Python,log] --- 文章首发地址:http ...

  7. 前端学HTTP之日志记录

    前面的话 几乎所有的服务器和代理都会记录下它们所处理的HTTP事务摘要.这么做出于一系列的原因:跟踪使用情况.安全性.计费.错误检测等等.本文将谥介绍日志记录 记录内容 大多数情况下,日志的记录出于两 ...

  8. ASP.NET Core应用中如何记录和查看日志

    日志记录不仅对于我们开发的应用,还是对于ASP.NET Core框架功能都是一项非常重要的功能特性.我们知道ASP.NET Core使用的是一个极具扩展性的日志系统,该系统由Logger.Logger ...

  9. .NET Core的日志[5]:利用TraceSource写日志

    从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...

随机推荐

  1. Jquery 数组与字符串之间的转换

    var auth_list = []; $("input[name='auth_list']:checkbox").each(function () { if ($(this).a ...

  2. bzoj1649 / P2854 [USACO06DEC]牛的过山车Cow Roller Coaster

    P2854 [USACO06DEC]牛的过山车Cow Roller Coaster dp 对铁轨按左端点排个序,蓝后就是普通的二维dp了. 设$d[i][j]$为当前位置$i$,成本为$j$的最小花费 ...

  3. 获取Json字符串中的key和value

    获取Json字符串中的key和value 在web项目中经常会用到json数据(如:struts2处理请求返回json数据给jsp解析),因此,JSONObject对象是必备的,这时就需要引入相关的j ...

  4. codevs 1423 骑士 - Tarjan - 动态规划

    题目描述 Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵 ...

  5. Duilib Edit编辑框禁止输入中文的方法

    转载:http://www.myexception.cn/vc-mfc/300749.html 编辑框是供用户输入的,但有时候我们要限制用户输入的内容,比如我们不让用户输入中文,只能输入字符和数字,因 ...

  6. VC 线程池

    参照:http://www.cnblogs.com/kzloser/archive/2013/03/11/2909221.html 参照:http://blog.csdn.net/pjchen/art ...

  7. HDU 6171 Admiral(双向BFS+队列)题解

    思路: 最大步骤有20,直接BFS会超时. 因为知道开始情况和结果所以可以用双向BFS,每个BFS规定最大步骤为10,这样相加肯定小于20.这里要保存每个状态搜索到的最小步骤,用Hash储存.当发现现 ...

  8. (转)Spring Boot(一)

    (二期)4.springboot的综合讲解 [课程四]springbo...概念.xmind64.5KB [课程四]spring装配方式.xmind0.2MB [课程四预习]spri...解读.xmi ...

  9. CSS3 常用选择器

    p:last-of-type{background-color: red;} 选择p中最后一项 p:nth-of-type(2n){background-color: red;} 隔行变色里面也可以填 ...

  10. WebForm、MVC、流式计算

    11月.NET技术讨论会圆满结束,会议纪要及相关文档如下如下:  1.WebForm预编译演示 文档:http://gitlab.light.fang.com/kongguDonet.Demo/Pre ...