Показывать только эффективную строку SQL P6Spy

Я использую p6spy для записи SQL-операторов, сгенерированных моей программой. Формат выведенного файла spy.log выглядит следующим образом:

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

Мне просто интересно, если кто-нибудь знает, есть ли способ изменить файл spy.properties и иметь только последний столбец, эффективную строку SQL, вывод в файл spy.log? Я просмотрел файл свойств, но не нашел ничего, что могло бы это поддержать.

Спасибо!

5 ответов

В spy.properties есть свойство, которое называется logMessageFormat что вы можете установить для пользовательской реализации MessageFormattingStrategy, Это работает для любого типа регистратора (например, файл, slf4j и т. Д.).

Например

logMessageFormat=my.custom.PrettySqlFormat

Пример использования форматирующего SQL-модуля Hibernate:

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

}

В p6Spy 3.9 это можно сделать достаточно просто. В spy.propertiesустановлен

      customLogMessageFormat=%(effectiveSql)

Я согласен с @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);
    }
}

Такой возможности для достижения этой цели пока нет. Я думаю, что у вас есть 2 варианта здесь:

  • заполнить новый отчет об ошибке / запросе функций (который также может принести пользу другим при использовании p6spy) по адресу: https://github.com/p6spy/p6spy/issues?state=open или
  • обеспечить пользовательскую реализацию.

Что касается более позднего варианта, я полагаю, что вы можете достичь этого с помощью своего собственного класса (в зависимости от используемого вами регистратора, давайте предположим, что вы используете 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).

Обратите внимание: я не тестировал предложение сам, но оно могло бы стать хорошей отправной точкой, и из самого обзора кода я бы сказал, что оно может работать.

Вы можете исправить 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 новым.

Другие вопросы по тегам