2014-11-21 29 views
24

Tôi đang cố gắng bật nhật ký bằng chương trình JDBC của mình bằng cách kết nối với cơ sở dữ liệu Oracle trong IDE nhật thực.Bật ghi nhật ký cho JDBC

Tôi đã trải qua bài đăng này JDBC logging to file sau đó tôi đã tạo chương trình java dưới đây và chạy nó từ IDE nhật thực của tôi, nhưng tôi không thể xem bất kỳ nhật ký nào do lớp trình điều khiển JDBC tạo ra.

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

} 

và tôi có dưới đây nội dung trong OracleLog.properties tôi file:

.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 

Nhưng khi tôi chạy chương trình của tôi bằng cách đặt ojdbc6-11.2.0.3.jar trong classpath sau đó tôi nhận được ngoại lệ như:

INFO: Test Message 
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,[email protected] 
    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 

Nếu tôi có ojdbc6_g.jar trong classpath thì tôi cũng nhận được ngoại lệ tương tự.

Vui lòng cho tôi biết cách tôi có thể bật ghi nhật ký cho chương trình JDBC của mình? về cơ bản tôi hy vọng sẽ thấy các bản ghi được tạo bởi mã JDBC bên trong.

Cập nhật: Bây giờ tôi đặt ojdbc6dms.jar tập tin trong classpath, chương trình của tôi được đưa ra dưới đây ngoại lệ:

Nov 28, 2014 9:09:02 PM jdbc.chap2.Logging main 
INFO: Test Message 
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,[email protected] 
    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 
+0

Bạn có trình điều khiển thích hợp trong classpath không? 'Đảm bảo rằng tệp JAR gỡ rối, nói ojdbc5_g.jar hoặc ojdbc6_g.jar, là tệp JAR Oracle JDBC duy nhất trong biến môi trường CLASSPATH.' và 'Để có được bản ghi đầu ra, bạn phải sử dụng các tệp JAR gỡ lỗi, được chỉ định bằng "_g" trong tên tệp,' –

+0

@ KonstantinV.Salikhov, Bây giờ tôi đã thử sử dụng 'ojdbc6_g.jar' trong classpath nhưng nhận được cùng thông báo lỗi, tôi đã cập nhật câu hỏi của mình với các chi tiết lỗi. – user3181365

+1

đậu tương được đăng ký sử dụng tên khác, hãy thử sử dụng jconsole và xem tên mbean và sử dụng tên chính xác. –

Trả lời

5

Nếu bạn đang sử dụng framework Spring, thì datasource-proxy là rất thuận tiện. Về cơ bản, bạn có thể quấn quanh bất kỳ DataSource nào và chỉ thêm hành vi ghi nhật ký.

enter image description here

Nếu bạn đang sử dụng Java EE, sau đó P6spy là một lựa chọn tốt:

enter image description here

Đằng sau hậu trường, p6spy cung cấp đánh chặn tuyên bố ở cấp Driver, mà là nhiều thuận tiện hơn cho các ứng dụng Java EE vì máy chủ ứng dụng cung cấp DataSource.

+0

Xin chào Vlad, bạn có thể xem bài đăng của tôi trên Hibernate - http: // stackoverflow không.com/questions/37088759/get-employee-with-higher-salary-in-each-department – user3181365

10

Có rất nhiều Spy khuôn khổ có sẵn cho mục đích này, hãy kiểm tra log4jdbc, tôi giảm này là những gì bạn đang tìm kiếm.

Tính năng

  • Hỗ trợ đầy đủ cho JDBC 3 và JDBC 4!
  • Dễ dàng cấu hình, trong hầu hết các trường hợp tất cả các bạn cần làm là thay đổi tên lớp lái xe để net.sf.log4jdbc.DriverSpy và thêm vào trước "jdbc: log4" để hiện tại của bạn url jdbc, thiết lập danh mục đăng nhập của bạn và bạn đã sẵn sàng!
  • Trong đầu ra đã ghi, đối với các câu lệnh đã chuẩn bị, các đối số kết buộc là tự động được chèn vào đầu ra SQL. Điều này giúp cải thiện khả năng đọc và gỡ lỗi trong nhiều trường hợp.
  • Thông tin thời gian SQL có thể được tạo để giúp xác định các câu lệnh SQL mất bao lâu để chạy, giúp xác định các câu lệnh đang chạy quá chậm và dữ liệu này có thể được xử lý bằng công cụ được bao gồm để tạo hồ sơ báo cáo nhanh chóng xác định SQL chậm trong ứng dụng của bạn.
  • Thông tin số kết nối SQL được tạo để giúp xác định sự cố kết nối hoặc phân luồng kết nối. Hoạt động với bất kỳ trình điều khiển cơ bản nào của JDBC, với JDK 1.4 trở lên và SLF4J 1.x.
  • Phần mềm nguồn mở, được cấp phép theo Apache 2 thân thiện với doanh nghiệp.0 giấy phép

