1. 選擇合理的日志級別、合理控制日志內容
2. 控制日志的輸出內容和格式
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
logger.debug("Entry number: {} is {}", i, entry[i]);
上面兩條語句在日志輸出上的效果是一樣的,但是開銷不一樣,主要的影響在於字符串轉換和字符串拼接上,無論是否生效,前者都會將變量轉換為字符串並進行拼接,而后者則只會在需要時執行這些操作。Log4J官方的測試結論是兩者在性能上能相差兩個數量級。試想一下,如果某個對象的toString()方法里用了ToStringBuilder來反射輸出幾十個屬性時,這時能省下多少資源。
因此,某些仍在使用Log4J 1.x或Apache Commons Logging(它們不支持{}模板的寫法)的公司都會有相應的編碼規范,要求在一定級別的日志(比如DEBUG和INFO)輸出前增加判斷:
if (logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); }
除了日志級別和日志消息,通常在日志中還會包含一些其他信息,比如日期、線程名、類信息、MDC變量等等,根據Takipi的測試,如果在日志中加入class,性能會急劇下降,比起LogBack的默認配置,吞吐量的降幅在6成左右。如果一定要打印類信息,可以考慮用類名來命名Logger。
在分布式系統中,一個請求可能會經過多個不同的子系統,這時最好生成一個UUID附在請求中,每個子系統在打印日志時都將該UUID放在MDC里,便於后續查詢相關的日志。
http://www.infoq.com/cn/articles/things-of-java-log-performance