以编程方式启用JDK类的日志记录 [英] Enable logging for JDK class programmatically

查看:116
本文介绍了以编程方式启用JDK类的日志记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Ok, the case is simple. I need to be able to enable/disable logging for a JDK class (HttpURLConnection) programmatically.

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调用日志之前必须在下次通话之前启用然后禁用。

In other words: before the first URL call the logging must be enabled and then disabled before the next call.

这是挑战!

我无法弄清楚如何做到这一点。

That is the challenge !
I'm unable to figure out how to do it.

必须使用Java 7.

Must work with Java 7.

我可以使用配置文件来执行此操作, logging.properties

I can do it by using configuration file, logging.properties :

sun.net.www.protocol.http.HttpURLConnection.level = ALL

但我想要有一个程序化的解决方案。

but I want to have a programmatic solution.

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

Here's code that works in Java 6 but not in 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。

UPDATE2

In order to make sure that a solution only enables output from our target class (and not all sorts of other JDK internal classes) I've created this minimal JAXB example. Here JAXB is simply an example of 'something else', it could have been any other part of the JDK that also use 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内部日志记录输出...或者您已经启用了比您想象的更多的日志记录。

Instantiate an instance of the Celebrity class and call printXML(). Put that into getSomething() method. This must not generate JAXB internal logging output ... or else you've enabled logging for more than you thought.

推荐答案

偶然发现 PlatformLoggingMXBean 。我需要尝试类似的东西:

Stumbled over PlatformLoggingMXBean the other day. I'll need to try something like:

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

并看到它有效。

这篇关于以编程方式启用JDK类的日志记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