jrivard@gmail.com 6 rokov pred
rodič
commit
4649396d3f

+ 1 - 2
server/src/main/java/password/pwm/config/profile/LdapProfile.java

@@ -35,7 +35,6 @@ import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigurationImpl;
 import password.pwm.config.value.data.UserPermission;
 import password.pwm.error.PwmUnrecoverableException;
-import password.pwm.ldap.LdapPermissionTester;
 import password.pwm.svc.cache.CacheKey;
 import password.pwm.svc.cache.CachePolicy;
 import password.pwm.util.java.StringUtil;
@@ -146,7 +145,7 @@ public class LdapProfile extends AbstractProfile implements Profile
         final boolean enableCanonicalCache = Boolean.parseBoolean( pwmApplication.getConfig().readAppProperty( AppProperty.LDAP_CACHE_CANONICAL_ENABLE ) );
 
         String canonicalValue = null;
-        final CacheKey cacheKey = CacheKey.newKey( LdapPermissionTester.class, null, "canonicalDN-" + this.getIdentifier() + "-" + dnValue );
+        final CacheKey cacheKey = CacheKey.newKey( LdapProfile.class, null, "canonicalDN-" + this.getIdentifier() + "-" + dnValue );
         if ( enableCanonicalCache )
         {
             final String cachedDN = pwmApplication.getCacheService().get( cacheKey, String.class );

+ 7 - 3
server/src/main/java/password/pwm/svc/cache/CacheDebugItem.java

@@ -22,14 +22,18 @@
 
 package password.pwm.svc.cache;
 
+import lombok.Builder;
 import lombok.Value;
 
 import java.io.Serializable;
 
 @Value
+@Builder
 class CacheDebugItem implements Serializable
 {
-    private CacheKey cacheKey;
-    private String age;
-    private int chars;
+    private final String srcClass;
+    private final String userIdentity;
+    private final String valueID;
+    private final String age;
+    private final int chars;
 }

+ 19 - 15
server/src/main/java/password/pwm/svc/cache/CacheService.java

@@ -29,17 +29,20 @@ import password.pwm.error.PwmException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.health.HealthRecord;
 import password.pwm.svc.PwmService;
+import password.pwm.util.java.ConditionalTaskExecutor;
 import password.pwm.util.java.JsonUtil;
-import password.pwm.util.java.TimeDuration;
 import password.pwm.util.logging.PwmLogger;
 
 import java.io.Serializable;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
 
 public class CacheService implements PwmService
 {
@@ -49,7 +52,7 @@ public class CacheService implements PwmService
 
     private STATUS status = STATUS.NEW;
 
-    private Instant lastTraceOutput;
+    private ConditionalTaskExecutor traceDebugOutputter;
 
     @Override
     public STATUS status( )
@@ -86,6 +89,10 @@ public class CacheService implements PwmService
         status = STATUS.OPENING;
         final int maxMemItems = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.CACHE_MEMORY_MAX_ITEMS ) );
         memoryCacheStore = new MemoryCacheStore( maxMemItems );
+        this.traceDebugOutputter = new ConditionalTaskExecutor(
+                ( ) -> outputTraceInfo(),
+                new ConditionalTaskExecutor.TimeDurationPredicate( 1, TimeUnit.MINUTES )
+        );
         status = STATUS.OPEN;
     }
 
@@ -104,7 +111,10 @@ public class CacheService implements PwmService
     @Override
     public ServiceInfoBean serviceInfo( )
     {
-        return new ServiceInfoBean( Collections.emptyList() );
+        final Map<String, String> debugInfo = new TreeMap<>( );
+        debugInfo.putAll( JsonUtil.deserializeStringMap( JsonUtil.serialize( memoryCacheStore.getCacheStoreInfo() ) ) );
+        debugInfo.putAll( JsonUtil.deserializeStringMap( JsonUtil.serializeMap( memoryCacheStore.storedClassHistogram( "histogram." ) ) ) );
+        return new ServiceInfoBean( Collections.emptyList(), debugInfo );
     }
 
     public Map<String, Serializable> debugInfo( )
