(MSA)3-1.log4jdbc와 p6spy 비교

Published: by Creative Commons Licence

log4jdbcp6spy 비교 및 설정 방법

log4jdbcp6spy는 모두 JDBC 쿼리 로깅을 위한 라이브러리입니다. 두 라이브러리는 SQL 쿼리 로깅, 파라미터 바인딩 로깅, 슬로우 쿼리 로깅 등을 제공합니다. 본 글에서는 두 라이브러리의 장단점, 특징 비교, 슬로우 쿼리 로깅 설정, 비동기 로깅 및 성능 최적화 설정, SQL 포맷 설정 등을 마크다운 형식으로 정리하였습니다.


log4jdbc vs p6spy 장단점 및 특징 비교

1. ** log4jdbc 특징**

  • 기본 작동 원리: JDBC 드라이버를 감시하여 SQL 쿼리와 파라미터를 로깅합니다.
  • 설정 용이성: 설정이 간단하고, Hibernate와 통합이 쉽게 가능합니다.
  • SQL 로그 포맷: SQL 쿼리와 파라미터 바인딩을 로그로 출력합니다.
  • 성능 최적화: 성능 최적화에는 다소 제한이 있을 수 있습니다.
  • 슬로우 쿼리 로깅: 별도의 설정을 통해 슬로우 쿼리 로그를 기록할 수 있습니다.

2. ** p6spy 특징**

  • 기본 작동 원리: JDBC 드라이버를 감시하고 SQL 쿼리, 파라미터, 쿼리 실행 시간 등을 기록합니다.
  • 확장성: 다양한 로그 포맷, 성능 분석, 통계 기능을 제공합니다.
  • 슬로우 쿼리 로깅: 쿼리 실행 시간이 오래 걸리는 SQL을 슬로우 쿼리 로그로 기록할 수 있습니다.
  • 성능 최적화: 비동기 로깅을 통해 성능에 미치는 영향을 최소화할 수 있습니다.
  • 로그 포맷: 다양한 출력 포맷(SingleLine, Multiline 등)을 지원하여 가독성을 높입니다.

슬로우 쿼리 로깅 설정

1. ** log4jdbc 슬로우 쿼리 로깅 설정**

log4jdbc에서 슬로우 쿼리를 로깅하려면 log4jdbc.properties 파일에 슬로우 쿼리 임계값을 설정해야 합니다. 예를 들어, 1000ms(1초) 이상의 쿼리를 슬로우 쿼리로 기록하려면 다음과 같이 설정할 수 있습니다.

# log4jdbc.properties 파일 설정
log4jdbc.slowQueryThreshold=1000  # 슬로우 쿼리 임계값 1000ms
log4jdbc.dump.sql.maxlinelength=200  # 로그 길이 제한
log4jdbc.dump.full.debug=true  # 전체 쿼리 덤프
log4jdbc.dump.slowqueries=true  # 슬로우 쿼리 로깅 활성화

2. p6spy 슬로우 쿼리 로깅 설정

p6spy에서는 p6spy.properties 파일을 통해 슬로우 쿼리 로깅을 설정할 수 있습니다. 아래와 같이 log4j2.logger.sql.level을 설정하면 슬로우 쿼리를 기록할 수 있습니다.

# p6spy.properties 파일 설정
log4j2.logger.sql.level=debug  # SQL 로그 레벨 설정
log4j2.logger.sql.slowquery=true  # 슬로우 쿼리 로그 활성화
log4j2.logger.sql.slowquerythreshold=1000  # 슬로우 쿼리 임계값 설정 (단위: 밀리초)

비동기 로깅 및 성능 최적화 설정

1. log4jdbc 비동기 로깅 및 성능 최적화 설정

log4jdbc는 비동기 로깅 기능을 직접 제공하지 않지만, Log4j2를 통해 비동기 로깅을 설정할 수 있습니다. Log4j2의 비동기 AsyncAppender를 사용하여 성능 최적화가 가능합니다.

