From d628735612dd634254c690ef71c04846e7d9c58c Mon Sep 17 00:00:00 2001 From: William Thurston Date: Sat, 18 Feb 2017 17:03:30 -0800 Subject: [PATCH] Only generate blitz location info when using NFPatternLayout to avoid costly stack creation. --- .../com/netflix/blitz4j/LoggingContext.java | 51 +++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/netflix/blitz4j/LoggingContext.java b/src/main/java/com/netflix/blitz4j/LoggingContext.java index 329d8b9..3b86ae3 100644 --- a/src/main/java/com/netflix/blitz4j/LoggingContext.java +++ b/src/main/java/com/netflix/blitz4j/LoggingContext.java @@ -16,10 +16,17 @@ package com.netflix.blitz4j; +import java.util.Enumeration; import java.util.concurrent.TimeUnit; +import com.netflix.logging.log4jAdapter.NFPatternLayout; +import org.apache.log4j.Appender; +import org.apache.log4j.Category; import org.apache.log4j.Level; +import org.apache.log4j.Logger; import org.apache.log4j.MDC; +import org.apache.log4j.helpers.AppenderAttachableImpl; +import org.apache.log4j.spi.AppenderAttachable; import org.apache.log4j.spi.LocationInfo; import org.apache.log4j.spi.LoggingEvent; @@ -157,11 +164,14 @@ public LocationInfo generateLocationInfo(LoggingEvent event) { } LocationInfo locationInfo = null; try { - locationInfo = (LocationInfo) LoggingContext - .getInstance() - .getLocationInfo(Class.forName(event.getFQNOfLoggerClass())); - if (locationInfo != null) { - MDC.put(LOCATION_INFO, locationInfo); + // We should only generate location info if the caller is using NFPatternLayout otherwise this is expensive and unused. + if (isUsingNFPatternLayout(event)) { + locationInfo = (LocationInfo) LoggingContext + .getInstance() + .getLocationInfo(Class.forName(event.getFQNOfLoggerClass())); + if (locationInfo != null) { + MDC.put(LOCATION_INFO, locationInfo); + } } } catch (Throwable e) { if (CONFIGURATION !=null && CONFIGURATION @@ -172,6 +182,37 @@ public LocationInfo generateLocationInfo(LoggingEvent event) { return locationInfo; } + private boolean isUsingNFPatternLayout(LoggingEvent event) { + final Category logger = event.getLogger(); + return logger != null && isUsingNFPatternLayout(logger.getAllAppenders()); + + } + + private boolean isUsingNFPatternLayout(Enumeration enumeration) { + if (enumeration == null) { + return false; + } + + while(enumeration.hasMoreElements()) { + Object maybeAppender = enumeration.nextElement(); + if (maybeAppender instanceof Appender) { + Appender a = (Appender) maybeAppender; + if (a.getLayout() instanceof NFPatternLayout) { + return true; + } + } + + if (maybeAppender instanceof AppenderAttachable) { + AppenderAttachable aa = (AppenderAttachable) maybeAppender; + if (isUsingNFPatternLayout(aa.getAllAppenders())) { + return true; + } + } + } + + return false; + } + /** * Get the location information of the logging event. If the information has * been cached it is retrieved from the MDC (for asynchronous events MDCs