仅显示有效的SQL字符串P6Spy

时间:2013-07-22 13:45:51

标签: sql p6spy

我正在使用p6spy来记录我的程序生成的sql语句。输出的spy.log文件的格式如下所示:

current time|execution time|category|statement SQL String|effective SQL string

我只是想知道是否有人知道是否有办法改变spy.properties文件并且只有最后一列,即有效的SQL字符串,输出到spy.log文件?我查看了属性文件,但没有发现任何似乎支持这一点。

谢谢!

5 个答案:

答案 0 :(得分:13)

在spy.properties中有一个名为logMessageFormat的属性,您可以将其设置为MessageFormattingStrategy的自定义实现。这适用于任何类型的记录器(即文件,slf4j等)。

E.g。

logMessageFormat=my.custom.PrettySqlFormat

使用Hibernate的漂亮SQL格式化程序的示例:

package my.custom;

import org.hibernate.jdbc.util.BasicFormatterImpl;
import org.hibernate.jdbc.util.Formatter;

import com.p6spy.engine.spy.appender.MessageFormattingStrategy;

public class PrettySqlFormat implements MessageFormattingStrategy {

    private final Formatter formatter = new BasicFormatterImpl();

    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql) {
        return formatter.format(sql); 
    }

}

答案 1 :(得分:1)

目前还没有提供通过配置实现此选项的选项。我认为你在这里有 2个选项

对于后面的选项,我相信你可以通过你自己的类来实现它(取决于你使用的记录器,让我们假设你使用Log4jLogger)。

好吧,如果您检查Log4jLogger github以及sourceforge版本的相关部分,您的实现应该相当简单:

spy.properties:

appender=com.EffectiveSQLLog4jLogger

实施本身可能如下所示:

package com;

import com.p6spy.engine.logging.appender.Log4jLogger;

public class EffectiveSQLLog4jLogger extends Log4jLogger {

  public void logText(String text) {
    super.logText(getEffectiveSQL(text));
  }

  private String getEffectiveSQL(String text) {
    if (null == text) {
      return null;
    }

    final int idx = text.lastIndexOf("|");

    // non-perfect detection of the exception logged case
    if (-1 == idx) {
      return text;
    }

    return text.substring(idx + 1); // not sure about + 1, but check and see :)
  }
}

请注意,实施应该包括github(新项目主页,尚未发布的版本)以及sourceforge(原始项目主页,发布1.3版本)。

请注意:我自己没有对提案进行测试,但这可能是一个很好的起点,从代码审查本身我可以说它可以正常工作。

答案 2 :(得分:1)

我同意@boberj,我们习惯使用Hibernate格式化程序,但不要忘记批处理,这就是我建议使用的原因:

import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import org.hibernate.engine.jdbc.internal.BasicFormatterImpl;
import org.hibernate.engine.jdbc.internal.Formatter;

/**
 * Created by Igor Dmitriev on 1/3/16
 */
public class HibernateSqlFormatter implements MessageFormattingStrategy {

    private final Formatter formatter = new BasicFormatterImpl();

    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql) {
        if (sql.isEmpty()) {
            return "";
        }
        String template = "Hibernate: %s %s {elapsed: %sms}";
        String batch = "batch".equals(category) ? ((elapsed == 0) ? "add batch" : "execute batch") : "";
        return String.format(template, batch, formatter.format(sql), elapsed);
    }
}

答案 3 :(得分:0)

您可以修补com.p6spy.engine.spy.appender.SingleLineFormat.java 删除准备好的元素和对P6Util的任何引用,如下所示:

package com.p6spy.engine.spy.appender;
public class SingleLineFormat implements MessageFormattingStrategy {
  @Override
  public String formatMessage(final int connectionId, final String now, final long elapsed, final String category, final String prepared, final String sql) {
    return now + "|" + elapsed + "|" + category + "|connection " + connectionId + "|" + sql;
  }
}

然后只编译文件 javac com.p6spy.engine.spy.appender.SingleLineFormat.java

用新的替换p6spy.jar中的现有类文件。

答案 4 :(得分:0)

在 p6Spy 3.9 中,这可以非常简单地实现。在 spy.properties 集中

customLogMessageFormat=%(effectiveSql)