Only show effective SQL string P6Spy

痞子三分冷 提交于 2019-11-29 07:54:50

In spy.properties there is a property called logMessageFormat that you can set to a custom implementation of MessageFormattingStrategy. This works for any type of logger (i.e. file, slf4j etc.).

E.g.

logMessageFormat=my.custom.PrettySqlFormat

An example using Hibernate's pretty-printing SQL formatter:

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); 
    }

}

There is no such option provided to achieve it via configuration only yet. I think you have 2 options here:

For the later option, I believe you could achieve it via your own class (depending on the logger you use, let's assume you use Log4jLogger).

Well, if you check relevant part of the Log4jLogger github as well as sourceforge version, your implementation should be rather straightforward:

spy.properties:

appender=com.EffectiveSQLLog4jLogger

Implementation itself could look like this:

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 :)
  }
}

Please note the implementation should cover github (new project home, no version released yet) as well as sourceforge (original project home, released 1.3 version).

Please note: I didn't test the proposal myself, but it could be a good starting point and from the code review itself I'd say it could work.

I agree with @boberj, we are used to having logs with Hibernate formatter, but don't forget about batching, that's why I suggest to use:

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);
    }
}

You can patch com.p6spy.engine.spy.appender.SingleLineFormat.java removing the prepared element and any reference to P6Util like so:

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;
  }
}

Then compile just the file javac com.p6spy.engine.spy.appender.SingleLineFormat.java

And replace the existing class file in p6spy.jar with the new one.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!