以编程方式启用JDK类的日志记录

时间:2014-01-09 21:05:19

标签: java logging

好的,案子很简单。我需要能够以编程方式启用/禁用JDK类(HttpURLConnection)的日志记录。

public class HttpLoggingTest {

    /**
      Just a dummy to get some action from HttpURLConnection
    */
    private static void getSomething(String urlStr) throws MalformedURLException, IOException {
        System.out.println("----- " + urlStr);
        HttpURLConnection conn = (HttpURLConnection) new URL("http://www.google.com").openConnection();

        for (Entry<String, List<String>> header : conn.getHeaderFields().entrySet()) {
            System.out.println(header.getKey() + "=" + header.getValue());
        }
        conn.disconnect();

    }

    public static void main(String[] args) throws MalformedURLException, IOException {

        // HERE : Enable JDK logging for class
        // sun.net.www.protocol.http.HttpURLConnection
        getSomething("http://www.goodle.com");

        // HERE: Disable JDK logging for class
        // sun.net.www.protocol.http.HttpURLConnection
        getSomething("http://www.microsoft.com");           
    }        
}

换句话说:在第一次调用URL之前,必须启用日志记录,然后在下次调用之前禁用日志记录。

这是挑战!
我无法弄明白该怎么做。

必须使用Java 7。

注意:

我可以使用配置文件logging.properties

来完成
sun.net.www.protocol.http.HttpURLConnection.level = ALL

但我希望有一个程序化的解决方案。

更新

这里的代码适用于Java 6但不适用于Java 7:

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map.Entry;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;    

public class HttpLoggingTest {

    /**
      Just a dummy to get some action from HttpURLConnection
    */
    private static void getSomething(String urlStr) throws MalformedURLException, IOException {
        System.out.println("----- " + urlStr);
        HttpURLConnection conn = (HttpURLConnection) new URL("http://www.google.com").openConnection();

        for (Entry<String, List<String>> header : conn.getHeaderFields().entrySet()) {
            System.out.println(header.getKey() + "=" + header.getValue());
        }
        conn.disconnect();            
    }

    private static void enableConsoleHandler() {
        //get the top Logger
        Logger topLogger = java.util.logging.Logger.getLogger("");

        // Handler for console (reuse it if it already exists)
        Handler consoleHandler = null;
        //see if there is already a console handler
        for (Handler handler : topLogger.getHandlers()) {
            if (handler instanceof ConsoleHandler) {
                //found the console handler
                consoleHandler = handler;
                break;
            }
        }

        if (consoleHandler == null) {
            //there was no console handler found, create a new one
            consoleHandler = new ConsoleHandler();
            topLogger.addHandler(consoleHandler);
        }
        consoleHandler.setLevel(Level.ALL);
    }

    public static void main(String[] args) throws MalformedURLException, IOException {

        enableConsoleHandler();

        final Logger httpLogger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection");


        // Enable JDK logging for class
        //sun.net.www.protocol.http.HttpURLConnection
        httpLogger.setLevel(java.util.logging.Level.FINE);
        getSomething("http://www.goodle.com");

        // Disable JDK logging for class
        // sun.net.www.protocol.http.HttpURLConnection
        httpLogger.setLevel(java.util.logging.Level.INFO);
        getSomething("http://www.microsoft.com");           
    }        
}

UPDATE2

为了确保解决方案 only 启用我们的目标类(而不是所有其他JDK内部类)的输出,我创建了这个最小的JAXB示例。这里JAXB只是“其他东西”的一个例子,它可能是JDK的任何其他部分也使用PlatformLogger。

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * Minimal dummy JAXB example. Only purpose is to provoke
 * some JAXB action. Non-prod quality!
 */
@XmlRootElement(name = "book")
public class Celebrity {

    @XmlElement
    public String getFirstName() {
        return "Marilyn";
    }

    @XmlElement
    public String getLastName() {
        return "Monroe";
    }

    public void printXML() {
        JAXBContext context;
        try {
            context = JAXBContext.newInstance(Celebrity.class);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            m.marshal(this, System.out);
        } catch (JAXBException ex) {
        }
    }
}

实例化Celebrity类的实例并调用printXML()。把它放到getSomething()方法中。这不能生成JAXB内部日志记录输出...或者您已经启用了比您想象的更多的日志记录。

2 个答案:

答案 0 :(得分:1)

前几天偶然发现PlatformLoggingMXBean。我需要尝试类似的事情:

PlatformLoggingMXBean platformLoggingMXBean = 
    ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class);
platformLoggingMXBean.setLoggerLevel(
    "sun.net.www.protocol.http.HttpURLConnection", "FINE");

看到它有效。

答案 1 :(得分:0)

尝试:

java.util.logging.Logger logger = 
        java.util.logging.Logger.getLogger(
            "sun.net.www.protocol.http.HttpURLConnection");
logger.setLevel(java.util.logging.Level.FINE);