我正在使用java.util.logging进行日志记录和跟踪.如何在Java应用程序中动态设置应写入日志的文件.
根据c3p0文档,您可以手动指定日志的位置,无论是通过JDK1.4日志记录,Log4j还是通过System.out.我正在运行SLF4J,所以我已经包含org.slf4j.jul-to-slf4j并调用SLF4JBridgeHandler.install()我的应用程序来强制所有Java util日志记录通过SLF4J.另外,我在我的c3p0.properties文件中包含以下属性:
com.mchange.v2.log.MLog = com.mchange.v2.log.jdk14logging.Jdk14MLog
Run Code Online (Sandbox Code Playgroud)
根据文档,这将强制c3p0记录到JDK1.4日志记录,这反过来将记录到SLF4J.这确实有点工作,但我仍然看到一些日志命中System.err:
例1:
17:24:32.648 [main] INFO com.mchange.v2.log.MLog - MLog clients using java 1.4+ standard logging.
Jul 27, 2011 5:24:32 PM com.mchange.v2.log.MLog <clinit>
INFO: MLog clients using java 1.4+ standard logging.
Jul 27, 2011 5:24:32 PM com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
17:24:32.754 [main] INFO com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
Run Code Online (Sandbox Code Playgroud)
上面的第1行和第6行写入SLF4J,其他写入System.err.
例2:
Jul …Run Code Online (Sandbox Code Playgroud) 我已经安装了Tomcat,并使用SLF4J作为我们的日志框架.我复制slf4j-api-1.6.4.jar并slf4j-jdk14-1.6.4.jar进入Tomcat库即$TOMCAT_HOME/lib.
我假设如果我使用SLF4J,它将委托给java.util.Logger,它将委托给底层的Tomcat日志框架.但是当我部署并检查我的应用程序时,我没有看到任何记录.我的所有异常/日志信息都会丢失.
我的理解是正确的,还是我错过了任何保持课堂路径的东西?
我试图在运行时设置java util日志配置文件,以避免必须将其设置为VM参数.但这只是行不通.每当我尝试重新读取配置时,都会禁用日志记录.
请参阅以下代码段:
package test;
import java.io.FileInputStream;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class A {
private static final Logger LOGGER= Logger.getLogger(A.class.getName());
public static void main(String[] args) throws Exception {
System.out.println("--- start");
LOGGER.log(Level.SEVERE, "SEVERE 1");
LOGGER.log(Level.FINEST, "FINEST 1");
LogManager.getLogManager().readConfiguration();
LOGGER.log(Level.SEVERE, "SEVERE 2");
LOGGER.log(Level.FINEST, "FINEST 2");
LogManager.getLogManager().readConfiguration(new FileInputStream("/tmp/logging.properties"));
LOGGER.log(Level.SEVERE, "SEVERE 3");
LOGGER.log(Level.FINEST, "FINEST 3");
System.out.println("--- end");
}
}
Run Code Online (Sandbox Code Playgroud)
如果我运行没有任何VM参数的类,这是输出:
--- start
09.11.2012 09:59:25 test.A main
SCHWERWIEGEND: SEVERE 1
09.11.2012 09:59:25 test.A main
SCHWERWIEGEND: SEVERE 2
--- end
Run Code Online (Sandbox Code Playgroud)
如您所见,仅记录SEVERE级别,因为这是JREs logging.properties的默认值.通话LogManager#readConfiguration() …
我的应用程序运行正常,直到我将jre升级到7u40.当我的应用程序初始化时,它正在执行Logger.getLogger("ClassName"),并且我得到以下异常.
java.lang.ExceptionInInitializerError
at java.util.logging.Logger.demandLogger(Unknown Source)
at java.util.logging.Logger.getLogger(Unknown Source)
at com.company.Application.Applet.<clinit>(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at java.util.logging.Logger.setParent(Unknown Source)
at java.util.logging.LogManager$6.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.logging.LogManager.doSetParent(Unknown Source)
at java.util.logging.LogManager.access$1100(Unknown Source)
at java.util.logging.LogManager$LogNode.walkAndSetParent(Unknown Source)
at java.util.logging.LogManager$LoggerContext.addLocalLogger(Unknown Source)
at java.util.logging.LogManager$LoggerContext.addLocalLogger(Unknown Source)
at java.util.logging.LogManager.addLogger(Unknown Source)
at java.util.logging.LogManager$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.logging.LogManager.<clinit>(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
例外来自这条线:
private static …Run Code Online (Sandbox Code Playgroud) 我想登录我的应用程序,其中包含几个类.我想在最后有一个.txt日志文件.因此,我创建了一个静态记录器实例,并在一个类中为它创建了一个FileHandler.因为我想拥有一个文件,所以我在FileHandler中将第二个参数设置为true,以便能够在日志记录期间附加日志文件.
public class MyLogging {
static Logger logger;
public Handler fileHandler;
Formatter plainText;
public MyLogging() throws IOException{
//instance the logger
logger = Logger.getLogger(MyLogging.class.getName());
//instance the filehandler
fileHandler = new FileHandler("myLog.txt",true);
//instance formatter, set formatting, and handler
plainText = new SimpleFormatter();
fileHandler.setFormatter(plainText);
logger.addHandler(fileHandler);
}
Run Code Online (Sandbox Code Playgroud)
之后,我创建了其他记录器.我知道我必须为每个类实例一个记录器.因此我只为每个类制作记录器(没有FileHandler).但所有的记录器都引用了一个类(不是我创建记录器的类).例如:
public class Test1 {
static Logger logger;
public Test1()throws IOException {
logger = Logger.getLogger(MyLogging.class.getName());
}
Run Code Online (Sandbox Code Playgroud)
虽然执行了日志记录,但我不确定这是否是正确的解决方案.你能给我一些建议如何用java.util.logging来记录多个类吗?
我创建了一个在Tomcat 8上运行的webapp.一如既往,我想使用slf4j,在这种情况下,由java.util.logging支持(因为它是Tomcat的默认值).相关的依赖是这样的:
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.10</version>
<scope>runtime</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我在代码中添加了一些日志语句(信息和调试),但我找不到它们.既没有在控制台输出中(如果我从eclipse启动Tomcat)也没有在/ logs文件夹中创建的任何日志文件中(我的应用程序正常运行).
那么这里缺少什么?我是否必须向conf/logging.properties添加内容(我不想将任何日志配置打包到我的应用程序中)?是否有一个示例如何配置在tomcat中部署的给定webapp的日志记录?
我正在开发一个使用slf4j api记录的应用程序:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
private static final Logger LOG = LoggerFactory.getLogger(FreemarkerEmailPreviewGenerator.class);
...
LOG.error("Error generating email preview", e);
Run Code Online (Sandbox Code Playgroud)
(上面的代码贴出来显示正在使用的类和包,但非常标准的东西.)
我们使用如下配置的logback:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{HH:mm:ss.SSS}] [%thread] [%-5level %logger{26} - %msg]%n
</pattern>
</encoder>
</appender>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我们的一些代码使用了使用java.util.logging记录的第三方库 - 特别是freemarker.从下面的控制台日志条目中可以看出,logback和jul都记录到控制台,但它们没有使用相同的配置(使用我们的模式的logback条目,jul不使用)
[12:24:38.842] [pool-2-thread-19] [INFO u.o.n.r.l.s.e.t.TemplateLoaderFromService - Finding template workflow/mail/templates/common/workflow-macros.ftl]
[12:24:38.859] [pool-2-thread-19] [INFO u.o.n.r.l.s.e.t.TemplateLoaderFromService - Loaded template workflow/mail/templates/common/workflow-macros.ftl as /workflow/mail/templates/common/workflow-macros.ftl from RegistryMailTemplateService.]
11-Jan-2017 12:24:38 freemarker.log.JDK14LoggerFactory$JDK14Logger error
SEVERE:
Expression domainContact is undefined …Run Code Online (Sandbox Code Playgroud) 我试图浏览Java日志API的教程:
www.vogella.com/articles/Logging/article.html
但是生成的文件是空的(在Netbeans,Eclipse中测试以及从cmd运行jar).日志消息仅显示在控制台中.
以下是项目中使用的文件.这种行为可能是什么原因?
项目:de.vogella.logger
MyHtmlFormatter.java
package de.vogella.logger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
//This custom formatter formats parts of a log record to a single line
class MyHtmlFormatter extends Formatter {
// This method is called for every log records
public String format(LogRecord rec) {
StringBuffer buf = new StringBuffer(1000);
// Bold any levels >= WARNING
buf.append("<tr>");
buf.append("<td>");
if (rec.getLevel().intValue() >= Level.WARNING.intValue()) {
buf.append("<b>");
buf.append(rec.getLevel());
buf.append("</b>");
} else {
buf.append(rec.getLevel());
}
buf.append("</td>");
buf.append("<td>"); …Run Code Online (Sandbox Code Playgroud) 我logging.properties在Eclipse这个样子,当我最初发布这个问题:
handlers = java.util.logging.ConsoleHandler
org.apache.catalina.core=OFF
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=JUL %4$s: %2$s%n%4$s: %5$s%n
Run Code Online (Sandbox Code Playgroud)
我在使用此配置的Linux服务器上遇到同样的问题:
handlers = 2localhost.org.apache.juli.FileHandler, org.apache.juli.FileHandler
.handlers = org.apache.juli.FileHandler
2localhost.org.apache.juli.FileHandler.level = INFO
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.FileHandler.prefix = localhost.
org.apache.juli.FileHandler.level = ALL
org.apache.juli.FileHandler.formatter = java.util.logging.SimpleFormatter
org.apache.juli.FileHandler.directory = ${catalina.base}/logs
java.util.logging.SimpleFormatter.format=tomcat: %4$s: %2$s%n%4$s: %5$s%n
org.apache.catalina.handlers = org.apache.juli.FileHandler
org.apache.catalina.startup.level = SEVERE
org.apache.catalina.session.ManagerBase.level = SEVERE
org.apache.catalina.core.AprLifecycleListener.level=SEVERE
org.apache.catalina.connector.level = SEVERE
org.apache.coyote.level=SEVERE
org.apache.catalina.level=ALL
org.apache.catalina.startup.HostConfig.level = SEVERE
org.apache.catalina.loader.WebappClassLoader.level = SEVERE
org.apache.catalina.session.ManagerBase.level = INFO
# ServletContext logger
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = ALL
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler …Run Code Online (Sandbox Code Playgroud)