我有一个用于日志记录的帮助程序类,它使用slf4j创建一个loggier并写入日志文件。
我正在使用FileAppender将日志写入已定义的文件。
问题是,这个FileAppender多次将每个日志行写入定义的文件中,但只在glassfish服务器的server.log中写入一次。
这就是我班级的样子:
package de.mycompany.framework.jframework.logging;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.slf4j.LoggerFactory;
/**
* Logger
* @author Marc Vollmer
*/
public class Logger {
/**
* Log Level
* Default: OFF
*/
private Level level = Level.OFF;
/**
* Constructor
*/
public Logger() {
String sLogLevel = "OFF";
try {
sLogLevel = (String)new InitialContext().lookup("jfw/LogLevel");
} catch (NamingException ex) {
}
switch(sLogLevel.toUpperCase()) {
case "DEBUG":
level = Level.DEBUG;
break;
case "INFO":
level = Level.INFO;
break;
case "TRACE":
level = Level.TRACE;
break;
case "WARN":
level = Level.WARN;
break;
case "ERROR":
level = Level.ERROR;
break;
case "ALL":
level = Level.ALL;
break;
default:
level = Level.OFF;
break;
}
}
/**
* Set the Log Level
*
* @param level Log Level
*/
public void setLevel(Level level) {
this.level = level;
}
/**
* Get the Log Level
*
* @return Log Level
*/
public Level getLevel() {
return level;
}
/**
* Get Classname from Package Path
*
* @param sPackage Package Path
* @return Class name
*/
private String getClassFromPackage(String sPackage) {
if (sPackage.contains(".")) {
return sPackage.split("\\.")[(sPackage.split("\\.").length-1)];
} else {
return sPackage;
}
}
/**
* Is the class ignored?
*
* @param sPackString Package PAth
* @return true if ignored, false if not
*/
private boolean isIgnoredClass(String sPackString) {
switch (getClassFromPackage(sPackString)) {
case "Logger":
case "Thread":
return true;
default:
return false;
}
}
/**
* Get the Logger
*
* @return SLF4J Logger
*/
private org.slf4j.Logger getLogger() {
String sName;
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
int i = 0;
StackTraceElement e = stacktrace[i]; // TODO: Adjust after tests
while (isIgnoredClass(e.getClassName())) {
e = stacktrace[++i];
}
sName = getClassFromPackage(e.getClassName()) + "." + e.getMethodName();
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
ch.qos.logback.classic.Logger logger = lc.getLogger(sName);
logger.addAppender(getFileAppender(lc));
logger.setLevel(level);
return logger;
}
/**
* Create a file appender
*
* @param lc Logger Context
* @return File Appender
*/
private FileAppender<ILoggingEvent> getFileAppender(LoggerContext lc) {
FileAppender<ILoggingEvent> fa = new FileAppender<>();
fa.setContext(lc);
fa.setName("FILE");
try {
fa.setFile((String)new InitialContext().lookup("jfw/LogFile"));
} catch (NamingException ex) {
fa.setFile("../logs/jfw.log");
}
PatternLayoutEncoder pl = new PatternLayoutEncoder();
pl.setContext(lc);
try {
pl.setPattern((String)new InitialContext().lookup("jfw/LogPattern"));
} catch (NamingException ex) {
pl.setPattern("%d{dd.MM.yyyy HH:mm:ss.SSS} [%-5(%level)] [%-50.50(%C{0}.%M)] %m%n%xEx");
}
pl.start();
fa.setEncoder(pl);
fa.start();
return fa;
}
/**
* Trace Message
*
* @param sMsg Log Message
*/
public void trace(String sMsg) {
if (getLogger().isTraceEnabled()) {
getLogger().trace(sMsg);
}
}
/**
* Trace Message
*
* @param sMsg Log Message
* @param throwable Throwable
*/
public void trace(String sMsg, Throwable throwable) {
if (getLogger().isTraceEnabled()) {
getLogger().trace(sMsg, throwable);
}
}
/**
* Debug Message
*
* @param sMsg Log Message
*/
public void debug(String sMsg) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(sMsg);
}
}
/**
* Debug Message
*
* @param sMsg Log Message
* @param throwable Throwable
*/
public void debug(String sMsg, Throwable throwable) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(sMsg, throwable);
}
}
/**
* Info Message
*
* @param sMsg Log Message
*/
public void info(String sMsg) {
if (getLogger().isInfoEnabled()) {
getLogger().info(sMsg);
}
}
/**
* Info Message
*
* @param sMsg Log Message
* @param throwable Throwable
*/
public void info(String sMsg, Throwable throwable) {
if (getLogger().isInfoEnabled()) {
getLogger().info(sMsg, throwable);
}
}
/**
* Warn Message
*
* @param sMsg Log Message
*/
public void warn(String sMsg) {
if (getLogger().isWarnEnabled()) {
getLogger().warn(sMsg);
}
}
/**
* Warn Message
*
* @param sMsg Log Message
* @param throwable Throwable
*/
public void warn(String sMsg, Throwable throwable) {
if (getLogger().isWarnEnabled()) {
getLogger().warn(sMsg, throwable);
}
}
/**
* Error Message
*
* @param sMsg Log Message
*/
public void error(String sMsg) {
if (getLogger().isErrorEnabled()) {
getLogger().error(sMsg);
}
}
/**
* Error Message
*
* @param sMsg Log Message
* @param throwable Throwable
*/
public void error(String sMsg, Throwable throwable) {
if (getLogger().isErrorEnabled()) {
getLogger().error(sMsg, throwable);
}
}
}
我使用System.out.println对控制台进行了一些调试输出,例如.trace只被调用一次,在server.log中写入一个日志条目,但在给定的日志文件中写入多个日志条目。
感谢您的回答!
答案 0 :(得分:3)
它会将de logline写入文件两次,因为在de LogBack配置中,文件已配置,然后再次将其添加到特定的Logger。由于日志框架在要写入的文件中是愚蠢的,因此它会将您的日志语句写两次。
查看代码,我看到您为每个logstatement创建了2次FileAppender。有点浪费记忆。如果程序发生某些事情导致它垃圾邮件日志文件,那么在Linux环境中可能会用完文件描述符。如果我是你,我应该放弃这个课程并直接从你的班级开始使用SLF4J。