[Oracle] Diagnosability in Jdbc, driver에서 사용되는 SQL 로깅
Oracle jdbc driver (ojdbc
) 중에서 _g
로 끝나는 라이브러리가 있는데 이걸 이용하면 driver 를 통해서 쿼리하는 SQL 을 모두 추적할 수가 있다.
Oracle Test DB
docker hub 에 간단하게 오라클 데이터베이스를 테스트해볼 수 있는 이미지가 있어 이걸 이용했다. 등록한 사용자랑 DB 스키마를 보니 owncloud 에서 repository DB 로 oracle XE 를 이용하기 위해 테스트 하는 용도로 사용하는 것 같은데, 기능 테스트만 하면 되기때문에 상관없다.
아래와 같이 간단하게 이미지를 다운받고 실행하면
docker pull deepdiver/docker-oracle-xe-11g
docker run -d -p 49160:22 -p 49161:1521 deepdiver/docker-oracle-xe-11g
아래와 같이 ssh 접근을 할 수도 있고
ssh root@localhost -p 49160
DB Listener 가 떠 있는 것도 확인할 수 있다.
# netstat -anp | grep 49161
tcp6 0 0 :::49161 :::* LISTEN -
Sample Jdbc Source Code
간단히 xe:autotest/owncloud 데이터베이스에 접속해 SELECT SQL 을 수행하는 코드를 작성하고
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ConnTest {
static String result = null;
static Connection conn = null;
static PreparedStatement pstmt = null;
public static void main(String[] argv) {
try{
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:49161:xe", "autotest", "owncloud");
String sql = "SELECT TABLE_NAME from ALL_TABLES";
pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String col1 = rs.getString("TABLE_NAME");
System.out.println(col1);
}
pstmt.close();
conn.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
컴파일하면 테스트 준비 끝.
javac ConnTest.java
Diagnosability in JDBC
링크 에 가면 자세한 사용법을 확인할 수 있는데 기본적인 사용법은 아래와 같다.
일단은 jdbc를 사용하는 메인 클래스를 실행할 때에 -Djava.util.logging.config.file=OracleLog.properties -Doracle.jdbc.Trace=true
와 같은 옵션을 추가해주면 되는데,
jdbc.log
라는 파일로 로그를 남기기 위해서 OracleLog.properties
설정 파일을 만들어준다.
.level=SEVERE
oracle.jdbc.level=FINE
oracle.jdbc.handlers=java.util.logging.FileHandler
java.util.logging.FileHandler.level=FINE
java.util.logging.FileHandler.pattern=jdbc.log
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
이제 다음과 같이 앞서 만든 프로그램을 실행하면
java \
-cp .:ojdbc8_g-19.3.0.0.jar \
-Djava.util.logging.config.file=OracleLog.properties \
-Doracle.jdbc.Trace=true \
ConnTest
jdbc.log
라는 파일이 생성되고 다음과 같이 DB 에 요청한 SQL 이 모두 로깅되는 것을 확인할 수 있다.
Oct 11, 2019 11:25:06 PM oracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource$BlockReleaserListener <init>
INFO: setCollectionUsageThreshold<PS Old Gen>(2479148236)
Oct 11, 2019 11:25:06 PM oracle.jdbc.driver.T4CConnection logon
INFO: Connection.logon: oracle.jdbc.driver.T4CConnection@1e67b872
Oct 11, 2019 11:25:06 PM oracle.jdbc.driver.T4CConnection logon
INFO: Operating System Process Identifier (SPID): 213
Oct 11, 2019 11:25:06 PM oracle.jdbc.driver.T4CConnection logon
INFO: DRCP Enabled: false
Oct 11, 2019 11:25:07 PM oracle.jdbc.driver.OracleStatement logSQL
CONFIG: 1FB700EE SQL: SELECT TABLE_NAME from ALL_TABLES
FINE
외에도, 공식 문서에 따르면 다음과 같은 LOGLEVEL 을 설정할 수 있다.
- OFF
- Turns off logging.
- SEVERE
- Logs SQLExceptions and internal errors.
- WARNING
- Logs SQLWarnings and bad but not fatal internal conditions.
- INFO
- Logs infrequent but significant events and errors. It produces a relatively low volume of log messages.
- CONFIG
- Logs SQL strings that are executed.
- FINE
- Logs the entry and exit to every public method providing a detailed trace of JDBC operations. It produces a fairly high volume of log messages.
- FINER
- Logs calls to internal methods.
- FINEST
- Logs calls to high volume internal methods.
- ALL
- Logs all the details. This is the most detailed level of logging.