Cách sử dụng

  • Đặt jar log4jdbc (dựa trên phiên bản JDK) vào classpath của ứng dụng của bạn.
  • chọn hệ thống ghi nhật ký để sử dụng, log4j, logback, đăng nhập commons..etc được hỗ trợ
  • Đặt lớp trình điều khiển JDBC của bạn thành net.sf.log4jdbc.DriverSpy trong cấu hình ứng dụng của bạn. Trình điều khiển cơ bản đang được theo dõi trong nhiều trường hợp sẽ được tải tự động mà không cần bất kỳ cấu hình bổ sung nào.
  • Thêm vào trước jdbc: log4 để url jdbc bình thường mà bạn đang sử dụng.

    Ví dụ, nếu url jdbc bình thường của bạn là jdbc: derby: // localhost: 1527 // db-derby-10.2.2.0-bin/cơ sở dữ liệu/MyDatabase Sau đó bạn sẽ thay đổi nó thành: jdbc: log4jdbc : derby: // localhost: 1527 // db-derby-10.2.2.0-bin/cơ sở dữ liệu/MyDatabase

  • Thiết lập nhật ký của bạn.

    jdbc.sqlonly: Chỉ ghi nhật ký SQL. SQL được thực hiện trong một câu lệnh đã chuẩn bị được tự động hiển thị với các đối số liên kết của nó được thay thế bằng dữ liệu được ràng buộc tại vị trí đó, để tăng khả năng đọc rất nhiều. 1.0

    jdbc.sqltiming: Ghi nhật ký SQL, hậu xử lý, bao gồm thống kê thời gian về thời gian thực thi của SQL. 1.0

    jdbc.audit: Ghi nhật ký TẤT CẢ các cuộc gọi JDBC ngoại trừ ResultSets. Đây là một đầu ra rất lớn và thường không cần thiết trừ khi theo dõi một vấn đề JDBC cụ thể. 1.0

    jdbc.resultset: Thậm chí nhiều đồ sộ hơn, bởi vì tất cả các cuộc gọi tới đối tượng ResultSet đều được ghi nhật ký. 1,0

    jdbc.connection: Logs kết nối mở và các sự kiện gần cũng như bán phá giá tất cả các số kết nối mở. Điều này rất hữu ích cho việc tìm kiếm các vấn đề rò rỉ kết nối.

+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. –

+0

Cảm ơn Eric, tôi đã cập nhật bài đăng của mình với chi tiết – Prince

3

Chủ đề rất cũ, tôi biết, nhưng những gì chưa được nhắc đến là Oracle tồn tại một giải pháp không yêu cầu bất kỳ thay đổi nào trong mã ứng dụng, chỉ bằng cách sử dụng trình điều khiển JDBC Oracle theo dõi bắt buộc và cho phép đăng nhập thông qua các thuộc tính JVM khi khởi động.

Oracle mình đã mô tả here này, và sau khi một số thử và sai tôi đã nhận nó để làm việc:

  1. Đặt dấu vết cho phép file jar ojdbc trong classpath của bạn. Trích dẫn từ trang Oracle được liên kết: "Để có được bản ghi đầu ra, bạn phải sử dụng các tệp JAR gỡ lỗi, được chỉ định bằng" _g "trong tên tệp, như ojdbc5_g.jar hoặc ojdbc6_g.jar." Cài đặt Oracle 11g của tôi chứa

  2. Tạo tệp logging.properties như được mô tả trên trang Oracle được liên kết và điều chỉnh mức ghi nhật ký theo nhu cầu của bạn. Ví dụ:

    .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. Thêm các thuộc tính JVM "-Doracle.jdbc.Trace = true -Djava.util.logging.config.file = logging.properties" cho lệnh khởi động java cho các ứng dụng JDBC của bạn.

Ứng dụng JDBC giờ đây sẽ tạo một tệp có tên jdbc.log chứa thông tin mong muốn. Trong một số trường hợp, có thể cần phải chỉ định đường dẫn đầy đủ đến tệp logging.properties.

+0

Câu trả lời này thực sự là đá, vì nó cho phép kiểm tra hành vi JDBC/Oracle của một ứng dụng mà không thay đổi mã của nó. –

+0

'.level = .SEVERE' này là gì? Nó mang lại cho tôi một lỗi giá trị mức độ xấu. – Stephane

+0

Lỗi đánh máy của nó, nó phải là '.level = SEVERE' –

Các vấn đề liên quan