本文的完成感谢葛严大神授权使用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. Android java 多线程(三)

  2. 20145304 刘钦令 Exp2 后门原理与实践

    20145304 刘钦令 Exp2 后门原理与实践 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 浏览网页时,或许会触发网站中隐藏的下载代码,将后门程序下载到默认地址. 下载的 ...

  3. 20145317彭垚 MSF基础应用

    20145317彭垚 MSF基础应用 基础问题回答 用自己的话解释什么是exploit,payload,encode? exploit就相当于是载具,将真正要负责攻击的代码传送到靶机中,我觉得老师上课 ...

  4. Java序列化流-ObjectOutputStream、ObjectInputStream

    Java对象流的基本概念: 实例代码: 实体类User: import java.io.Serializable; /** * @author zsh * @company wlgzs * @crea ...

  5. vs2012旗舰版 有效注册密钥

    Microsoft Visual Studio Ultimate 2012 旗舰版 有效注册密钥: YKCW6-BPFPF-BT8C9-7DCTH-QXGWC

  6. jQuery 中 $( ) 函数的用法总结

    摘要 jQuery对象: 具有jquery框架设置的所有功能的调用者, 就是该框架的对象 $又是什么?: $就是jQuery对象, jQuery对象为window的全局属性, 所以可以直接使用 如何自 ...

  7. 51nod 1083 矩阵取数问题

    就很简单很简单的dp 只能从右或者从下走 所以  dp方程直接看下面公式吧  反正也不难 #include<bits/stdc++.h> using namespace std; ; in ...

  8. js函数事件对象

    每个函数都有4个默认对象 arguments 保存着实际传入的参数,集合列表 return 有两个功能,打断函数和返回函数值 this 谁调用的函数,this就是谁 event 事件对象 事件 box ...

  9. UVa 820 因特网带宽(最大流)

    https://vjudge.net/problem/UVA-820 题意: 给出所有计算机之间的路径和路径容量后求出两个给定结点之间的流通总容量. 思路: 裸的最大流问题.注意有个比较坑的地方,最后 ...

  10. python学习站点

    1.python 外部扩展网址 http://www.lfd.uci.edu/~gohlke/pythonlibs Python Extension Packages 2.web2py学习 http: ...