yan*_*nko 35 java logging stack-trace
public static Logger getLogger() {
final Throwable t = new Throwable();
final StackTraceElement methodCaller = t.getStackTrace()[1];
final Logger logger = Logger.getLogger(methodCaller.getClassName());
logger.setLevel(ResourceManager.LOGLEVEL);
return logger;
}
Run Code Online (Sandbox Code Playgroud)
此方法将返回一个记录器,该记录器知道它正在记录的类.反对它的任何想法?
许多年后:https://github.com/yanchenko/droidparts/blob/master/droidparts/src/org/droidparts/util/L.java
eri*_*son 23
创建堆栈跟踪是一个相对较慢的操作.您的调用者已经知道它所属的类和方法,因此浪费了精力.解决方案的这一方面效率低下.
即使您使用静态类信息,也不应该为每条消息再次获取Logger.来自 Log4j 的作者,CekiGülcü:
包装类中最常见的错误是在每个日志请求上调用Logger.getLogger方法.这可以保证对您的应用程序的性能造成严重破坏.真!!!
这是在类初始化期间获取Logger的传统,高效的习惯用法:
private static final Logger log = Logger.getLogger(MyClass.class);
Run Code Online (Sandbox Code Playgroud)
请注意,这为层次结构中的每种类型提供了单独的Logger.如果您想出一个getClass()在实例上调用的方法,您将看到由基类型记录的消息显示在子类型的记录器下.也许这在某些情况下是可取的,但我发现它令人困惑(而且我倾向于赞成合成而不是继承).
显然,使用动态类型via getClass()将要求您每个实例至少获取一次记录器,而不是像使用静态类型信息的推荐习惯用法那样每个类获取一次.
Nee*_*raj 22
该MethodHandles类(如Java 7)包括查找类,从静态上下文,可以找到并返回当前类的名称.请考虑以下示例:
import java.lang.invoke.MethodHandles;
public class Main {
private static final Class clazz = MethodHandles.lookup().lookupClass();
private static final String CLASSNAME = clazz.getSimpleName();
public static void main( String args[] ) {
System.out.println( CLASSNAME );
}
}
Run Code Online (Sandbox Code Playgroud)
运行时会产生:
Main
Run Code Online (Sandbox Code Playgroud)
对于记录器,您可以使用:
private static Logger LOGGER =
Logger.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
Run Code Online (Sandbox Code Playgroud)
Cow*_*wan 18
我们实际上在LogUtils类中有类似的东西.是的,它有点狡猾,但就我而言,优点是值得的.我们希望确保我们没有任何开销,因为它被重复调用,所以我们(有点hackily)确保它只能从静态初始化器上下文调用,la:
private static final Logger LOG = LogUtils.loggerForThisClass();
Run Code Online (Sandbox Code Playgroud)
如果从普通方法或实例初始化程序调用它(即如果"静态"不在上面),它将失败,以降低性能开销的风险.方法是:
public static Logger loggerForThisClass() {
// We use the third stack element; second is this method, first is .getStackTrace()
StackTraceElement myCaller = Thread.currentThread().getStackTrace()[2];
Assert.equal("<clinit>", myCaller.getMethodName());
return Logger.getLogger(myCaller.getClassName());
}
Run Code Online (Sandbox Code Playgroud)
有人问过这有什么好处
= Logger.getLogger(MyClass.class);
Run Code Online (Sandbox Code Playgroud)
可能从来没有必要处理那些从其他地方复制并粘贴该行并忘记更改类名的人,让您处理将其所有内容发送到另一个记录器的类.
Daa*_*aan 16
我想这会为每个课程增加很多开销.每个班级都必须"抬头".你创建新的Throwable对象来做到这一点......这些扔掉的东西不是免费的.
假设您将静态引用保存到记录器,这里是一个独立的静态单例:
public class LoggerUtils extends SecurityManager
{
public static Logger getLogger()
{
String className = new LoggerUtils().getClassName();
Logger logger = Logger.getLogger(className);
return logger;
}
private String getClassName()
{
return getClassContext()[2].getName();
}
}
Run Code Online (Sandbox Code Playgroud)
用法很干净:
Logger logger = LoggerUtils.getLogger();
Run Code Online (Sandbox Code Playgroud)
对于使用它的每个类,您都必须查找 Logger,因此您不妨在这些类中使用静态 Logger。
private static final Logger logger = Logger.getLogger(MyClass.class.getName());
Run Code Online (Sandbox Code Playgroud)
然后,当您需要处理日志消息时,只需引用该记录器即可。您的方法所做的事情与静态 Log4J Logger 已经做的事情相同,那么为什么要重新发明轮子呢?
| 归档时间: |
|
| 查看次数: |
62759 次 |
| 最近记录: |