2008-10-17 105 views
15

是要一般使用的java.util.logging每类需要声明一个像这样的记录:如何减少Java日志模板代码?

public class MyClass { 
    private static Logger _log = Logger.getLogger(MyClass.class.getName()); 
} 

你如何避免这种MyClass.class.getName()样板代码?

+1

你应该把记录器实例决赛。 – 2008-10-17 16:47:39

+0

我使用@Trace注释来执行方法调用跟踪,即记录所有参数和结果/异常。有了这个库:https://github.com/nicholas22/jpropel – 2011-10-09 10:16:50

回答

12

我有一个在Eclipse中设置的模板,因此我只需键入声明的一部分,然后Eclipse将为我自动完成其余部分。

${:import(org.apache.log4j.Logger)} 
private final static Logger log = Logger.getLogger(${enclosing_type}.class); 
${cursor} 

所以,我只需要键入logger,打Ctrl+Space,其次是Enter和Eclipse的其余填补了我,并增加了进口报关以及。

这不会减少样板代码的数量,但至少可以减少按键的数量。

2

如果您使用1.2 +版本的log4j,则不需要getName(),getLogger()接受Class参数。但至于其他方面,如果您希望每个班级都有一个具有自己类别的静态日志成员,则没有任何方法。

+0

除了编写一个getLogger类的getLogger接口并调用getName之外,还有其他方法吗? – 2008-10-17 15:59:18

+0

你没有编写一个等价的方法,你使用log4j方法org.apache.log4j.Logger#getLogger(Class clazz),它自log4j 1.2以来就存在了。 – 2008-10-17 18:43:40

0

您可以简化这一点,因为getLogger重载也只是上课。像这样:

public class MyClass { 
    private static Logger _log = Logger.getLogger(MyClass.class); 
} 

记录器可以像您想要的那样随意或不灵活。你可以为每个类抓取一个新的记录器,就像你上面的例子一样,并且有一个记录器层次结构,你可以通过类来控制和打开/关闭记录。或者如果你的项目很小或者是一个原型等,你可以直接调用Logger.getRootLogger() - 但是你将失去微调你记录和不记录日志的灵活性。你可以有一个基类,其中记录生活,让每个人都称之为一个,但同样,你失去了一些灵活性:

public class MyBase { 
    protected static Logger _log = Logger.getLogger(MyClass.class); 
} 

public class MyClass extends MyBase { 
    .... 
    _log.info("Stuff...."); 
} 

底线,如果你想保持微调配置你的日志的能力在后期的项目中(对于一个类开启更精细的级别调试),那么您可能需要在每个课程中都贴上样板。

+0

您的基类正在使用错误的类创建记录器。 但是,如果你修好了,子类是不是会记录超类的记录器? – davetron5000 2008-10-17 15:58:25

-1

如果使非静态的记录,至少可以继承它:

public class SomeBaseClass 
{ 
    protected Logger logger = Logger.getLogger(getClass()); 
} 

public class SubClass extends SomeBaseClass 
{ 
    public void doit() { logger.debug("doit!!!!"); } 
} 

这是我怎么总是做了。

+0

不会记录所有针对SomeBaseClass的消息吗? – 2008-10-17 15:59:14

+0

不,getClass()将返回对象的运行时类 – 2008-10-17 16:45:16

2

如果你去包级记录仪,增加每包一个样板类的,你可以这样写:

private static final Logger log = Logs.log; 

有黑客读取调用者的类名(事实上日志实现有一个黑客来检测当前的方法),但我不会建议。

3

根据您的需求记录的文章,你可以创建一个静态方法“LoggingService”类用于记录各种“渠道”。我发现我真的不需要将日志粒度降低到课程级别。您可以将您的记录器命名为每种最适合您的产品。我们已经在大型企业应用程序中使用了这个技术好几年了,粒度对我们来说确实不是问题。

在静态初始化块初始化...因此,以记录消息的日志服务:

LoggingService.logError(“嗒嗒”);

每个班级都没有样板代码。

下面是一个例子日志服务:

public class LoggingService { 

/** 
* A log for informational messages. 
*/ 
static private Logger infoLog; 

/** 
* A log for data access messages. 
*/ 
static private Logger dataAccessLog; 

/** 
* A log for debug messages. 
*/ 
static private Logger debugLog; 

/** 
* A log for error messages. 
*/ 
static private Logger errorLog; 

/** 
* A log for all XML related messages. 
*/ 
static private Logger xmlLog; 

/** 
* A log for all trace messages. 
*/ 
static private Logger traceLog; 

/** 
* A log for all warning messages. 
*/ 
static private Logger warnLog; 

static { 

    //This is the bootstrap for the logging service. 
    //Setup each logger 
    infoLog = Logger.getLogger("com.company.logging.info"); 
    dataAccessLog = Logger.getLogger("com.company.logging.dataaccess"); 
    debugLog = Logger.getLogger("com.company.logging.debug"); 
    errorLog = Logger.getLogger("com.company.logging.error"); 
    xmlLog = Logger.getLogger("com.company.logging.xml"); 
    traceLog = Logger.getLogger("com.company.logging.trace"); 
    warnLog = Logger.getLogger("com.company.logging.warn"); 

    // This must be set so isErrorEnabled() will work. 
    errorLog.setLevel(Level.ERROR); 
    warnLog.setLevel(Level.WARN); 
} 
static public void logDataAccess(String pMessage) { 
    dataAccessLog.info(pMessage); 
} 

static public void logInfo(String pMessage) { 
    infoLog.info(pMessage); 
} 

static public void logDebug(String pMessage) { 
    debugLog.debug(pMessage); 
} 

static public void logTrace(String pMessage) { 
    traceLog.debug(pMessage); 
} 

static public void logWarn(String pMessage) { 
    warnLog.warn(pMessage); 
} 

static public void logError(String pMessage) { 
    errorLog.error(pMessage); 
} 

static public void logError(String pMessage, Throwable pThrowable) { 
    errorLog.error(pMessage, pThrowable); 
} 

static public void logXml(String pMessage, XmlBean pContainer) { 

    if (!xmlLog.isInfoEnabled()) return; 

    xmlLog.info(pMessage + " : " + JAXBHelper.marshal(pContainer)); 
} 

static public boolean isInfoEnabled() { 
    return infoLog.isInfoEnabled(); 
} 

static public boolean isDataAccessEnabled() { 
    return dataAccessLog.isInfoEnabled(); 
} 

static public boolean isDebugEnabled() { 
    return debugLog.isDebugEnabled(); 
} 

static public boolean isErrorEnabled() { 
    if (errorLog.getLevel().toInt() >= Level.ERROR_INT) { 
     return true; 
    } 
    return false; 
} 

static public boolean isTraceEnabled() { 
    return traceLog.isDebugEnabled(); 
} 

static public boolean isXmlEnabled() { 
    return xmlLog.isInfoEnabled(); 
} 

static public boolean isWarnEnabled() { 
    return warnLog.isEnabledFor(Level.WARN); 
} 

}

3

看看其实,使用类名的记录器名称的通常的做法是懒惰的比什么都重要。

更好的做法是通过任务上下文命名记录器。这涉及到更多的思考过程和计划,但最终的结果是更加平均的粒度,您可以在其中切换实际任务而不是类的日志记录级别。

1

可以减少和其他许多样板代码与龙目岛

https://github.com/rzwitserloot/lombok

@Slf4j 
    public class LogExample { 
} 

public class LogExample { 
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class); 
}