source

JDBC를 사용할 때 SQL 문에 대한 로깅을 실행하는 방법

manysource 2023. 4. 5. 22:02

JDBC를 사용할 때 SQL 문에 대한 로깅을 실행하는 방법

이클립스 IDE에서 Oracle 데이터베이스에 연결하여 JDBC 프로그램을 사용하여 로그를 활성화하려고 합니다.

이 SO 포스트 JDBC 로깅을 파일화하여 아래 Java 프로그램을 만들고 Eclipse IDE에서 실행했는데 JDBC 드라이버 클래스에서 생성된 로그를 볼 수 없었습니다.

import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class Logging {

    static Logger log = Logger.getLogger(Logging.class.toString());
    static Connection con = null;

    public static void main(String[] args) throws SQLException,
            ClassNotFoundException {
        System.setProperty("oracle.jdbc.Trace", Boolean.TRUE.toString());
        System.setProperty("java.util.logging.config.file",
                "OracleLog.properties");
        log.info("Test Message");
        enableLogging(false);
        getConnection();
        closeConnection();
    }

    static private void enableLogging(boolean logDriver) {
        try {
            oracle.jdbc.driver.OracleLog.setTrace(true);

            // compute the ObjectName
            String loader = Thread.currentThread().getContextClassLoader()
                    .toString().replaceAll("[,=:\"]+", "");
            javax.management.ObjectName name = new javax.management.ObjectName(
                    "com.oracle.jdbc:type=diagnosability,name=" + loader);

            // get the MBean server
            javax.management.MBeanServer mbs = java.lang.management.ManagementFactory
                    .getPlatformMBeanServer();

            // find out if logging is enabled or not
            System.out.println("LoggingEnabled = "
                    + mbs.getAttribute(name, "LoggingEnabled"));

            // enable logging
            mbs.setAttribute(name, new javax.management.Attribute(
                    "LoggingEnabled", true));

            File propFile = new File("path/to/properties");
            LogManager logManager = LogManager.getLogManager();
            logManager.readConfiguration(new FileInputStream(propFile));

            if (logDriver) {
                DriverManager.setLogWriter(new PrintWriter(System.err));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException,
            ClassNotFoundException {
        Properties connectionProps = new Properties();
        connectionProps.put("user", "test_app");
        connectionProps.put("password", "test");

        Class.forName("oracle.jdbc.driver.OracleDriver");
        con = DriverManager.getConnection(
                "jdbc:oracle:thin:@"+HOST_IP+":1521:"+SID,
                connectionProps);
        System.out.println("Connected to database");
        return con;
    }

    public static void closeConnection() throws SQLException {
        if (con != null) {
            con.close();
        }
    }

}

OracleLog.properties 파일에 다음 내용이 있습니다.

.level=SEVERE
oracle.jdbc.level=INFO
oracle.jdbc.handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

을 실행할 때 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ojdbc6-11.2.0.3.jar에서 classpath로.

INFO: Test Message
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,name=sun.misc.Launcher$AppClassLoader@73d16e93
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:643)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
    at myjdbc.Logging.enableLogging(Logging.java:45)
    at myjdbc.Logging.main(Logging.java:24)
Connected to database

내가 약면면면면이 ojdbc6_g.jar클래스 패스에서도 같은 예외가 발생하고 있습니다.

JDBC 프로그램에 대한 로깅을 활성화하려면 어떻게 해야 합니까? 기본적으로 내부 JDBC 코드에 의해 생성된 로그를 확인해야 합니다.

업데이트: 지금 배치했습니다.ojdbc6dms.jar파일이 제과 같은예외가 .classpath 파파 、 classpath 。내 프로그램에서 다음과 같은 예외가 발생하고 있습니다.

Nov 28, 2014 9:09:02 PM jdbc.chap2.Logging main
INFO: Test Message
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,name=sun.misc.Launcher$AppClassLoader@73d16e93
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:643)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
    at jdbc.chap2.Logging.enableLogging(Logging.java:45)
    at jdbc.chap2.Logging.main(Logging.java:24)
Exception in thread "main" java.lang.NoClassDefFoundError: oracle/dms/console/DMSConsole
    at oracle.jdbc.driver.DMSFactory.<clinit>(DMSFactory.java:48)
    at oracle.jdbc.driver.PhysicalConnection.createDMSSensors(PhysicalConnection.java:2121)
    at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:730)
    at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:433)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:608)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:208)
    at jdbc.chap2.Logging.getConnection(Logging.java:70)
    at jdbc.chap2.Logging.main(Logging.java:25)