@@ -112,6 +122,7 @@ public class CacheService implements PwmService
         final Map<String, Serializable> debugInfo = new LinkedHashMap<>( );
         debugInfo.put( "memory-statistics", memoryCacheStore.getCacheStoreInfo() );
         debugInfo.put( "memory-items", new ArrayList<Serializable>( memoryCacheStore.getCacheDebugItems() ) );
+        debugInfo.put( "memory-histogram", new HashMap<>( memoryCacheStore.storedClassHistogram( "" ) ) );
         return Collections.unmodifiableMap( debugInfo );
     }
 
@@ -136,11 +147,11 @@ public class CacheService implements PwmService
         }
         final Instant expirationDate = cachePolicy.getExpiration();
         memoryCacheStore.store( cacheKey, expirationDate, payload );
-        outputTraceInfo();
+
+        traceDebugOutputter.conditionallyExecuteTask();
     }
 
     public <T> T get( final CacheKey cacheKey, final Class<T> classOfT  )
-            throws PwmUnrecoverableException
     {
         if ( cacheKey == null )
         {
@@ -158,28 +169,21 @@ public class CacheService implements PwmService
             payload = memoryCacheStore.read( cacheKey, classOfT );
         }
 
-        outputTraceInfo();
+        traceDebugOutputter.conditionallyExecuteTask();
 
         return (T) payload;
     }
 
     private void outputTraceInfo( )
     {
-        if ( lastTraceOutput == null || TimeDuration.fromCurrent( lastTraceOutput ).isLongerThan( 30 * 1000 ) )
-        {
-            lastTraceOutput = Instant.now();
-        }
-        else
-        {
-            return;
-        }
-
         final StringBuilder traceOutput = new StringBuilder();
         if ( memoryCacheStore != null )
         {
             final CacheStoreInfo info = memoryCacheStore.getCacheStoreInfo();
             traceOutput.append( ", memCache=" );
             traceOutput.append( JsonUtil.serialize( info ) );
+            traceOutput.append( ", histogram=" );
+            traceOutput.append( JsonUtil.serializeMap( memoryCacheStore.storedClassHistogram( "" ) ) );
         }
         LOGGER.trace( traceOutput );
     }

+ 27 - 1
server/src/main/java/password/pwm/svc/cache/MemoryCacheStore.java

@@ -37,6 +37,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
 class MemoryCacheStore implements CacheStore
 {
@@ -103,7 +104,18 @@ class MemoryCacheStore implements CacheStore
             final Instant storeDate = cacheValueWrapper.getExpirationDate();
             final String age = Duration.between( storeDate, Instant.now() ).toString();
             final int chars = JsonUtil.serialize( cacheValueWrapper.getPayload() ).length();
-            final CacheDebugItem cacheDebugItem = new CacheDebugItem( cacheKey, age, chars );
+            final String keyClass = cacheKey.getSrcClass() == null ? "null" : cacheKey.getSrcClass().getName();
+            final String keyUserID = cacheKey.getUserIdentity() == null ? "null" : cacheKey.getUserIdentity().toDisplayString();
+            final String keyValue = cacheKey.getValueID() == null ? "null" : cacheKey.getValueID();
+
+            final CacheDebugItem cacheDebugItem = CacheDebugItem.builder()
+                    .srcClass( keyClass )
+                    .userIdentity( keyUserID )
+                    .valueID( keyValue )
+                    .age( age )
+                    .chars( chars )
+                    .build();
+
             items.add( cacheDebugItem );
         }
         return Collections.unmodifiableList( items );
@@ -117,4 +129,18 @@ class MemoryCacheStore implements CacheStore
         private final Instant expirationDate;
         private final Serializable payload;
     }
+
+    Map<String, Integer> storedClassHistogram( final String prefix )
+    {
+        final Map<String, Integer> output = new TreeMap<>(  );
+        for ( final CacheKey cacheKey : memoryStore.asMap().keySet() )
+        {
+            final String className = cacheKey.getSrcClass() == null ? "n/a" : cacheKey.getSrcClass().getSimpleName();
+            final String key = prefix + className;
+            final Integer currentValue = output.getOrDefault( key, 0 );
+            final Integer newValue = currentValue + 1;
+            output.put( key, newValue );
+        }
+        return output;
+    }
 }