无法发送 JUL -> Logback
Cannot send JUL -> Logback
我正在尝试将来自第 3 方应用程序(使用 JUL ConsoleHandler)的日志记录发送到 logback。我已经关注了该网站上的所有其他帖子,但无法正常工作。我做错了什么吗?
我将以下内容添加到我的 RCP class 的开头,它实现了 bundle activator
public class MyTestActivator implements BundleActivator {
static {
LogManager.getLogManager().reset();
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
java.util.logging.Logger.getGlobal().setLevel(Level.FINEST);
}
@Override
public void start(final BundleContext bundleContext) throws
Exception {
try {
LoggerContext context = (LoggerContext) LoggerFactory.
getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(context);
try {
context.reset();
configurator.doConfigure(getClass().
getResourceAsStream("/logback.xml"));
} catch (JoranException e) {
throw new IOException(e.getMessage(), e);
}
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
} catch (final IOException e) {
e.printStackTrace();
}
}
}
我的 feature.xml 文件包含:
<plugin
id="jul.to.slf4j"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="ch.qos.logback.classic"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="ch.qos.logback.core"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
我的 logback.xml 包含:
<configuration>
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
更新:我也尝试了以下方法,但没有达到预期效果
private static final java.util.logging.Logger[] pin;
static {
LogManager.getLogManager().reset();
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
pin = new java.util.logging.Logger[] {
java.util.logging.Logger.getLogger(""),
java.util.logging.Logger.getLogger("3rd.party.package") };
for (java.util.logging.Logger l : pin) {
l.setLevel(Level.FINEST);
for (Handler h : l.getHandlers()){
if (h instanceof ConsoleHandler){
h.setFormatter(new Formatter(){
public final String format(LogRecord record) {
if (record == null) {
return "";
} else {
return "CONSOLE_MSG:"+record.getMessage();
}
}
});
}
}
}
}
更新 我相信我可以通过添加以下代码来代替上一节中的 for 循环来实现它:
java.util.logging.Logger root = java.util.logging.Logger.getLogger("");
java.util.logging.Logger myLog = java.util.logging.Logger.getLogger("3rd.party.package");
myLog.setParent(root);
myLog.setUseParentHandlers(true);
java.util.logging.LogManager.getLogManager().getLogger( "" ).setLevel( Level.ALL );
唯一的缺点是我可能必须抓住每个记录器并执行此操作。当我查看调试器时,我注意到 none 其中有一个父项(它是空的)
Logger.getGlobal()
is not the root of all JUL loggers. The root of all JUL loggers is Logger.getLogger("")
. If you make programmatic changes to loggers then you have to 因此设置在垃圾回收时不会恢复。
您需要确保日志记录并发布到 parent handlers 并一直到根记录器。
private static final java.util.logging.Logger[] pin;
static {
//Pin first.
pin = new java.util.logging.Logger[] {
java.util.logging.Logger.getLogger(""),
java.util.logging.Logger.getLogger("3rd.party.package") };
//Setup SLF4J
LogManager.getLogManager().reset();
SLF4JBridgeHandler.removeHandlersForRootLogger();
//SLF4JBridgeHandler.install();
java.util.logging.Logger.getLogger("").addHandler(new SLF4JBridgeHandler());
//Change JUL levels.
for (java.util.logging.Logger l : pin) {
l.setLevel(Level.FINEST);
}
}
你也应该试试:
public class MyTestActivator implements BundleActivator {
static {
//Pin first.
pin = new java.util.logging.Logger[] {
java.util.logging.Logger.getLogger(""),
java.util.logging.Logger.getLogger("3rd.party.package") };
//Change JUL levels.
for (java.util.logging.Logger l : pin) {
l.setLevel(Level.FINEST);
}
}
@Override
public void start(final BundleContext bundleContext) throws Exception {
try {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(context);
try {
context.reset();
configurator.doConfigure(getClass().getResourceAsStream("/logback.xml"));
//Setup SLF4J
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
} catch (JoranException e) {
throw new IOException(e.getMessage(), e);
}
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
} catch (final IOException e) {
e.printStackTrace();
}
}
}
将根记录器的 logback 级别设置为 debug
或 trace
。与设置 logback 控制台附加程序的级别相同。
The only downside is that I'll probably have to catch each logger and do this.
可以执行,但记录器树会随时间变化。
The only downside is that I'll probably have to catch each logger and do this. When I looked in the debugger I noticed none of them had a parent (it was null)
这很奇怪。如果记录器是根记录器,则父项仅应为空。也许您正在使用的 LogManager 中存在错误?
或者,您可以向每个要监视的记录器添加一个 new SLF4JBridgeHandler()
,但这不如监视根记录器好。
我正在尝试将来自第 3 方应用程序(使用 JUL ConsoleHandler)的日志记录发送到 logback。我已经关注了该网站上的所有其他帖子,但无法正常工作。我做错了什么吗?
我将以下内容添加到我的 RCP class 的开头,它实现了 bundle activator
public class MyTestActivator implements BundleActivator { static { LogManager.getLogManager().reset(); SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); java.util.logging.Logger.getGlobal().setLevel(Level.FINEST); } @Override public void start(final BundleContext bundleContext) throws Exception { try { LoggerContext context = (LoggerContext) LoggerFactory. getILoggerFactory(); JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(context); try { context.reset(); configurator.doConfigure(getClass(). getResourceAsStream("/logback.xml")); } catch (JoranException e) { throw new IOException(e.getMessage(), e); } StatusPrinter.printInCaseOfErrorsOrWarnings(context); } catch (final IOException e) { e.printStackTrace(); } } }
我的 feature.xml 文件包含:
<plugin id="jul.to.slf4j" download-size="0" install-size="0" version="0.0.0" unpack="false"/> <plugin id="ch.qos.logback.classic" download-size="0" install-size="0" version="0.0.0" unpack="false"/> <plugin id="ch.qos.logback.core" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
我的 logback.xml 包含:
<configuration> <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> <resetJUL>true</resetJUL> </contextListener> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <root level="info"> <appender-ref ref="STDOUT" /> </root> </configuration>
更新:我也尝试了以下方法,但没有达到预期效果
private static final java.util.logging.Logger[] pin;
static {
LogManager.getLogManager().reset();
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
pin = new java.util.logging.Logger[] {
java.util.logging.Logger.getLogger(""),
java.util.logging.Logger.getLogger("3rd.party.package") };
for (java.util.logging.Logger l : pin) {
l.setLevel(Level.FINEST);
for (Handler h : l.getHandlers()){
if (h instanceof ConsoleHandler){
h.setFormatter(new Formatter(){
public final String format(LogRecord record) {
if (record == null) {
return "";
} else {
return "CONSOLE_MSG:"+record.getMessage();
}
}
});
}
}
}
}
更新 我相信我可以通过添加以下代码来代替上一节中的 for 循环来实现它:
java.util.logging.Logger root = java.util.logging.Logger.getLogger(""); java.util.logging.Logger myLog = java.util.logging.Logger.getLogger("3rd.party.package"); myLog.setParent(root); myLog.setUseParentHandlers(true); java.util.logging.LogManager.getLogManager().getLogger( "" ).setLevel( Level.ALL );
唯一的缺点是我可能必须抓住每个记录器并执行此操作。当我查看调试器时,我注意到 none 其中有一个父项(它是空的)
Logger.getGlobal()
is not the root of all JUL loggers. The root of all JUL loggers is Logger.getLogger("")
. If you make programmatic changes to loggers then you have to
您需要确保日志记录并发布到 parent handlers 并一直到根记录器。
private static final java.util.logging.Logger[] pin;
static {
//Pin first.
pin = new java.util.logging.Logger[] {
java.util.logging.Logger.getLogger(""),
java.util.logging.Logger.getLogger("3rd.party.package") };
//Setup SLF4J
LogManager.getLogManager().reset();
SLF4JBridgeHandler.removeHandlersForRootLogger();
//SLF4JBridgeHandler.install();
java.util.logging.Logger.getLogger("").addHandler(new SLF4JBridgeHandler());
//Change JUL levels.
for (java.util.logging.Logger l : pin) {
l.setLevel(Level.FINEST);
}
}
你也应该试试:
public class MyTestActivator implements BundleActivator {
static {
//Pin first.
pin = new java.util.logging.Logger[] {
java.util.logging.Logger.getLogger(""),
java.util.logging.Logger.getLogger("3rd.party.package") };
//Change JUL levels.
for (java.util.logging.Logger l : pin) {
l.setLevel(Level.FINEST);
}
}
@Override
public void start(final BundleContext bundleContext) throws Exception {
try {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(context);
try {
context.reset();
configurator.doConfigure(getClass().getResourceAsStream("/logback.xml"));
//Setup SLF4J
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
} catch (JoranException e) {
throw new IOException(e.getMessage(), e);
}
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
} catch (final IOException e) {
e.printStackTrace();
}
}
}
将根记录器的 logback 级别设置为 debug
或 trace
。与设置 logback 控制台附加程序的级别相同。
The only downside is that I'll probably have to catch each logger and do this.
The only downside is that I'll probably have to catch each logger and do this. When I looked in the debugger I noticed none of them had a parent (it was null)
这很奇怪。如果记录器是根记录器,则父项仅应为空。也许您正在使用的 LogManager 中存在错误?
或者,您可以向每个要监视的记录器添加一个 new SLF4JBridgeHandler()
,但这不如监视根记录器好。