Caused by: java.lang.ClassNotFoundException: oracle.dms.console.DMSConsole
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 10 more

2019년 업데이트 : log4jdbc는 2015년 이후 유지되지 않고 있으며, p6dbc는 여전히 활발하게 유지되고 있는 것으로 보입니다.

원답

이 목적을 위해 사용할 수 있는 Spy 프레임워크가 많이 있습니다.log4jdbc를 확인해 주세요.이것이 당신이 찾고 있는 것입니다.

특징들

  • JDBC 3 및 JDBC 4 완전 지원!
  • 대부분의 경우 드라이버 클래스 이름을 net.sf.log4jdbc로 변경하면 쉽게 설정할 수 있습니다.DriverSpy 및 기존 jdbc URL에 "jdbc:log4"를 추가하고 로그 카테고리를 설정하면 바로 사용할 수 있습니다.
  • 로그 출력에서는 준비된 스테이트먼트의 경우 bind 인수가 SQL 출력에 자동으로 삽입됩니다.이것에 의해, 많은 케이스의 가독성과 디버깅이 큰폭으로 향상됩니다.
  • SQL 타이밍 정보를 생성하여 SQL 문이 실행되는 데 걸리는 시간을 식별할 수 있습니다.또한 이 데이터는 포함된 툴을 사용하여 포스트 프로세싱하여 응용 프로그램에서 느린 SQL을 빠르게 식별하는 프로파일링 보고서 데이터를 생성할 수 있습니다.
  • SQL 연결 번호 정보는 연결 풀링 또는 스레드 문제를 식별하는 데 도움이 됩니다.JDK 1.4 이후 및 SLF4J 1.x에서 기본 JDBC 드라이버와 함께 작동합니다.
  • 비즈니스 친화적인 Apache 2.0 라이센스로 라이센스가 부여된 오픈 소스 소프트웨어

사용.

  • log4jdbc jar(JDK 버전에 기반)를 응용 프로그램의 클래스 경로에 배치합니다.
  • 사용할 로깅 시스템을 선택합니다.log4j, logback, commons logging..기타 지원
  • JDBC 드라이버 클래스를 net.sf.log4jdbc로 설정합니다.어플리케이션 구성의 DriverSpy.대부분의 경우 스파이 되고 있는 기본 드라이버는 추가 구성 없이 자동으로 로드됩니다.
  • 사용하고 있는 통상의 jdbc URL 에 jdbc:log4 를 부가합니다.

    예를 들어 일반 jdbc URL이 jdbc:derby://localhost:1527//db-derby-10.2.0-bin/databases/MyDatabase인 경우 jdbc:log4jdbc:derby:/localhost:1527/db-db-dby-10.2.0/my.bases/myBases로 변경합니다.

  • 벌목기를 설치하세요.

    jdbc.sqlonly: SQL만 기록합니다.준비된 스테이트먼트 내에서 실행된SQL은 자동으로 bind 인수를 해당 위치에 있는 데이터로 대체하여 가독성을 크게 높입니다.1.0

    jdbc.sqltiming: SQL 실행에 걸린 시간에 대한 타이밍 통계를 포함하여 SQL 실행 후 로그를 기록합니다.1.0

    jdbc.syslog:ResultSets를 제외한 모든 JDBC 호출을 기록합니다.이것은 매우 큰 양의 출력이며 특정 JDBC 문제를 추적하지 않는 한 일반적으로 필요하지 않습니다.1.0

    jdbc.syset:ResultSet 객체에 대한 모든 콜이 기록되기 때문에 볼륨은 더욱 커집니다.1.0

    jdbc.connection:연결 열기 및 닫기 이벤트와 열려 있는 연결 번호를 모두 덤프합니다.이것은 접속 누전 문제를 추적하는 데 매우 유용합니다.

