2017-04-07 632 views
3

我想在调试日志中编写一些日志,这些日志在具有信息日志级别的生产日志中将不可用。那么这个额外的调试日志将如何影响性能?我的意思是如果我们在INFO中设置日志级别,记录器必须检查日志级别是什么,并发现log.debug需要被忽略。那么额外的日志级别检查是否会影响性能?在部署时是否有任何删除log.debug()语句的自动方法?我的意思是在开发期间,log.debug将在那里,我们可以调试。但在生产部署期间,automagical机制将删除所有log.debug()消息。我不确定这些是否可能。如果不是那么好 - C'est la vie!log.debug是否会降低性能

+1

当然,它会影响性能。问题在于它会如何影响性能。答案是,这取决于你记录什么,因为PARAMS到'log'仍将即使没有日志输出评价。解决此问题的方法是针对一个静态变量的检查,然后可以优化掉来包装你的日志报表,或进入一个记录块之前检查日志级别。问题是它是否值得。 –

回答

2

那么这个额外的调试日志将如何影响性能呢?

为记录仪盘I/O调用(假设你正在写文件系统),绝对不建议在生产环境DEBUG日志级别它会影响应用程序的性能。

是否有任何automagical方式在部署时删除log.debug()语句 ?

没有,是去除log.debug()报表没有神奇的方式,但是当你设置日志记录级别为INFO,那么只要你是不是做重的计算,同时传递参数给debug()方法,它应该没事的。例如,如果您有记录级别设置为INFO,并假定你已经得到了空两个记录器在你的代码

logger.debug(" Entry:: "); //this logger is fine, no calculations 
//Below logger, you are doing computations to print i.e., calling to String methods 
logger.debug(" Entry : product:"+product+" dept:"+dept);//overhead toString() calls 

我建议使用slf4j,这样就可以避免被第二记录计算开销

//Below logger product and dept toString() NOT invoked 
logger.debug(" Entry : product:{} dept{}", product, dept); 

一个更重要的一点是,与SLF4J只是一个抽象:如下图所示使用{}(其中使用它的MessageFormatter与实际值替换)您可以在任何日志框架之间切换,您可以在here以下看看下面的文本。

的简单的日志门面为Java(SLF4J)用作一个简单的门面 或抽象的各种日志框架(例如java.util.logging中, 的logback,log4j的),允许最终用户在所希望的记录堵塞 框架在部署时。

+0

难道我们不能使用具有相同的特征,因为sl4j的log4j2? – user1539343

+0

是的,它是你的,要么log4j2或SLF4J是(如上所示)相比log4j1.x避免'DEBUG'开销肯定更好的选择 – developer

1

你可以用你的“调试”语句调用isDebugEnabled()

if (log.isDebugEnabled()) { 
    log.debug("my debug statement"); 
} 

同样,包住“信息”语句调用isInfoEnabled()

的想法这样做背后检查日志级别是否被启用是一种廉价(固定成本)操作。生成正在记录的语句的成本取决于您在做什么。

1

检查日志记录级别的开销是非常少的,几乎可以忽略。启用调试日志时,您会看到对性能的重大影响。这种影响取决于您写入日志的数据量,存储量(如果您的存储是固态硬盘,与使用正常磁盘时的性能相比,性能降低幅度较小),则有多少线程会写入日志(自只有一个线程可以立即写入文件,所有其他线程必须等待,这是一个顺序过程)。我已经提到了三个,但是还有更多的因素决定了日志记录对应用程序性能的影响。

要回答你的第二个问题是没有自动的方式从你的代码中删除调试语句。

2

你可以通过你如何编写记录语句尽量减少这种。如果你写

Object a = .... 
log.debug("I have an a: " + a); 

然后不管你使用的参数的日志框架必须在调试功能运行之前进行评估。这意味着,即使你在INFO水平,你付出呼吁atoString和构建参数字符串的性能开销。如果您改为写例如(这取决于格式化你的日志框架使用,该工程的log4j和SLF4J)

log.debug("I have an a: {}", a); 

您不支付这笔费用,但只记录器检查您是否在调试模式是成本 - 除非你需要它,你不支付参数评估。

的另一件事是检查你正在缓冲输出(同样,在SLF4J,有缓冲追加程序),这将最大限度地减少写入。

1

,我想指出的另一种技术,往往在Android开发应用,是可以后期处理您的罐子里取出电话,如调试。使用的工具通常是proguard。如果定义了呼叫作为无副作用,它可以被优化,确保几乎为零的性能损失被删除....它甚至应该是足够聪明的优化掉你正在做的日志信息的任何字符串建设。

https://www.guardsquare.com/en/proguard/manual/usage#assumenosideeffects