以编程方式关闭特定包的java.util.logging

5
我正在使用一个内部使用Apache CXF的SDK。 Apache CXF默认使用java.util.logging包进行日志记录。
我想将日志级别从INFO更改为WARNING或完全关闭。我能在应用程序的主方法中以编程方式实现吗?

你尝试过这个示例吗? - eparvan
@eparvan 我尝试了:Logger.getLogger("org.apache.cxf").setLevel(Level.OFF),但没有起作用。INFO级别的日志仍然显示出来。 - stepanian
这个链接应该会有所帮助:http://www.nailedtothex.org/roller/kyle/entry/java-util-logging-programmatic-configuration - Prahalad Deshpande
@PrahaladDeshpande 抱歉,它不支持。 - stepanian
我尝试了eparvan提供的示例,并且在CXF3.1.6和java1.8中它能正常工作。我还使用log4j编写了一种替代方案。 - pedrofb
4个回答

4
有一种编程方法可以解决这个问题,但不够直观。如果需要在更精细的层面或多个类之间控制日志,转换到SLF4J或Log4J可能更好。
问题在于Loggers使用WeakReferences进行缓存。从调用Logger.setLevel()到实际使用Logger的时间段内,它可能被垃圾回收(GC)掉。所以记录日志的Logger并不是您设置级别的Logger!尤其是在启动过程中有很多GC的框架中。
解决方案是以编程方式设置配置而不是实际的Loggers。
String logConfig = ".level=" + java.util.logging.Level.INFO + '\n';
logConfig += "handlers=java.util.logging.ConsoleHandler\n";
// ensure ConsoleHandler does not filter
logConfig += "java.util.logging.ConsoleHandler" + ".level=" + java.util.logging.Level.FINEST + '\n';

//set your custom levels
logConfig += "org.apache.cxf" + ".level=" + java.util.logging.Level.WARNING + "\n";

try {
  java.util.logging.LogManager.getLogManager().readConfiguration(new java.io.ByteArrayInputStream(logConfig.getBytes("UTF-8")));
  // no need to close ByteArrayInputStream -- it is a no-op
}
catch (IOException ioe) {
  System.err.println("cannot fully configure logging");
  ioe.printStackTrace();
}

请注意这种方法存在一些问题:
  1. 您正在覆盖内置配置,因此必须设置根处理程序。如果设置了 -Djava.util.logging.config.file,它也会被覆盖。
  2. 完全是hack - 可能无法维护或理解。
  3. 您的配置字符串必须是有效的。请注意,所有行都必须以 \n 结尾。
  4. 必须尽早调用,最好在 main() 的第一行。如果不可能,您还需要迭代所有现有的 Loggers 并使用 setLevel() 更新其配置。

从调用Logger.setLevel()的时间到实际使用Logger的时间,它可能会被垃圾回收。如果您持有对记录器的引用,则不会出现问题。 - Svetlin Zarev
有没有一种方法可以让CXF在没有命令行参数的情况下以编程方式使用log4j? - stepanian
@SvetlinZarev 我认为保留对Logger的引用应该可以解决问题,但如果您尝试为不同的类/包保留不同的设置,则可能需要大量Logger。 - AngerClown

1
下面的链接来自Apache CXF,无论是java.util.logging还是log4j或sl4j,都有易于理解的文档:

http://cxf.apache.org/docs/general-cxf-logging.html

如果您使用log4j,这将非常容易。
您可以为Apache CXF配置log4j,然后在log4j.properties文件中添加以下内容,这将关闭Apache CXF日志记录。
log4j.apache.cxf = WARN

有没有办法让CXF在程序中使用log4j,而无需使用命令行参数? - stepanian
正如@pedrofb在您的一个答案中建议的那样。已经有一个SO帖子可用于以编程方式设置它-https://dev59.com/VGox5IYBdhLWcg3wyXVx#9003191 - Chirag Parmar

1

配置日志级别

在CXF发行版的/etc文件夹中,有一个示例Java SE logging.properties文件可用于配置日志。例如,如果您想将控制台日志级别从WARNING更改为FINE,则需要按照以下方式更新此logging.properties文件中的两个属性:

.level= FINE
java.util.logging.ConsoleHandler.level = FINE

注意:如果您想将FINE更改为其他级别,只需将FINE更改为其他级别即可

完成此操作后,您需要将-Djava.util.logging.config.file属性设置为logging.properties文件的位置。例如,下面的Ant目标已经设置了该属性:

<target name="runClient">
   <java classname="client.WSClient" fork="true">         
      <classpath>
         <pathelement location="${build.classes.dir}"/>
         <fileset dir="${env.CXF_HOME}/lib">
            <include name="*.jar"/>
         </fileset>
      </classpath>
      <jvmarg value="-Djava.util.logging.config.file=/usr/myclientapp/logging.properties"/>
   </java>
</target>

另外,对于SOAP客户端,您可以修改位于JDK_HOME/jre/lib文件夹中的Java全局logging.properties文件,或者对于托管Servlet的Web服务提供者,将logging.properties文件放置在WEB-INF/classes文件夹中(有关更多详细信息,请参见此处。)

资源链接:

  1. http://cxf.apache.org/docs/general-cxf-logging.html

启用/禁用CXF日志记录(有效负载)

To remove cxf logging just comment out or remove code the following code from your cxf configuration xml file.

<cxf:bus>
      <cxf:features>
          <cxf:logging></cxf:logging>
      </cxf:features>
</cxf:bus>

关闭额外的日志记录:

要关闭额外的日志记录,请将 org.apache.cxf 的日志级别更改为 ERROR。在 log4j.properties 中添加以下行:

log4j.logger.org.apache.cxf=ERROR

资源链接:

如何关闭额外的日志记录?


我对你在这里发布的所有内容都很熟悉。请阅读我的问题。 - stepanian

1
你可以使用Log4j代替java.util.logging,如文档所述。这是一种100%的编程方式,可为基于apache CXF的应用程序配置Log4j appender,具体请参考答案
//equivalent to -Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger     
System.setProperty("org.apache.cxf.Logger","org.apache.cxf.common.logging.Log4jLogger");

//Creates the file appender
FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("mylog.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.WARN);
fa.setAppend(true);
fa.activateOptions();

//Add the appender to CXF logger
Logger.getLogger("org.apache.cxf").addAppender(fa);

你需要在类路径中使用 log4j.jar 并在任何 CXF 初始化之前执行代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接