Java Oracle ojdbc驱动程序未记录SQL查询参数
我已经将应用程序正确配置为记录SQL查询,但是没有显示参数值,而是显示问号(?) 我跟踪了StackOverflow中的许多问题以及官方文档,但都没有效果 我的应用程序在OpenLiberty服务器上运行Java Oracle ojdbc驱动程序未记录SQL查询参数,java,logging,parameters,ojdbc,Java,Logging,Parameters,Ojdbc,我已经将应用程序正确配置为记录SQL查询,但是没有显示参数值,而是显示问号(?) 我跟踪了StackOverflow中的许多问题以及官方文档,但都没有效果 我的应用程序在OpenLiberty服务器上运行 Driver: ojdbc6_g.jar 我的配置: com.ibm.ws.logging.trace.specification=*=audit:oracle=CONFIG oracle.jdbc.Trace=true # set levels .level=SEVERE oracle
Driver: ojdbc6_g.jar
我的配置:
com.ibm.ws.logging.trace.specification=*=audit:oracle=CONFIG
oracle.jdbc.Trace=true
# set levels
.level=SEVERE
oracle.level=INFO
oracle.jdbc.driver.level=CONFIG
oracle.sql.level=CONFIG
# configure handlers
oracle.handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=CONFIG
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
有没有办法通过使用第三方库或修改应用程序代码来查看SQL参数
有没有办法通过使用第三方库或修改应用程序代码来查看SQL参数
您必须使用oracle.jdbc.driver=FINE
修改logging.properties,因为这正是记录参数的方法
我已经将应用程序正确配置为记录SQL查询,但是没有显示参数值,而是显示问号(?)
Oracle驱动程序被编码为将参数记录为单独的日志语句。从您的问题来看,您试图解决的问题似乎是由Oracle驱动程序为参数创建多个日志记录和仅包含绑定的查询本身创建一个日志记录引起的格式问题。由于存在格式问题,日志框架要求您创建自定义格式设置程序,以将日志记录转换为您希望看到的特定输出格式
您必须创建的格式化程序的唯一新奇之处是,您需要将多个日志记录合并成一条格式良好的消息
下面是一个让您开始学习的示例:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayDeque;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
public class CoalesceFormatter extends Formatter {
private final ArrayDeque<LogRecord> records = new ArrayDeque<>();
private final Formatter target = new SimpleFormatter();
@Override
public synchronized String format(LogRecord record) {
if (records.isEmpty()) {
if (!isStart(record)) {
return target.format(record);
} else {
records.add(record);
return ""; //suppress output
}
}
if (isEnd(record)) {
LogRecord first = records.poll();
String query = this.formatMessage(first);
for (LogRecord parameter; (parameter = records.poll()) != null;) {
query = query.replaceFirst("\\?", this.formatMessage(parameter));
}
LogRecord clone = clone(first);
clone.setMessage(query);
clone.setParameters(null);
assert records.isEmpty() : records;
return this.target.format(clone);
}
if (isDelayed(record)) {
records.add(record);
return ""; //suppress output
}
//Normal record
return target.format(record);
}
private boolean isStart(LogRecord r) {
//TODO: this is the call site of preparing the query.
return "prepareStatement".equals(r.getSourceMethodName());
}
private boolean isDelayed(LogRecord r) {
//TODO: this needs more filtering
return "setParameter".equals(r.getSourceMethodName());
}
private boolean isEnd(LogRecord r) {
//TODO: fix as needed
//valueOf deals with null
return String.valueOf(r.getSourceMethodName()).startsWith("execute");
}
private LogRecord clone(LogRecord r) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(out)) {
oos.writeObject(r);
} catch(IOException ignore) {
}
try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream oos = new ObjectInputStream(in)) {
return (LogRecord) oos.readObject();
} catch(IOException | ClassNotFoundException ignore) {
}
return r;
}
}
import java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.IOException;
导入java.io.ObjectInputStream;
导入java.io.ObjectOutputStream;
导入java.util.ArrayDeque;
导入java.util.logging.Formatter;
导入java.util.logging.LogRecord;
导入java.util.logging.SimpleFormatter;
公共类合并格式化程序扩展格式化程序{
私有最终ArrayQue记录=新ArrayQue();
私有最终格式化程序目标=新的SimpleFormatter();
@凌驾
公共同步字符串格式(日志记录){
if(records.isEmpty()){
如果(!isStart(记录)){
返回target.format(记录);
}否则{
记录。添加(记录);
返回“”;//禁止输出
}
}
如果(我发送(记录)){
LogRecord first=records.poll();
字符串查询=this.formatMessage(第一个);
for(LogRecord参数;(参数=records.poll())!=null;){
query=query.replaceFirst(“\\?”,this.formatMessage(参数));
}
LogRecord clone=克隆(第一个);
clone.setMessage(查询);
clone.setParameters(null);
assert records.isEmpty():记录;
返回此.target.format(克隆);
}
如果(延迟(记录)){
记录。添加(记录);
返回“”;//禁止输出
}
//正常记录
返回target.format(记录);
}
专用布尔值isStart(日志记录r){
//TODO:这是准备查询的调用站点。
返回“prepareStatement”.equals(r.getSourceMethodName());
}
专用布尔值延迟(日志记录r){
//TODO:这需要更多的过滤
返回“setParameter”.equals(r.getSourceMethodName());
}
专用布尔isEnd(日志记录r){
//TODO:根据需要进行修复
//valueOf处理空值
返回字符串.valueOf(r.getSourceMethodName()).startsWith(“执行”);
}
专用日志记录克隆(日志记录r){
ByteArrayOutputStream out=新建ByteArrayOutputStream();
try(ObjectOutputStream oos=new ObjectOutputStream(out)){
oos.writeObject(r);
}捕获(IOException忽略){
}
try(ByteArrayInputStream in=newbytearrayinputstream(out.toByteArray());
ObjectInputStream oos=新ObjectInputStream(in)){
return(LogRecord)oos.readObject();
}捕获(IOException | ClassNotFoundException忽略){
}
返回r;
}
}
这个问题是否与以下问题相同:?我也尝试了这个选项,但结果是在整个java调用集上有很多bervose输入/输出参数。在我的场景中,这是令人困惑的,因为我使用了一个客户机框架来进行大量java调用。我希望SQL查询以内联方式显示参数,而不是问号。我也希望这样,但我认为Oracle驱动程序没有提供它。你说你不想使用第三方库——这很不幸,因为有很多库提供了你想要的东西。