매우 오래된 토픽인 것은 알지만 아직 언급되지 않은 것은 Oracle의 경우 필요한 추적 지원 Oracle JDBC 드라이버를 사용하고 시작 시 JVM 속성을 통한 로깅을 활성화하는 것만으로 애플리케이션 코드를 변경할 필요가 없는 솔루션이 존재한다는 것입니다.

Oracle에서 직접 이 내용을 설명했는데, 시행착오를 거쳐 다음과 같은 작업을 수행하게 되었습니다.

  1. 트레이스 대응ojdbc jar 파일을 클래스 패스에 배치합니다.링크된 Oracle 페이지에서 인용: "로그 출력을 얻으려면 ojdbc5_g.jar 또는 ojdbc6_g.jar와 같이 파일 이름에 "_g"로 표시된 debug JAR 파일을 사용해야 합니다." Oracle 11g 설치 내용

  2. 링크된 Oracle 페이지의 설명에 따라 logging.properties 파일을 생성하고 필요에 따라 로깅 수준을 조정합니다.예:

    .level=SEVERE oracle.jdbc.level=FINEST oracle.jdbc.handlers=java.util.logging.FileHandler java.util.logging.FileHandler.level=FINEST java.util.logging.FileHandler.pattern=jdbc.log java.util.logging.FileHandler.count=1 java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

  3. JVM 속성 "-Doracle.jdbc"를 추가합니다.Trace=true -Djava.util.logging.config.파일=java.properties"를 JDBC 응용 프로그램의 java startup 명령어로 지정합니다.

이제 JDBC 응용 프로그램에서 원하는 정보를 포함하는 jdbc.log라는 이름의 파일이 생성됩니다.경우에 따라 logging.properties 파일에 대한 전체 경로를 지정해야 할 수 있습니다.

Spring 프레임워크를 사용하는 경우 데이터 소스 프록시 프레임워크는 매우 편리합니다.기본적으로 어떤 것이든 감쌀 수 있습니다.DataSource로깅 동작을 추가합니다.

여기에 이미지 설명 입력

Java EE를 사용하는 경우 P6spy를 사용하는 것이 좋습니다.

여기에 이미지 설명 입력

이면에는 p6spy가 스테이트먼트 가로채기를 제공합니다.Driverlevel. EE가 사용하기 때문에 EE 합니다.DataSource이치노

Log4j 를 사용하고 있는 경우는, 다음의 조작을 실시합니다.

Oracle JDBC Developer's Guide: Diagnosability in JDBC에서 설명ojdbc_g 사용
할 수 있습니다.19.3 드라이버는 Maven에 있습니다.

        <dependency>
            <groupId>com.oracle.ojdbc</groupId>
            <artifactId>ojdbc8_g</artifactId>
            <version>19.3.0.0</version>
        </dependency>

Log4j JDK 로깅 어댑터도 필요합니다.

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jul</artifactId>
            <version>2.13.0</version>
        </dependency>

하다
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
-Doracle.jdbc.Trace=true

log4j2.xml에서 로거 구성

        <Logger name="oracle.jdbc" level="TRACE">
            <AppenderRef ref="Console"/>
        </Logger>
        <Logger name="oracle.sql" level="TRACE">
            <AppenderRef ref="Console"/>
        </Logger>

:level="ALL"합니다.

대응하는 시스템 속성을 설정해 보셨습니까?예: TRACE의 경우:

System.setProperty( "oracle.jdbc.Trace", Boolean.TRUE.toString() );

(https://docs.oracle.com/cd/B28359_01/java.111/b31224/diagnose.htm)에서 입수).

언급URL : https://stackoverflow.com/questions/27060563/how-to-enable-logging-for-sql-statements-when-using-jdbc