好的,案子很简单。我需要能够以编程方式启用/禁用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");
}
}
为了确保解决方案 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内部日志记录输出...或者您已经启用了比您想象的更多的日志记录。
答案 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);