feat: add performance debug logging (wip)
diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
index d216586..8cd7341 100644
--- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
@@ -107,8 +107,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@Component(immediate = true, service={ ModelFactory.class, ServletRequestListener.class },
- property= { HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER+"=true",
+@Component(immediate = true, service={ ModelFactory.class, ServletRequestListener.class },
+ property= { HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER+"=true",
HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT+"=(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)" })
@Designate(ocd=ModelAdapterFactoryConfiguration.class)
@SuppressWarnings("deprecation")
@@ -217,6 +217,7 @@
}
private static final Logger log = LoggerFactory.getLogger(ModelAdapterFactory.class);
+ private static final Logger perfLog = LoggerFactory.getLogger(ModelAdapterFactory.class.getName() + "-perf");
private final @NotNull ConcurrentMap<String, RankedServices<Injector>> injectors = new ConcurrentHashMap<>();
private final @NotNull RankedServices<Injector> sortedInjectors = new RankedServices<>();
@@ -242,7 +243,7 @@
@Reference
BindingsValuesProvidersByContext bindingsValuesProvidersByContext;
- @Reference
+ @Reference
AdapterManager adapterManager;
ModelPackageBundleListener listener;
@@ -267,7 +268,7 @@
@Override
public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
- Result<AdapterType> result = internalCreateModel(adaptable, type);
+ Result<AdapterType> result = internalCreateModelMeasured(adaptable, type);
if (!result.wasSuccessful()) {
log.warn("Could not adapt to model", result.getThrowable());
return null;
@@ -279,7 +280,7 @@
@Override
public @NotNull <ModelType> ModelType createModel(@NotNull Object adaptable, @NotNull Class<ModelType> type) throws MissingElementsException,
InvalidAdaptableException, ValidationException, InvalidModelException {
- Result<ModelType> result = internalCreateModel(adaptable, type);
+ Result<ModelType> result = internalCreateModelMeasured(adaptable, type);
if (!result.wasSuccessful()) {
throw result.getThrowable();
}
@@ -345,7 +346,7 @@
// throw exception here
throw new ModelClassException("Could not yet find an adapter factory for the model " + requestedType + " from adaptable " + adaptable.getClass());
}
-
+
@SuppressWarnings("unchecked")
private Map<Class<?>, SoftReference<Object>> getOrCreateCache(final Object adaptable) {
Map<Class<?>, SoftReference<Object>> adaptableCache;
@@ -361,7 +362,32 @@
}
return adaptableCache;
}
-
+
+
+ private <ModelType> Result<ModelType> internalCreateModelMeasured(@NotNull Object adaptable, @NotNull Class<ModelType> type) {
+ Result<ModelType> result;
+ if (perfLog.isDebugEnabled()) {
+ long startTime = perfLog.isDebugEnabled() ? System.nanoTime() : -1;
+ ThreadInvocationCounter threadInvocationCounter = invocationCountThreadLocal.get();
+ threadInvocationCounter.resetStats();
+
+ result = internalCreateModel(adaptable, type);
+
+ double duration = ((double) System.nanoTime() - startTime) / 1000000.0;
+
+ perfLog.debug("createdModel({},{}) took {}ms, instantiations {}, max recursion {}",
+ adaptable.getClass().getName(),
+ type.getName(),
+ duration,
+ threadInvocationCounter.getOverallCount(),
+ threadInvocationCounter.getMaxRecursion());
+ } else {
+ result = internalCreateModel(adaptable, type);
+ }
+
+ return result;
+ }
+
@SuppressWarnings("unchecked")
private <ModelType> Result<ModelType> internalCreateModel(final Object adaptable, final Class<ModelType> requestedType) {
Result<ModelType> result;
@@ -1285,7 +1311,7 @@
if (clazz == null) {
throw new ModelClassException("Could find model registered for resource type: " + resource.getResourceType());
}
- return handleBoundModelResult(internalCreateModel(resource, clazz));
+ return handleBoundModelResult(internalCreateModelMeasured(resource, clazz));
}
@Override
@@ -1294,7 +1320,7 @@
if (clazz == null) {
throw new ModelClassException("Could find model registered for request path: " + request.getServletPath());
}
- return handleBoundModelResult(internalCreateModel(request, clazz));
+ return handleBoundModelResult(internalCreateModelMeasured(request, clazz));
}
private Object handleBoundModelResult(Result<?> result) {
@@ -1324,7 +1350,7 @@
if (clazz == null) {
throw new ModelClassException("Could find model registered for resource type: " + resource.getResourceType());
}
- Result<?> result = internalCreateModel(resource, clazz);
+ Result<?> result = internalCreateModelMeasured(resource, clazz);
return handleAndExportResult(result, name, targetClass, options);
}
@@ -1335,7 +1361,7 @@
if (clazz == null) {
throw new ModelClassException("Could find model registered for request path: " + request.getServletPath());
}
- Result<?> result = internalCreateModel(request, clazz);
+ Result<?> result = internalCreateModelMeasured(request, clazz);
return handleAndExportResult(result, name, targetClass, options);
}
diff --git a/src/main/java/org/apache/sling/models/impl/ThreadInvocationCounter.java b/src/main/java/org/apache/sling/models/impl/ThreadInvocationCounter.java
index b386aa5..e1c454e 100644
--- a/src/main/java/org/apache/sling/models/impl/ThreadInvocationCounter.java
+++ b/src/main/java/org/apache/sling/models/impl/ThreadInvocationCounter.java
@@ -21,6 +21,8 @@
class ThreadInvocationCounter {
private int count;
+ private int max;
+ private int overallCount;
final int maxRecursionDepth;
@@ -28,12 +30,29 @@
this.maxRecursionDepth = maxRecursionDepth;
}
+ public void resetStats() {
+ max = 0;
+ overallCount = 0;
+ }
+
+ public int getMaxRecursion() {
+ return max;
+ }
+
+ public int getOverallCount() {
+ return overallCount;
+ }
+
public boolean isMaximumReached() {
return count >= maxRecursionDepth;
}
public void increase() {
this.count++;
+ this.overallCount++;
+ if (count > max) {
+ max = count;
+ }
}
public void decrease() {