adaptive-caching-framework
Changes
evaluation/applications/AP/CloudStore/src/main/java/eu/cloudscale/showcase/Configuration.java 2(+1 -1)
evaluation/applications/AP/spring-petclinic/src/main/java/org/springframework/samples/petclinic/Configuration.java 2(+1 -1)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/Analyzer.java 37(+15 -22)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/AdaptiveMethodCacher.java 37(+10 -27)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/MethodCacher.java 4(+2 -2)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/caffeine/CaffeineCache.java 2(+1 -1)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/ehcache/EhCacheCache.java 2(+1 -1)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/guava/GuavaCache.java 2(+1 -1)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/configuration/annotation/AdaptiveCaching.java 4(+2 -2)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/support/Tracer.java 2(+0 -2)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/TracerAspect.java 181(+116 -65)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/cache/vendors/guava/GuavaMonitor.java 1(+0 -1)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/storage/providers/RedisRepository.java 1(+0 -1)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/DataFiltering.java 75(+75 -0)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightAnalyzer.java 93(+49 -44)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetricAspect.java 177(+73 -104)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetrics.java 131(+69 -62)
framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/statistics/StatisticalTest.java 7(+5 -2)
framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/Learner.java 2(+1 -1)
framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/tests/adaptivecaching/CacheableTest.java 6(+1 -5)
README.md 2(+1 -1)
Details
diff --git a/evaluation/applications/AP/CloudStore/pom.xml b/evaluation/applications/AP/CloudStore/pom.xml
index 145fd8a..daff975 100644
--- a/evaluation/applications/AP/CloudStore/pom.xml
+++ b/evaluation/applications/AP/CloudStore/pom.xml
@@ -185,7 +185,7 @@
<dependency>
<groupId>br.ufrgs.inf.prosoft.adaptivecaching</groupId>
<artifactId>autonomicmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
diff --git a/evaluation/applications/AP/CloudStore/src/main/java/eu/cloudscale/showcase/Configuration.java b/evaluation/applications/AP/CloudStore/src/main/java/eu/cloudscale/showcase/Configuration.java
index fc0a6c5..cf4155e 100644
--- a/evaluation/applications/AP/CloudStore/src/main/java/eu/cloudscale/showcase/Configuration.java
+++ b/evaluation/applications/AP/CloudStore/src/main/java/eu/cloudscale/showcase/Configuration.java
@@ -7,7 +7,7 @@ import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.Model
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.RepositoryType;
@AdaptiveCaching(cacheProvider = CacheProviderType.EHCACHE, logRepository = RepositoryType.MEMORY,
- modelling = Modelling.FULLEXPLORATION, analyzerEnabled = true, enabled = true, disableMonitoringAfterAnalysis = true,
+ modelling = Modelling.FULLEXPLORATION, analyzerEnabled = true, enabled = true, disableMonitoringAfterAnalysis = false,
clearMonitoringDataOnStart = true, traceAsync = false, tracerEnabled = true, analyzeOnce = true, expiryInterval = 86400)
@ComponentScan(allowed = "eu.cloudscale.showcase", denied = {"eu.cloudscale.showcase.db.model", "eu.cloudscale.showcase.servlets", "eu.cloudscale.showcase.db.dao.hibernate"})
public class Configuration {
diff --git a/evaluation/applications/AP/spring-petclinic/pom.xml b/evaluation/applications/AP/spring-petclinic/pom.xml
index be0e136..7974415 100644
--- a/evaluation/applications/AP/spring-petclinic/pom.xml
+++ b/evaluation/applications/AP/spring-petclinic/pom.xml
@@ -231,6 +231,11 @@
<artifactId>autonomicmanager</artifactId>
<version>0.6.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongo-java-driver</artifactId>
+ <version>3.2.2</version>
+ </dependency>
</dependencies>
<!-- Maven plugin versions are mentioned in order to guarantee the build reproducibility in the long term -->
diff --git a/evaluation/applications/AP/spring-petclinic/src/main/java/org/springframework/samples/petclinic/Configuration.java b/evaluation/applications/AP/spring-petclinic/src/main/java/org/springframework/samples/petclinic/Configuration.java
index eaec9c8..cd3eda3 100644
--- a/evaluation/applications/AP/spring-petclinic/src/main/java/org/springframework/samples/petclinic/Configuration.java
+++ b/evaluation/applications/AP/spring-petclinic/src/main/java/org/springframework/samples/petclinic/Configuration.java
@@ -8,7 +8,7 @@ import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.Repos
import br.ufrgs.inf.prosoft.adaptivecaching.sampling.annotations.Criteria;
@AdaptiveCaching(cacheProvider = CacheProviderType.EHCACHE, logRepository = RepositoryType.MEMORY,
- modelling = Modelling.FULLEXPLORATION, analyzerEnabled = true, enabled = true, disableMonitoringAfterAnalysis = true,
+ modelling = Modelling.FULLEXPLORATION, analyzerEnabled = true, enabled = true, disableMonitoringAfterAnalysis = false,
clearMonitoringDataOnStart = true, traceAsync = false, tracerEnabled = true, analyzeOnce = true, expiryInterval = 60)
@Criteria("more frequent I more expensive")
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/Analyzer.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/Analyzer.java
index 36b87a7..6dd5d5d 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/Analyzer.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/Analyzer.java
@@ -2,33 +2,15 @@ package br.ufrgs.inf.prosoft.adaptivecaching.analysis;
import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.FlowchartWorkFlow;
import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodEntry;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.CacheabilityMetrics;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.extensions.guava.GuavaCache;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.extensions.guava.GuavaCacheManager;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.Cache;
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.AdaptiveCaching;
-import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.CacheProviderType;
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.Modelling;
-import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.RepositoryType;
-import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.TriggerType;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.aspects.TracerAspect;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.LogTrace;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheInfo;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheMonitor;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.vendors.guava.GuavaMonitor;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.providers.MongoRepository;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.Repository;
-import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightAnalyzer;
-import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightMetricAspect;
-import com.mongodb.MongoClient;
-import com.mongodb.client.MongoDatabase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintWriter;
-import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -57,10 +39,21 @@ public class Analyzer implements Runnable {
@Override
public void run() {
- if (!TracerAspect.analyzerEnabled) {
- logger.info("Analyzer disabled, not running...");
- return;
- }
+// while(!TracerAspect.analyzerEnabled){
+// try {
+// logger.info("Analyzer disabled, waiting 30 seconds to check again...");
+// Thread.sleep(30000);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// }
+
+// logger.info("Analyzer enable, waiting 120 seconds to start...");
+// try {
+// Thread.sleep(120000);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
List all = dataSource.findAll();
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/AdaptiveMethodCacher.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/AdaptiveMethodCacher.java
index f712049..6d06026 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/AdaptiveMethodCacher.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/AdaptiveMethodCacher.java
@@ -25,11 +25,16 @@ public class AdaptiveMethodCacher implements MethodCacher {
}
@Override
- public Object cache(Object key, ProceedingJoinPoint joinPoint) throws Throwable {
+ public void putInCache(Object key, Object result) throws Throwable {
+ if (result != null) {
+ cache.put(key, result);
+ logger.debug(key + " with value: " + result + " set in cachemanager");
+ }
+ }
+
+ @Override
+ public Object getFromCache(Object key) throws Throwable {
- //already calculated
- //final Key key = new Key(joinPoint);
- //final SimpleKey key = (SimpleKey) joinPointKeyGenerator.generate(joinPoint);
ValueWrapper value = cache.get(key);
if (value != null) {
@@ -37,29 +42,7 @@ public class AdaptiveMethodCacher implements MethodCacher {
return value.get();
}
- Object result;
- try {
- result = joinPoint.proceed();
- } catch (Exception ex) {
- throw ex;
- }
-
- if (result != null) {
- //todo maximize such decision
- //maybe getcache info a lot can lead to a performance problem
-// if(cacheMonitor.getCacheInfo().getFreeSpace() > 0) {
- cache.put(key, result);
- logger.debug(key + " with value: " + result + " set in cachemanager");
-// }
- }
-
- return result;
- }
-
- @Override
- public Object cache(ProceedingJoinPoint joinPoint) throws Throwable {
- final Key key = new Key(joinPoint);
- return cache(key, joinPoint);
+ return null;
}
@Override
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/MethodCacher.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/MethodCacher.java
index 63226d2..4a8a053 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/MethodCacher.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/cacher/MethodCacher.java
@@ -4,9 +4,9 @@ import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public interface MethodCacher {
- Object cache(final Object key, final ProceedingJoinPoint joinPoint) throws Throwable;
+ void putInCache(final Object key, Object result) throws Throwable;
- Object cache(final ProceedingJoinPoint joinPoint) throws Throwable;
+ Object getFromCache(final Object key) throws Throwable;
void preflush(final JoinPoint joinPoint);
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/caffeine/CaffeineCache.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/caffeine/CaffeineCache.java
index b351080..6b47fed 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/caffeine/CaffeineCache.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/caffeine/CaffeineCache.java
@@ -1,7 +1,7 @@
package br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.extensions.caffeine;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.support.AbstractValueAdaptingCache;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.ValueWrapper;
+import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.support.AbstractValueAdaptingCache;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.springframework.lang.UsesJava8;
import org.springframework.util.Assert;
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/ehcache/EhCacheCache.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/ehcache/EhCacheCache.java
index b775f2f..7266996 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/ehcache/EhCacheCache.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/ehcache/EhCacheCache.java
@@ -1,8 +1,8 @@
package br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.extensions.ehcache;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.Cache;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.support.SimpleValueWrapper;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.ValueWrapper;
+import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.support.SimpleValueWrapper;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.Status;
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/guava/GuavaCache.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/guava/GuavaCache.java
index 80b934d..a3d4002 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/guava/GuavaCache.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/cachemanager/extensions/guava/GuavaCache.java
@@ -1,7 +1,7 @@
package br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.extensions.guava;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.support.AbstractValueAdaptingCache;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.ValueWrapper;
+import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.support.AbstractValueAdaptingCache;
import com.google.common.cache.CacheStats;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException;
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/configuration/annotation/AdaptiveCaching.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/configuration/annotation/AdaptiveCaching.java
index d113d49..de6d11d 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/configuration/annotation/AdaptiveCaching.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/configuration/annotation/AdaptiveCaching.java
@@ -27,8 +27,8 @@ public @interface AdaptiveCaching {
@Deprecated long firstExpiry() default 300000; //5 minutes
//todo when analysis based on trigger do not make sense to have this, its similar to trigger by time
- @Deprecated long analysisInterval() default 600000; //10 minutes
- @Deprecated long firstAnalysis() default 240000; //4 minutes
+ @Deprecated long analysisInterval() default 1200000; //20 minutes
+ @Deprecated long firstAnalysis() default 120000; //2 minutes
TriggerType triggerType() default TriggerType.TIME; //if were not by time, load the class that implements the interface @Trigger
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/support/Tracer.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/support/Tracer.java
index f9a82b6..86982bf 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/support/Tracer.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/support/Tracer.java
@@ -6,8 +6,6 @@ import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Objects;
-
/**
* @deprecated used to trace methods async, not working due to hibernate sessions...
*/
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/TracerAspect.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/TracerAspect.java
index 49bef4a..411c503 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/TracerAspect.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/TracerAspect.java
@@ -4,9 +4,11 @@ import br.ufrgs.inf.prosoft.adaptivecaching.analysis.Analyzer;
import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodEntry;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.cacher.AdaptiveMethodCacher;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.cacher.key.Key;
+import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.ValueWrapper;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.util.threads.NamedThreads;
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.AdaptiveCaching;
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.ComponentScan;
+import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.RepositoryType;
import br.ufrgs.inf.prosoft.adaptivecaching.exceptions.CacheProviderException;
import br.ufrgs.inf.prosoft.adaptivecaching.exceptions.ConfigurationException;
import br.ufrgs.inf.prosoft.adaptivecaching.exceptions.StorageException;
@@ -18,12 +20,9 @@ import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheMonitor;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheMonitorFactory;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.Repository;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.RepositoryFactory;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.providers.MongoRepository;
import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightAnalyzer;
import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightMetricAspect;
-import com.mongodb.MongoClient;
-import com.mongodb.MongoTimeoutException;
-import com.mongodb.client.MongoDatabase;
+import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightMetrics;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@@ -65,28 +64,20 @@ public class TracerAspect {
*/
public static boolean enabled = true;
public static boolean tracerEnabled = true;
+ public static boolean samplingEnabled = false;
+ public static int samplingEach = 2;
public static boolean analyzerEnabled = true;
+ public static boolean lightweightTracerEnabled = true;
private final ScheduledExecutorService analyzerExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
"adaptivecaching-analyzer",
"identifying cacheable methods"
));
- //not used: in case of the framework being responsible for expiring content, ehcache already provides a native feature
- private final ScheduledExecutorService expirationExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
- "adaptivecaching-expiration",
- "expiring old cacheable methods"
- ));
- //not used: in case of offline analysis, which demands cacheable methods to be load from other sources
- private final ScheduledExecutorService loaderExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
- "adaptivecaching-loading",
- "loading cacheable methods from storage (offline analyzed)"
+
+ private final ScheduledExecutorService lightweightAnalyzerExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
+ "lightweight-analyzer",
+ "computing lightweight metrics and setting allowedmethods"
));
- //not used: in case of async tracing
- private final ExecutorService tracerExecutor = Executors.newSingleThreadScheduledExecutor(
- new NamedThreads(
- "adaptivecaching-tracer",
- "tracing methods"
- ));
Logger logger = LoggerFactory.getLogger(TracerAspect.class);
//traceable configuration
@@ -101,6 +92,9 @@ public class TracerAspect {
private Properties properties;
private UserGetter userGetter;
private Repository repository;
+ private Repository repositoryMongo;
+
+ public static Map<String, LightweightMetrics> metrics;
@Pointcut(
//any execution except the own framework
@@ -115,7 +109,7 @@ public class TracerAspect {
"&& if())"
)
public static boolean anyCall() {
- return enabled;
+ return enabled || lightweightTracerEnabled;
}
//TODO Decouple repository from this
@@ -163,6 +157,7 @@ public class TracerAspect {
repository = RepositoryFactory.getRepository(properties, cachingConfig.logRepository());
+ repositoryMongo = RepositoryFactory.getRepository(properties, RepositoryType.MONGODB);
if (cachingConfig.clearMonitoringDataOnStart()) {
repository.removeAll();
@@ -178,15 +173,7 @@ public class TracerAspect {
this.cacheMonitor = CacheMonitorFactory.getCacheMonitor(this.cacher.getCache(), cachingConfig.cacheProvider());
//TODO load another options from @AdaptiveCaching
-
- //TODO get time from properties or see the external process
- if (cachingConfig.analyzerEnabled()) {
- TracerAspect.analyzerEnabled = true;
- //TODO trigger by time
- analyzerExecutor.scheduleWithFixedDelay(
- new Analyzer(repository, cacheMonitor.getCacheInfo(), cachingConfig),
- cachingConfig.firstAnalysis(), cachingConfig.analysisInterval(), TimeUnit.MILLISECONDS);
- }
+ configureAnalyzer();
//TODO trigger by time
//TODO in some cases (Ehcache) it is better to set a timetolive directly on cache provider
@@ -204,6 +191,12 @@ public class TracerAspect {
methodBlackList = new ArrayList<>();
+ metrics = new HashMap<>();
+ if(lightweightTracerEnabled)
+ lightweightAnalyzerExecutor.scheduleWithFixedDelay(
+ new LightweightAnalyzer(),
+ 60000, 450000, TimeUnit.MILLISECONDS);
+
} catch (ConfigurationException e) {
turnoff();
@@ -217,6 +210,16 @@ public class TracerAspect {
}
}
+ private void configureAnalyzer() {
+ //TODO get time from properties or see the external process
+ if (cachingConfig.analyzerEnabled()) {
+ //TODO trigger by time
+ analyzerExecutor.scheduleWithFixedDelay(
+ new Analyzer(repository, cacheMonitor.getCacheInfo(), cachingConfig),
+ cachingConfig.firstAnalysis(), cachingConfig.analysisInterval(), TimeUnit.MILLISECONDS);
+ } else TracerAspect.analyzerEnabled = false;
+ }
+
@Around("anyCall()")
public Object aroundMethods(ProceedingJoinPoint joinPoint) throws Throwable {
@@ -230,15 +233,37 @@ public class TracerAspect {
Key key = new Key(joinPoint);
//when method is already cached and obtained from it, no trace will be generated
- if (cacheableMethodKeys.contains(key)) {
- this.cacher.cache(key, joinPoint);
+ boolean cacheable = cacheableMethodKeys.contains(key);
+
+ if (cacheable) {
+ Object cachedResult = this.cacher.getFromCache(key);
+ if(cachedResult != null)
+ return cachedResult;
}
- if (tracerEnabled) {
- trace(key, joinPoint);
+ Object result = trace(key, joinPoint);
+
+ if (cacheable && result != null) {
+ this.cacher.putInCache(key, result);
+ logger.debug(key + " with value: " + result + " set in cachemanager");
}
- return joinPoint.proceed();
+ return result;
+ }
+
+ private int samplingIndex = 0;
+ private boolean shouldBeSampled() {
+ if(!samplingEnabled)
+ return true;
+
+// if((rand.nextInt(10) + 1) > samplingChance)
+// return true;
+// synchronized (this){
+ samplingIndex++;
+ if ((samplingIndex % samplingEach) == 0)
+ return true;
+ else return false;
+// }
}
private boolean isAllowed(ProceedingJoinPoint joinPoint) throws Throwable {
@@ -255,16 +280,11 @@ public class TracerAspect {
}
//trace only allowed packages
-// for (String p : allowed) {
-// if (joinPoint.getSignature().toLongString().contains(p)
-// && !methodBlackList.contains(joinPoint.getSignature().toLongString()))
-// return true;
-// }
-
- //trace only allowed by lightweight metrics
- if (LightweightAnalyzer.allowedFineGrained
- .contains(joinPoint.getSignature().toLongString()))
- return true;
+ for (String p : allowed) {
+ if (joinPoint.getSignature().toLongString().contains(p)
+ && !methodBlackList.contains(joinPoint.getSignature().toLongString()))
+ return true;
+ }
return false;
}
@@ -274,33 +294,64 @@ public class TracerAspect {
//method calls can change the args, so it is better to get it at the beginning
Object[] joinPointArgs = joinPoint.getArgs();
+ String signature = joinPoint.getSignature().toString();
+
+ LightweightMetrics metric = null;
+ if(lightweightTracerEnabled) {
+ metric = metrics.get(signature);
+ if (metric != null)
+ metric.incOccurrence();
+ else {
+ String name = joinPoint.getSignature().toString().split(" ")[1];
+ name = name.substring(0, name.indexOf("("));
+ metric = new LightweightMetrics(name, joinPoint.getSignature().toLongString());
+ metric.incOccurrence();
+ if (TracerAspect.analyzerEnabled)
+ metrics.put(signature, metric);
+ }
+ }
+
long startTime = currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = currentTimeMillis();
- //we do not cache null returns, but we trace them
- //maybe the method can sometimes return null... so there is not verification here
- LogTrace logTrace = new LogTrace();
- logTrace.setStartTime(startTime);
- logTrace.setEndTime(endTime);
-
- //TODO declare on properties the class name which implements UserGetter, parse and initialize
- logTrace.setUserId(userGetter.getCurrentUser());
-
- MethodInfo methodInfo = new MethodInfo(joinPoint.getSignature().toLongString(), joinPointArgs, result, key);
- logTrace.setMethodInfo(methodInfo);
-
- try {
- //could not trace async or batch due to database sessions, when saving the session could be closed already
- repository.save(logTrace);
- logger.debug("New trace entry: " + logTrace);// " serialization and save time: " + (System.currentTimeMillis() - la));
- } catch (Exception e) {
- logger.debug("Couldn't trace " + logTrace.getMethodInfo().getSignature() + " due to: " + e.getMessage());// + " process time: " + (System.currentTimeMillis() - la), e);
- logger.debug("Adding " + logTrace.getMethodInfo().getSignature() + " to blacklist");
- TracerAspect.methodBlackList.add(logTrace.getMethodInfo().getSignature());
+ if(lightweightTracerEnabled) {
+ metric.addTime(startTime, endTime - startTime);
+ metric.addReturnSize(result);
+ metric.addUser(userGetter.getCurrentUser());
}
-// traceTime += System.currentTimeMillis() - temp;
+ //trace only allowed by lightweight metrics
+ if(tracerEnabled
+ && ((lightweightTracerEnabled && LightweightAnalyzer.allowedFineGrained
+ .contains(joinPoint.getSignature().toLongString()))
+ || !lightweightTracerEnabled)
+ && shouldBeSampled()) {
+
+ //we do not cache null returns, but we trace them
+ //maybe the method can sometimes return null... so there is not verification here
+ LogTrace logTrace = new LogTrace();
+ logTrace.setStartTime(startTime);
+ logTrace.setEndTime(endTime);
+
+ //TODO declare on properties the class name which implements UserGetter, parse and initialize
+ logTrace.setUserId(userGetter.getCurrentUser());
+
+ MethodInfo methodInfo = new MethodInfo(joinPoint.getSignature().toLongString(), joinPointArgs, result, key);
+ logTrace.setMethodInfo(methodInfo);
+
+ try {
+ //could not trace async or batch due to database sessions, when saving the session could be closed already
+ if (analyzerEnabled)
+ repository.save(logTrace);
+ else repositoryMongo.save(logTrace);
+ logger.debug("New trace entry: " + logTrace);// " serialization and save time: " + (System.currentTimeMillis() - la));
+ } catch (Exception e) {
+ logger.debug("Couldn't trace " + logTrace.getMethodInfo().getSignature() + " due to: " + e.getMessage());// + " process time: " + (System.currentTimeMillis() - la), e);
+ logger.debug("Adding " + logTrace.getMethodInfo().getSignature() + " to blacklist");
+ TracerAspect.methodBlackList.add(logTrace.getMethodInfo().getSignature());
+ }
+ }
return result;
}
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/cache/vendors/guava/GuavaMonitor.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/cache/vendors/guava/GuavaMonitor.java
index 3de4beb..36a7ab5 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/cache/vendors/guava/GuavaMonitor.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/cache/vendors/guava/GuavaMonitor.java
@@ -1,7 +1,6 @@
package br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.vendors.guava;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.extensions.guava.GuavaCache;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.model.Cache;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheInfo;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheMonitor;
import com.google.common.cache.CacheStats;
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/storage/providers/RedisRepository.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/storage/providers/RedisRepository.java
index 2eb2d78..edce5d7 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/storage/providers/RedisRepository.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/storage/providers/RedisRepository.java
@@ -2,7 +2,6 @@ package br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.providers;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.Repository;
import org.redisson.Redisson;
-import org.redisson.api.RBatch;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/DataFiltering.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/DataFiltering.java
new file mode 100644
index 0000000..e6df458
--- /dev/null
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/DataFiltering.java
@@ -0,0 +1,75 @@
+package br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics;
+
+import br.ufrgs.inf.prosoft.adaptivecaching.sampling.statistics.StatisticalTest;
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+
+public class DataFiltering {
+
+ public static boolean isGroup(String group, DescriptiveStatistics criteria, double value){
+
+ boolean isNormal = StatisticalTest.isNormalDistribution(criteria.getValues(), 0.05);
+ DescriptiveStatistics half = new DescriptiveStatistics();
+ if(!isNormal && (group.equals("most") || group.equals("least"))) {
+ for(double val : criteria.getValues())
+ if(group.equals("most") && val >= criteria.getPercentile(75))
+ half.addValue(val);
+ else if(group.equals("least") && val <= criteria.getPercentile(25))
+ half.addValue(val);
+ }
+
+ switch (group){
+ case "normal":
+ if (isNormal)
+ return (value >= (criteria.getMean() - criteria.getStandardDeviation()) &&
+ value <= (criteria.getMean() + criteria.getStandardDeviation()));
+ else
+ return (value >= criteria.getPercentile(25) &&
+ value <= criteria.getPercentile(75));
+ case "more":
+ if (isNormal)
+ return value >= (criteria.getMean() + criteria.getStandardDeviation());
+ else
+ return value >= criteria.getPercentile(75);
+ case "less":
+ if (isNormal)
+ return value <= (criteria.getMean() - criteria.getStandardDeviation());
+ else
+ return value <= criteria.getPercentile(25);
+ case "most":
+ if (isNormal)
+ return value >= (criteria.getMean() + (2*criteria.getStandardDeviation()));
+ else
+ return value >= half.getPercentile(50);
+ case "least":
+ if (isNormal)
+ return value <= (criteria.getMean() + (2*criteria.getStandardDeviation()));
+ else
+ return value <= half.getPercentile(50);
+ }
+
+ throw new RuntimeException("Não foi possível classificar...");
+ }
+
+
+ //
+// //Example: less frequent
+// for(String method : LightweightMetricAspect.metrics.keySet()) {
+// LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
+// if(sc.getFrequency() < (frequencies.getMean() - frequencies.getStandardDeviation()))
+// allowedFineGrained.add(sc.getLongName());
+// }
+//
+// //Example: frequent
+// for(String method : LightweightMetricAspect.metrics.keySet()) {
+// LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
+// if(sc.getFrequency() >= (frequencies.getMean() - frequencies.getStandardDeviation())
+// && sc.getFrequency() <= (frequencies.getMean() + frequencies.getStandardDeviation()))
+// allowedFineGrained.add(sc.getLongName());
+// }
+
+
+ //Example: more frequent U more expensive
+// if(DataFiltering.isGroup("more", frequencies, sc.getFrequency())
+// || DataFiltering.isGroup("more", expensiveness, sc.getFrequency()))
+// allowedFineGrained.add(sc.getLongName());
+}
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightAnalyzer.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightAnalyzer.java
index 9612e1d..c799306 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightAnalyzer.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightAnalyzer.java
@@ -1,5 +1,6 @@
package br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.aspects.TracerAspect;
import br.ufrgs.inf.prosoft.adaptivecaching.sampling.statistics.StatisticalTest;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.slf4j.Logger;
@@ -16,7 +17,7 @@ public class LightweightAnalyzer implements Runnable {
public static void analyze() {
- logger.info("Analyzing {} lightweight methods for relevance", LightweightMetricAspect.metrics.size());
+ logger.info("Analyzing {} lightweight methods for relevance...", TracerAspect.metrics.size());
DescriptiveStatistics frequencies = new DescriptiveStatistics();
DescriptiveStatistics changeabilities = new DescriptiveStatistics();
@@ -26,20 +27,18 @@ public class LightweightAnalyzer implements Runnable {
DescriptiveStatistics userBehaviors = new DescriptiveStatistics();
DescriptiveStatistics concurrencies = new DescriptiveStatistics();
DescriptiveStatistics expensiveness = new DescriptiveStatistics();
- DescriptiveStatistics globalimpact = new DescriptiveStatistics();
- for (String method : LightweightMetricAspect.metrics.keySet()) {
- LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
+ DescriptiveStatistics globalimpacts = new DescriptiveStatistics();
+ for (String method : TracerAspect.metrics.keySet()) {
+ LightweightMetrics sc = TracerAspect.metrics.get(method);
frequencies.addValue(sc.getFrequency());
changeabilities.addValue(sc.getChangeability());
- errorprones.addValue(sc.getStaticErrorprone());
+ errorprones.addValue(sc.getErrorprone());
latencies.addValue(sc.getLatency());
maintainabilities.addValue(sc.getMaintainability());
userBehaviors.addValue(sc.getUserBehavior());
concurrencies.addValue(sc.getConcurrency());
expensiveness.addValue(sc.getExpensiveness());
- globalimpact.addValue(sc.getGlobalImpact());
-
-// System.out.print(sc.getFrequency() + ",");
+ globalimpacts.addValue(sc.getGlobalImpact());
}
System.out.println("---------------------------");
@@ -58,59 +57,65 @@ public class LightweightAnalyzer implements Runnable {
System.out.println("Metric: expensiveness; Distribution: " +
((StatisticalTest.isNormalDistribution(expensiveness.getValues(), 0.05)) ? "normal" : "not_normal"));
System.out.println("Metric: globalimpact; Distribution: " +
- ((StatisticalTest.isNormalDistribution(globalimpact.getValues(), 0.05)) ? "normal" : "not_normal"));
+ ((StatisticalTest.isNormalDistribution(globalimpacts.getValues(), 0.05)) ? "normal" : "not_normal"));
System.out.println("Metric: latency; Distribution: " +
((StatisticalTest.isNormalDistribution(latencies.getValues(), 0.05)) ? "normal" : "not_normal"));
//cleaning selected methods
allowedFineGrained = new HashSet<>();
- //TODO precess SET operations dynamically
+ //TODO process SET operations dynamically
// LightweightMetricAspect.criteriaDSL
-// //Example: more frequent I more expensive
-// for (String method : LightweightMetricAspect.metrics.keySet()) {
-// LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
-//
-// logger.info("Testing {} with frequency {} and expensiveness {}", sc
-// , frequencies.getMean() + frequencies.getStandardDeviation()
-// , expensiveness.getMean() + expensiveness.getStandardDeviation());
-// if (sc.getFrequency() > (frequencies.getMean() + frequencies.getStandardDeviation())
-// && sc.getExpensiveness() > (expensiveness.getMean() + expensiveness.getStandardDeviation()))
-// allowedFineGrained.add(sc.getLongName());
-// }
-
- //Example: more frequent U more expensive
- for(String method : LightweightMetricAspect.metrics.keySet()) {
- LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
- if(sc.getFrequency() > (frequencies.getMean() + frequencies.getStandardDeviation())
- || sc.getExpensiveness() > (expensiveness.getMean() + expensiveness.getStandardDeviation()))
+ //less changeable C more frequent C (more user_behavior U (less user_behavior C more expensive))
+ for(String method : TracerAspect.metrics.keySet()) {
+ LightweightMetrics sc = TracerAspect.metrics.get(method);
+
+// if ((DataFiltering.isGroup("less", changeabilities, sc.getChangeability())
+// || DataFiltering.isGroup("normal", changeabilities, sc.getChangeability()))
+// && (DataFiltering.isGroup("more", frequencies, sc.getFrequency())
+// || DataFiltering.isGroup("normal", frequencies, sc.getFrequency()))
+// && ((DataFiltering.isGroup("more", userBehaviors, sc.getUserBehavior())
+// || DataFiltering.isGroup("normal", userBehaviors, sc.getUserBehavior()))
+// || ((DataFiltering.isGroup("less", userBehaviors, sc.getUserBehavior())
+// || DataFiltering.isGroup("normal", userBehaviors, sc.getUserBehavior()))
+// && (DataFiltering.isGroup("more", expensiveness, sc.getExpensiveness())
+// || DataFiltering.isGroup("more", expensiveness, sc.getExpensiveness())))))
+
+ //less changeable C more frequent C (more user_behavior U (less user_behavior C more expensive))
+ if (DataFiltering.isGroup("less", changeabilities, sc.getChangeability())
+ && DataFiltering.isGroup("more", frequencies, sc.getFrequency())
+ && (DataFiltering.isGroup("more", userBehaviors, sc.getUserBehavior())
+ || (DataFiltering.isGroup("less", userBehaviors, sc.getUserBehavior())
+ && DataFiltering.isGroup("more", expensiveness, sc.getExpensiveness()))))
+
+// if (DataFiltering.isGroup("least", changeabilities, sc.getChangeability())
+// && DataFiltering.isGroup("most", frequencies, sc.getFrequency())
+// && (DataFiltering.isGroup("most", userBehaviors, sc.getUserBehavior())
+// || (DataFiltering.isGroup("least", userBehaviors, sc.getUserBehavior())
+// && DataFiltering.isGroup("most", expensiveness, sc.getExpensiveness()))))
+
+// if (DataFiltering.isGroup("less", changeabilities, sc.getChangeability())
+// && DataFiltering.isGroup("most", frequencies, sc.getFrequency())
+// && DataFiltering.isGroup("most", expensiveness, sc.getExpensiveness()))
+
allowedFineGrained.add(sc.getLongName());
}
logger.info("Selected methods for fine-grained: {}", allowedFineGrained);
-//
-// //Example: less frequent
-// for(String method : LightweightMetricAspect.metrics.keySet()) {
-// LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
-// if(sc.getFrequency() < (frequencies.getMean() - frequencies.getStandardDeviation()))
-// allowedFineGrained.add(sc.getLongName());
-// }
-//
-// //Example: frequent
-// for(String method : LightweightMetricAspect.metrics.keySet()) {
-// LightweightMetrics sc = LightweightMetricAspect.metrics.get(method);
-// if(sc.getFrequency() >= (frequencies.getMean() - frequencies.getStandardDeviation())
-// && sc.getFrequency() <= (frequencies.getMean() + frequencies.getStandardDeviation()))
-// allowedFineGrained.add(sc.getLongName());
-// }
-
+// TracerAspect.enabled = true;
+ TracerAspect.analyzerEnabled = true;
+// LightweightMetricAspect.enabled = true;
}
@Override
public void run() {
- logger.info("Lightweight calculating metrics and updating coarse-monitoring into {} methods...", allowedFineGrained);
+ if (!TracerAspect.lightweightTracerEnabled) {
+ logger.info("Lightweight monitoring disabled...");
+ return;
+ }
+
analyze();
}
}
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetricAspect.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetricAspect.java
index 5d7913f..2b80dde 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetricAspect.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetricAspect.java
@@ -1,16 +1,14 @@
package br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.Analyzer;
import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.util.threads.NamedThreads;
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.AdaptiveCaching;
import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.ComponentScan;
import br.ufrgs.inf.prosoft.adaptivecaching.exceptions.ConfigurationException;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.aspects.TracerAspect;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.usersession.UserGetter;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.usersession.UserGetterFactory;
import br.ufrgs.inf.prosoft.adaptivecaching.sampling.annotations.Criteria;
-import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@@ -23,152 +21,123 @@ import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static java.lang.System.currentTimeMillis;
-@Aspect
+//@Aspect
public class LightweightMetricAspect {
- @Pointcut(
- //any execution except the own framework
- "execution(!void *(..)) && !within(br.ufrgs.inf.prosoft.adaptivecaching..*) " +
- //avoid calls from repository while serializing objects, it is necessary if a hash could not be used
- "&& !cflow(call(* br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage..*(..)))"
- )
- public void anyCall() {
- }
+// public static boolean enabled = true;
+
+// @Pointcut(
+// //any execution except the own framework
+// "(execution(!void *(..)) && !within(br.ufrgs.inf.prosoft.adaptivecaching..*) " +
+// //avoid calls from repository while serializing objects, it is necessary if a hash could not be used
+// "&& !cflow(call(* br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage..*(..)))" +
+// //conditional to enable and disable at runtime
+// "&& if())"
+// )
+// public static boolean anyCall() {
+// return enabled;
+// }
Logger logger = LoggerFactory.getLogger(LightweightMetricAspect.class);
- private final ScheduledExecutorService analyzerExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
- "lightweight-analyzer",
- "computing lightweight metrics and setting allowedmethods"
- ));
+// private final ScheduledExecutorService analyzerExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
+// "lightweight-analyzer",
+// "computing lightweight metrics and setting allowedmethods"
+// ));
- public static Map<String, LightweightMetrics> metrics;
+// public static Map<String, LightweightMetrics> metrics;
private UserGetter userGetter;
//traceable configuration
private String[] allowed;
private String[] notAllowed;
- public static String criteriaDSL = "";
+// public static String criteriaDSL = "";
public LightweightMetricAspect() {
- metrics = new HashMap<>();
+// metrics = new HashMap<>();
userGetter = UserGetterFactory.getInstance();
- Class<?> configClass = getAvailableConfigurationClass();
+// Class<?> configClass = getAvailableConfigurationClass();
//getting criteria DSL
- Criteria criteria = configClass.getAnnotation(Criteria.class);
- criteriaDSL = criteria.value();
+// Criteria criteria = configClass.getAnnotation(Criteria.class);
+// criteriaDSL = criteria.value();
//getting allowed packages from @ComponentScan
- ComponentScan componentScanConfig = configClass.getAnnotation(ComponentScan.class);
- if (componentScanConfig == null) {
- //if not specified, it assumes the same package where @AdaptiveCaching were declared
- allowed = new String[]{configClass.getPackage().getName()};
- //logger.error("ComponenScan for AdaptiveCaching not found, adaptive caching disabled.");
- //enabled = false;
- //return;
- }
- allowed = componentScanConfig.allowed();
- notAllowed = componentScanConfig.denied();
+// ComponentScan componentScanConfig = configClass.getAnnotation(ComponentScan.class);
+// if (componentScanConfig == null) {
+// //if not specified, it assumes the same package where @AdaptiveCaching were declared
+// allowed = new String[]{configClass.getPackage().getName()};
+// //logger.error("ComponenScan for AdaptiveCaching not found, adaptive caching disabled.");
+// //enabled = false;
+// //return;
+// }
+// allowed = componentScanConfig.allowed();
+// notAllowed = componentScanConfig.denied();
logger.info("Lightweight monitoring will trace methods into {} packages...", allowed);
- analyzerExecutor.scheduleWithFixedDelay(
- new LightweightAnalyzer(),
- 60000, 150000, TimeUnit.MILLISECONDS);
+// if(enabled)
+// analyzerExecutor.scheduleWithFixedDelay(
+// new LightweightAnalyzer(),
+// 60000, 450000, TimeUnit.MILLISECONDS);
+// TracerAspect.enabled = false;
}
- @Around("anyCall()")
+// @Around("anyCall()")
public Object aroundMethods(ProceedingJoinPoint joinPoint) throws Throwable {
- if (!isAllowed(joinPoint))
- return joinPoint.proceed();
+// if (!isAllowed(joinPoint))
+// return joinPoint.proceed();
String signature = joinPoint.getSignature().toString();
- LightweightMetrics metric = metrics.get(signature);
- if (metric != null)
- metric.incOccurrence();
- else {
- String name = joinPoint.getSignature().toString().split(" ")[1];
- name = name.substring(0, name.indexOf("("));
- metric = new LightweightMetrics(name, joinPoint.getSignature().toLongString());
- metric.incOccurrence();
- metrics.put(signature, metric);
- }
+// LightweightMetrics metric = metrics.get(signature);
+// if (metric != null)
+// metric.incOccurrence();
+// else {
+// String name = joinPoint.getSignature().toString().split(" ")[1];
+// name = name.substring(0, name.indexOf("("));
+// metric = new LightweightMetrics(name, joinPoint.getSignature().toLongString());
+// metric.incOccurrence();
+// if(TracerAspect.analyzerEnabled)
+// metrics.put(signature, metric);
+// }
//values are given in bytes, divide by 1000000 to get values in MB.
- Runtime runtime = Runtime.getRuntime();
- long startMemory = runtime.totalMemory() - runtime.freeMemory();
+// Runtime runtime = Runtime.getRuntime();
+// long startMemory = runtime.totalMemory() - runtime.freeMemory();
long startTime = currentTimeMillis();
- long startThread = java.lang.Thread.activeCount();
+// long startThread = java.lang.Thread.activeCount();
Object result = joinPoint.proceed();
long endTime = currentTimeMillis();
- metric.addTime(startTime, endTime - startTime);
- long endMemory = runtime.totalMemory() - runtime.freeMemory();
- metric.addMemoryConsumption(endMemory - startMemory);
- long endThread = java.lang.Thread.activeCount();
- metric.addThreadNumber(endThread - startThread);
- metric.addReturnSize(result);
- metric.addUser(userGetter.getCurrentUser());
+// metric.addTime(startTime, endTime - startTime);
+// long endMemory = runtime.totalMemory() - runtime.freeMemory();
+// metric.addMemoryConsumption(endMemory - startMemory);
+// long endThread = java.lang.Thread.activeCount();
+// metric.addThreadNumber(endThread - startThread);
+// metric.addReturnSize(result);
+// metric.addUser(userGetter.getCurrentUser());
return result;
}
- @AfterThrowing(pointcut = "anyCall()", throwing = "e")
- public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
- String signature = joinPoint.getSignature().toString();
- LightweightMetrics metric = metrics.get(signature);
- metric.incThrown();
- }
-
- private boolean isAllowed(ProceedingJoinPoint joinPoint) throws Throwable {
- String signature = joinPoint.getSignature().toString();
- if (signature.contains("br.ufrgs.inf.prosoft.adaptivecaching")) {
- return false;
- }
-
- for (String p : notAllowed) {
- //toString to avoid get the return class as a false positive
- if (signature.contains(p)) {
- return false;
- }
- }
-
- //trace only allowed packages
- for (String p : allowed) {
- if (joinPoint.getSignature().toLongString().contains(p))
- return true;
- }
-
- return false;
- }
-
- private Class<?> getAvailableConfigurationClass() {
- //TODO Decouple??
- Reflections reflections = new Reflections(
- new ConfigurationBuilder()
- .setUrls(ClasspathHelper.forClassLoader())
- .setScanners(new SubTypesScanner(false), new ResourcesScanner(), new TypeAnnotationsScanner()));
-
- //loading @AdaptiveCaching
- Set<Class<?>> configurations =
- reflections.getTypesAnnotatedWith(AdaptiveCaching.class);
- if (configurations.isEmpty())
- throw new ConfigurationException("@AdaptiveCaching not found, adaptive caching disabled.");
- if (configurations.size() > 1)
- throw new ConfigurationException("@AdaptiveCaching has too many definitions, adaptive caching disabled.");
- return configurations.iterator().next();
- }
+// @AfterThrowing(pointcut = "anyCall()", throwing = "e")
+// public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
+// String signature = joinPoint.getSignature().toString();
+// LightweightMetrics metric = metrics.get(signature);
+// metric.incThrown();
+// }
}
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetrics.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetrics.java
index 8538dcf..eca170e 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetrics.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/LightweightMetrics.java
@@ -11,15 +11,14 @@ import java.util.Set;
public class LightweightMetrics {
+ private static SizeOf sizeOf = SizeOf.newInstance();
private long occurrences;
private SummaryStatistics timeStatistics;
- private SummaryStatistics memoryStatistics;
- private SummaryStatistics threadStatistics;
+// private SummaryStatistics memoryStatistics;
+// private SummaryStatistics threadStatistics;
private SummaryStatistics intervalStatistics;
- private long thrownCounter;
private List<Long> startTimes;
private SummaryStatistics returnSizeStatistics;
- private static SizeOf sizeOf = SizeOf.newInstance();
private Set<String> users;
private String name;
private String longName;
@@ -30,8 +29,8 @@ public class LightweightMetrics {
this.longName = longName;
startTimes = new ArrayList<>();
timeStatistics = new SummaryStatistics();
- memoryStatistics = new SummaryStatistics();
- threadStatistics = new SummaryStatistics();
+// memoryStatistics = new SummaryStatistics();
+// threadStatistics = new SummaryStatistics();
returnSizeStatistics = new SummaryStatistics();
intervalStatistics = new SummaryStatistics();
intervalStatistics.addValue(0);
@@ -48,13 +47,13 @@ public class LightweightMetrics {
intervalStatistics.addValue(startTime - startTimes.get(startTimes.size() - 2));
}
- public void addThreadNumber(long threads){
- threadStatistics.addValue(threads);
- }
-
- public void addMemoryConsumption(long memory){
- memoryStatistics.addValue(memory);
- }
+// public void addThreadNumber(long threads){
+// threadStatistics.addValue(threads);
+// }
+//
+// public void addMemoryConsumption(long memory){
+// memoryStatistics.addValue(memory);
+// }
public void addReturnSize(Object returnObject){
if(returnObject != null)
@@ -63,9 +62,9 @@ public class LightweightMetrics {
returnSizeStatistics.addValue(0);
}
- public void incThrown() {
- thrownCounter++;
- }
+// public void incThrown() {
+// thrownCounter++;
+// }
public void incOccurrence() {
occurrences++;
@@ -85,8 +84,27 @@ public class LightweightMetrics {
return intervalTimes;
}
+ public String getName() {
+ return name;
+ }
+
+ public String getLongName() {
+ return longName;
+ }
+
+ @Override
+ public String toString() {
+ return "LightweightMetrics{" +
+ "name='" + name + '\'' +
+ ", frequency=" + getFrequency() +
+ ", expensiveness=" + getExpensiveness() +
+ '}';
+ }
+
+ //Metrics below
+
/**
- *
+ * Number of occurrences (calls)
* @return number of occurrences
*/
public long getFrequency() {
@@ -94,79 +112,68 @@ public class LightweightMetrics {
}
/**
- *
- * @return number of different users
+ * Cyclomatic complexity (Cyclomatic at understand tool)
+ * @return Cyclomatic complexity from static metrics file
*/
- public long getUserBehavior(){
- return users.size();
+ public long getMaintainability(){
+ return staticMetrics.getMetrics(name).cyclomatic;
}
/**
- *
- * @return throughput
+ * Mean classSize of the return
+ * @return class size
*/
- public double getLatency(){
- return (startTimes.get(startTimes.size()-1) - startTimes.get(0)) / startTimes.size();
+ public double getChangeability(){
+ return returnSizeStatistics.getMean();
}
/**
- *
- * @return inter interval times
+ * Mean number of different users that triggered the method
+ * @return number of different users
*/
- public double getConcurrency(){
- return intervalStatistics.getMean();
+ public long getUserBehavior(){
+ return users.size();
}
/**
- *
- * @return processing times
+ * Mean Interval inter-calls
+ * @return inter interval times
*/
- public double getExpensiveness(){
- return timeStatistics.getMean();
+ public double getConcurrency(){
+ return intervalStatistics.getMean();
}
/**
- *
- * @return class size
+ * Number of constructs (if, while, for) (MaxNesting at understand tool)
+ * @return MaxNesting from static metrics file
*/
- public double getChangeability(){
- return returnSizeStatistics.getMean();
+ public long getErrorprone(){
+ return staticMetrics.getMetrics(name).maxNesting;
}
/**
- *
- * @return number of exceptions raised
+ * Mean processing time
+ * @return processing times
*/
- public long getDynamicErrorprone(){
- return thrownCounter;
- }
-
- public long getStaticErrorprone(){
- return staticMetrics.getMetrics(name).maxNesting;
+ public double getExpensiveness(){
+ return timeStatistics.getMean();
}
- public long getMaintainability(){
- return staticMetrics.getMetrics(name).cyclomatic;
- }
+ /**
+ * Number of static resources (variables and methods) referenced and thread creations (CountOutput at understand tool)
+ * @return CountOutput from static metrics file
+ */
public long getGlobalImpact(){
return staticMetrics.getMetrics(name).countOutput;
}
- public String getName() {
- return name;
- }
-
- public String getLongName() {
- return longName;
+ /**
+ * Throughput
+ * @return Throughput
+ */
+ public double getLatency(){
+ return (startTimes.get(startTimes.size()-1) - startTimes.get(0)) / startTimes.size();
}
- @Override
- public String toString() {
- return "LightweightMetrics{" +
- "name='" + name + '\'' +
- ", frequency=" + getFrequency() +
- ", expensiveness=" + getExpensiveness() +
- '}';
- }
}
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/statistics/StatisticalTest.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/statistics/StatisticalTest.java
index 7ebe3f7..8b47e4d 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/statistics/StatisticalTest.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/statistics/StatisticalTest.java
@@ -8,10 +8,13 @@ public class StatisticalTest {
public static boolean isNormalDistribution(double[] sample, double significanceLevel){
final NormalDistribution unitNormal = new NormalDistribution(0d, 1d);
- System.out.println("p-value: " + TestUtils.kolmogorovSmirnovTest(unitNormal, sample, false));
//alpha significance level (equiv. 100 * (1-alpha)% confidence) where 0 < alpha < 1 use
//Significance level of 95%: 100 * (1-0.05)
- return TestUtils.kolmogorovSmirnovTest(unitNormal, sample, significanceLevel);
+
+ //the test below compares p-value < alpha = 0.05
+ //As a rule of thumb, we reject the null hypothesis if p < 0.05.
+ //So if p < 0.05, we don't believe that our variable follows a normal distribution in our population.
+ return !TestUtils.kolmogorovSmirnovTest(unitNormal, sample, significanceLevel);
}
}
diff --git a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/Learner.java b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/Learner.java
index eceea9a..00891d2 100644
--- a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/Learner.java
+++ b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/Learner.java
@@ -14,8 +14,8 @@ import br.ufrgs.inf.prosoft.adaptivecaching.configuration.annotation.types.Trigg
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.LogTrace;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.CacheMonitor;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.cache.vendors.ehcache.EhCacheMonitor;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.providers.MongoRepository;
import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.Repository;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.providers.MongoRepository;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Output;
import com.google.common.hash.Hashing;
diff --git a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/Statistics.java b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/Statistics.java
index 7a278db..4d750a0 100644
--- a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/Statistics.java
+++ b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/Statistics.java
@@ -1,9 +1,6 @@
package br.ufrgs.inf.prosoft.sampling;
-import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightMetricAspect;
-import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightMetrics;
import br.ufrgs.inf.prosoft.adaptivecaching.sampling.statistics.StatisticalTest;
-import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.commons.math3.random.EmpiricalDistribution;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.junit.Assert;
diff --git a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/tests/adaptivecaching/CacheableTest.java b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/tests/adaptivecaching/CacheableTest.java
index 6fec9c1..4830df3 100644
--- a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/tests/adaptivecaching/CacheableTest.java
+++ b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/tests/adaptivecaching/CacheableTest.java
@@ -1,11 +1,7 @@
package br.ufrgs.inf.prosoft.tests.adaptivecaching;
-import br.ufrgs.inf.prosoft.adaptivecaching.cachemanager.cacher.key.Key;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.hamcrest.MatcherAssert;
import org.hamcrest.CoreMatchers;
-import org.junit.Test;
-import org.mockito.Mockito;
+import org.hamcrest.MatcherAssert;
import java.security.SecureRandom;
import java.util.Random;
README.md 2(+1 -1)
diff --git a/README.md b/README.md
index 471bedc..9a357af 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Simulations were performed using three different caching configurations: (i) no
#### Required Tools
- [Jmeter 3.3](http://jmeter.apache.org/) - not tested with newer versions
-- Jmeter Plugins - install them when required after loading the workload scripts
+- [Jmeter Plugins](https://jmeter-plugins.org/wiki/PluginsManager/) - install the plugin manager and plugins when required after loading the workload scripts
- MySQL 5.5 or newer
- Java 8 - not tested with Java 9 or 10
- Maven 3 or newer