<configuration>

    <!-- 비동기 로깅 설정 -->
    <appender name="ASYNC_CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="CONSOLE"/>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="ASYNC_CONSOLE"/>
    </root>
</configuration>

2. ** p6spy 비동기 로깅 및 성능 최적화 설정**

p6spy는 기본적으로 비동기 로깅을 지원합니다. p6spy.properties 파일에서 비동기 로깅을 활성화하려면 appender를 설정할 수 있습니다.

# p6spy.properties 파일 설정
appender=com.p6spy.engine.spy.appender.Slf4jLogger
log4j2.logger.sql.level=debug  # SQL 로그 레벨 설정
log4j2.logger.sql.name=org.hibernate.SQL

또한, p6spy는 비동기적으로 로그를 기록할 수 있으며, 성능 최적화가 필요한 경우 쿼리 실행 시간을 측정하고 슬로우 쿼리를 쉽게 추적할 수 있습니다.

SQL 포맷 설정 및 예시

p6spy에서는 다양한 출력 포맷을 지원합니다. p6spy.properties 파일에서 logMessageFormat을 설정하여 출력 포맷을 변경할 수 있습니다.

# p6spy.properties 파일 설정
logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat  # 한 줄 포맷
logMessageFormat=com.p6spy.engine.spy.appender.MultilineFormat   # 멀티라인 포맷

또한, p6spy는 쿼리와 파라미터를 명확하게 출력할 수 있도록 Slf4jLogger를 사용하여 로그를 기록할 수 있습니다.

# p6spy.properties 파일 설정
logMessageFormat=com.p6spy.engine.spy.appender.Slf4jLogger  # Slf4j를 사용한 로깅

✅ p6spy 선택 이유

신규 프로젝트에서 p6spy라이브러리가 유지보수, 커스터마이징, 가독성, 통합 편의성에서 log4jdbc보다 우수하고 실무에서도 안정적이고 유연하게 활용할 수 있을 것 같아 선택하게 되었습니다.

1. Spring Boot에 최적화된 연동

  • p6spy-spring-boot-starter 제공 → 설정이 간편하고 직관적
  • application.yml, logback-spring.xml만으로 빠르게 구성 가능

2. 보기 좋은 로그 포맷 + 파라미터 바인딩

  • 실제 실행된 SQL + 바인딩된 파라미터가 함께 출력
  • MultiLineFormat, SingleLineFormat, 커스텀 포맷터 지원

3. 강력한 커스터마이징 기능

  • 쿼리 필터링, 실행 시간 로깅, 로그 출력 방식 등 세부 설정 가능
  • 직접 구현한 포맷터나 Appender 적용 가능

4. 활발한 유지보수 & 커뮤니티

  • GitHub 기준으로 최신 버전 유지 관리 중
  • 레퍼런스 자료 및 예제도 풍부

5. 안정성과 성능

  • 경량화된 구조 + 실전에서 충분히 검증된 성능
  • 개발 및 운영 환경 모두에서 유용

✅ p6spy 프로젝트 설정

# Slf4J 로거를 사용하여 P6Spy 로그를 기록합니다.
appender=com.p6spy.engine.spy.appender.Slf4JLogger

# 로그 메시지 형식을 여러 줄로 출력하도록 설정합니다. (주석처리됨)
#logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat

# 로그에서 제외할 카테고리를 설정합니다. (info, debug, result, batch 로그를 제외)
excludecategories=info,debug,result,batch

# 실행 시간 임계값 설정 (1000ms 이상 실행된 SQL 쿼리만 로그에 기록)
executionThreshold=1000

# 로그 메시지 형식을 사용자 정의 형식으로 설정합니다.
# 형식: 현재 시간 | 실행 시간(ms) | 카테고리 | 연결 ID | SQL 쿼리
logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
customLogMessageFormat=%(currentTime)|%(executionTime)ms|%(category)|connection%(connectionId) %(sql)

# 바인딩된 파라미터 정보를 로그에 포함시킵니다.
includeBindings=true