ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • p6spy 로그 설정 방법
    Language/Java 2024. 9. 27. 14:53



    스프링부트 설정

    P6spyConfig

    이 클래스는 스프링 애플리케이션이 시작될 때 자동으로 실행되며, P6Spy의 로그 포맷을 P6spyPrettySqlFormatter라는 사용자 정의 포맷터로 설정하는 역할을 한다. 이로 인해, P6Spy가 데이터베이스 쿼리를 로그할 때 P6spyPrettySqlFormatter에 정의된 형식대로 로그를 출력하게 된다.

    import com.p6spy.engine.spy.P6SpyOptions;
    import jakarta.annotation.PostConstruct;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class P6spyConfig {
    
      @PostConstruct
      public void setLogMessageFormat() {
        P6SpyOptions.getActiveInstance().setLogMessageFormat(P6spyPrettySqlFormatter.class.getName());
      }
    }

     

    P6spyPrettySqlFormatter

    간단하게 아래처럼 사용할 수 있다.

    public class P6spyPrettySqlFormatter implements MessageFormattingStrategy {
        @Override
        public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
            return String.format("%s | took %dms | SQL: %s", now, elapsed, sql);
        }
    }

     

    저는 블로그와 지피티의 도움으로 아래처럼 설정하였다.

    import com.p6spy.engine.logging.Category;
    import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    import org.hibernate.engine.jdbc.internal.FormatStyle;
    
    public class P6spyPrettySqlFormatter implements MessageFormattingStrategy {
      private String getServiceNameFromStackTrace() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    
        for (StackTraceElement element : stackTrace) {
          // 예: "com.example.service" 패키지의 클래스를 서비스로 가정
          if (element.getClassName().contains("service")) {
            return element.getClassName() + "." + element.getMethodName();
          }
        }
        return "UnknownService";
      }
    
      @Override
      public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
        String serviceInfo = getServiceNameFromStackTrace();
    
        sql = formatSql(category, sql);
    //    Date currentDate = new Date();
    //    SimpleDateFormat format1 = new SimpleDateFormat("yy.MM.dd HH:mm:ss");
    //    return now + "|" + elapsed + "ms|" + category + "|connection " + connectionId + "|" + P6Util.singleLine(prepared) + sql;
    //    return format1.format(currentDate) + " | " + "OperationTime : " + elapsed + "ms" + sql;
        return String.format("%s | took %dms | category: %s | connection: %d | %s | SQL: %s",
            serviceInfo, elapsed, category, connectionId, now, sql);
      }
    
      private String formatSql(String category, String sql) {
        if (sql == null || sql.trim().isEmpty()) {
          return sql;
        }
    
        // Only format Statement, distinguish DDL And DML
        if (Category.STATEMENT.getName().equals(category)) {
          String tmpsql = sql.trim().toLowerCase(Locale.ROOT);
          if (tmpsql.startsWith("create") || tmpsql.startsWith("alter") || tmpsql.startsWith("comment")) {
            sql = FormatStyle.DDL.getFormatter().format(sql);
          } else {
            sql = FormatStyle.BASIC.getFormatter().format(sql);
          }
          sql = "|\nHeFormatSql(P6Spy sql,Hibernate format):" + sql;
        }
    
        return sql;
      }
    }

     

    application.yml

    #p6spy 로그설정 (운영환경은 반드시 false)
    decorator:
      datasource:
        p6spy:
          enable-logging: true
    
    # 운영환경
    #decorator:
    #  datasource:
    #    enabled: false

     

    결과

    주요설정

      if (tmpsql.startsWith("create") || tmpsql.startsWith("alter") || tmpsql.startsWith("comment")) {
        sql = FormatStyle.DDL.getFormatter().format(sql);
      } else {
        sql = FormatStyle.BASIC.getFormatter().format(sql);
      }


    결과

     

    끝!

     

    참고)
    https://backtony.tistory.com/34

     

    댓글

Designed by Tistory.