adaptive-caching-framework

Details

diff --git a/evaluation/applications/AP/shopizer/sm-core/src/main/resources/log4j.properties b/evaluation/applications/AP/shopizer/sm-core/src/main/resources/log4j.properties
index 2f9c9f6..56116dd 100755
--- a/evaluation/applications/AP/shopizer/sm-core/src/main/resources/log4j.properties
+++ b/evaluation/applications/AP/shopizer/sm-core/src/main/resources/log4j.properties
@@ -2,7 +2,7 @@ log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.Stdout.layout.ConversionPattern=[%d{ISO8601}] %-5p - %-26.26c{1} - %m\n
 
-log4j.rootLogger=WARN,Stdout
+log4j.rootLogger=ERROR,Stdout
 
 
 # hibernate queries
diff --git a/evaluation/applications/AP/shopizer/sm-shop/pom.xml b/evaluation/applications/AP/shopizer/sm-shop/pom.xml
index 96fbd23..fd88587 100755
--- a/evaluation/applications/AP/shopizer/sm-shop/pom.xml
+++ b/evaluation/applications/AP/shopizer/sm-shop/pom.xml
@@ -361,7 +361,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>
 
         <dependency>
diff --git a/evaluation/applications/AP/shopizer/sm-shop/src/main/resources/log4j.xml b/evaluation/applications/AP/shopizer/sm-shop/src/main/resources/log4j.xml
index 80b16b0..3dc8755 100755
--- a/evaluation/applications/AP/shopizer/sm-shop/src/main/resources/log4j.xml
+++ b/evaluation/applications/AP/shopizer/sm-shop/src/main/resources/log4j.xml
@@ -18,7 +18,7 @@
         <param name="MaxFileSize" value="10000KB"/>
         <param name="Append" value="true"/>
         <param name="Encoding" value="UTF-8"/>
-        <param name="Threshold" value="debug"/>
+        <param name="Threshold" value="error"/>
         <layout class="org.apache.log4j.PatternLayout">
             <!-- The log message pattern -->
             <param name="ConversionPattern" value="%d{dd MMM yyyy HH:mm:ss} [%5p] (%F:%L) [%M] - %m%n"/>
@@ -34,7 +34,7 @@
         <param name="File" value="/sm-shop.log"/>
         <param name="Append" value="true"/>
         <param name="Encoding" value="UTF-8"/>
-        <param name="Threshold" value="debug"/>
+        <param name="Threshold" value="error"/>
 
         <layout class="org.apache.log4j.PatternLayout">
             <param name="ConversionPattern" value="%d{dd MMM yyyy HH:mm:ss} [%5p] (%F:%L) [%M] - %m%n"/>
@@ -47,7 +47,7 @@
     </logger>
 
     <logger name="org.hibernate">
-        <level value="info"/>
+        <level value="ERROR"/>
     </logger>
 
     <logger name="org.apache.commons">
@@ -66,7 +66,7 @@
     </appender>
 
     <root>
-        <priority value="debug"/>
+        <priority value="ERROR"/>
         <appender-ref ref="CONSOLE"/>
         <appender-ref ref="WEB"/>
         <appender-ref ref="CORE"/>
diff --git a/evaluation/applications/AP/shopizer/sm-shop/src/main/webapp/WEB-INF/classes/log4j.xml b/evaluation/applications/AP/shopizer/sm-shop/src/main/webapp/WEB-INF/classes/log4j.xml
index 19ce9e9..0cf5ebc 100755
--- a/evaluation/applications/AP/shopizer/sm-shop/src/main/webapp/WEB-INF/classes/log4j.xml
+++ b/evaluation/applications/AP/shopizer/sm-shop/src/main/webapp/WEB-INF/classes/log4j.xml
@@ -11,7 +11,7 @@
 	</appender>
 
 	<logger name="com.salesmanager">
-		<level value="debug" />
+		<level value="info" />
 	</logger>
 	
 	<!-- 3rdparty Loggers -->
@@ -28,16 +28,16 @@
 	</logger>
 
 	<logger name="org.springframework.http">
-		<level value="debug" />
+		<level value="info" />
 	</logger>
 
 	<logger name="org.springframework.web">
-		<level value="debug" />
+		<level value="info" />
 	</logger>
 
 	<!-- Root Logger -->
 	<root>
-		<priority value="warn" />
+		<priority value="error" />
 		<appender-ref ref="console" />
 	</root>
 	
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 6dd5d5d..d96f67c 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
@@ -39,6 +39,15 @@ public class Analyzer implements Runnable {
     @Override
     public void run() {
 
+//        logger.info("Tracing stats....... \n Stateful trace: {} \n Light trace: {} \n Checking allow: {}", TracerAspect.timeToStatefulTrace.getMean() / 1000,
+//                TracerAspect.timeToLightweightTrace.getMean() / 1000, TracerAspect.timeToCheckAllowedTrace.getMean() / 1000);
+
+
+        if(!TracerAspect.analyzerEnabled) {
+            logger.info("Analyzer disabled, waiting until next run to check again...");
+            return;
+        }
+
 //        while(!TracerAspect.analyzerEnabled){
 //            try {
 //                logger.info("Analyzer disabled, waiting 30 seconds to check again...");
@@ -84,6 +93,8 @@ public class Analyzer implements Runnable {
 
         if (adaptiveConfig.analyzeOnce())
             TracerAspect.analyzerEnabled = false;
+
+        logger.info("Start caching...");
     }
 
 
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 de6d11d..c3a8704 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
@@ -28,7 +28,8 @@ public @interface AdaptiveCaching {
 
     //todo when analysis based on trigger do not make sense to have this, its similar to trigger by time
     @Deprecated long analysisInterval() default 1200000; //20 minutes
-    @Deprecated long firstAnalysis() default 120000; //2 minutes
+    @Deprecated long firstAnalysis() default 240000; //4 minutes
+//    @Deprecated long firstAnalysis() default 60000; //1 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/TracerAspect.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/aspects/TracerAspect.java
index 411c503..5c12a4c 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
@@ -23,6 +23,8 @@ import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.storage.RepositoryFactory
 import br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics.LightweightAnalyzer;
 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.metrics.StaticMetrics;
+import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -38,7 +40,8 @@ import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.util.*;
-import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -54,9 +57,9 @@ import static java.lang.System.currentTimeMillis;
 public class TracerAspect {
 
     //used in case the method info is required
-    public static Set<MethodEntry> cacheableMethods = new HashSet<>();
+    public static Set<MethodEntry> cacheableMethods = new ConcurrentSkipListSet<>();
     //used in case the method info is not required
-    public static Set<Object> cacheableMethodKeys = new HashSet<>();
+    public static Set<Object> cacheableMethodKeys = new ConcurrentSkipListSet<>();
     //used to list methods that raise exceptions due to tracing, they deal with internal and low level classes of spring and others, shoud be avoided
     public static List<String> methodBlackList = new ArrayList<>();
     /**
@@ -64,10 +67,22 @@ 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 samplingEnabled = true;
+    public static int samplingPercentage = 50;
     public static boolean analyzerEnabled = true;
     public static boolean lightweightTracerEnabled = true;
+    public static boolean lightweightAnayzerEnabled = true;
+
+//    public static String staticFile = "/home/jhonnymertz/workspace/adaptive-caching-framework/understand/petclinic.csv";
+//    public static String staticFile = "/home/jhonnymertz/workspace/adaptive-caching-framework/understand/cloudstore.csv";
+    public static String staticFile = "/home/jhonnymertz/workspace/adaptive-caching-framework/understand/shopizer.csv";
+
+
+//    public static SummaryStatistics timeToLightweightTrace = new SummaryStatistics();
+//    public static SummaryStatistics timeToStatefulTrace = new SummaryStatistics();
+//    public static SummaryStatistics timeToCheckAllowedTrace = new SummaryStatistics();
+
+    public static Map<String, Boolean> traceMethods = null;
 
     private final ScheduledExecutorService analyzerExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreads(
             "adaptivecaching-analyzer",
@@ -167,16 +182,14 @@ public class TracerAspect {
                 //TODO switch and build: pass a parameter and build
                 userGetter = UserGetterFactory.getInstance();
 
-            } else tracerEnabled = false;
-
-            this.cacher = new AdaptiveMethodCacher(cachingConfig.cacheProvider(), cachingConfig.expiryInterval());
-            this.cacheMonitor = CacheMonitorFactory.getCacheMonitor(this.cacher.getCache(), cachingConfig.cacheProvider());
+                this.cacher = new AdaptiveMethodCacher(cachingConfig.cacheProvider(), cachingConfig.expiryInterval());
+                this.cacheMonitor = CacheMonitorFactory.getCacheMonitor(this.cacher.getCache(), cachingConfig.cacheProvider());
 
-            //TODO load another options from @AdaptiveCaching
-            configureAnalyzer();
+                //TODO load another options from @AdaptiveCaching
+                configureAnalyzer();
 
-            //TODO trigger by time
-            //TODO in some cases (Ehcache) it is better to set a timetolive directly on cache provider
+                //TODO trigger by time
+                //TODO in some cases (Ehcache) it is better to set a timetolive directly on cache provider
 //            this.expirationExecutor.scheduleWithFixedDelay(
 //                    new VerboseRunnable(() -> TracerAspect.this.clean()),
 //                    cachingConfig.firstExpiry(), cachingConfig.expiryInterval(), TimeUnit.MILLISECONDS
@@ -188,15 +201,19 @@ public class TracerAspect {
 //                    1, 10000, TimeUnit.SECONDS
 //            );
 //        }
+                methodBlackList = new ArrayList<>();
+                traceMethods = new ConcurrentHashMap<>();
 
-            methodBlackList = new ArrayList<>();
+            } else tracerEnabled = false;
 
-            metrics = new HashMap<>();
-            if(lightweightTracerEnabled)
-                lightweightAnalyzerExecutor.scheduleWithFixedDelay(
-                        new LightweightAnalyzer(),
-                        60000, 450000, TimeUnit.MILLISECONDS);
 
+            if(lightweightTracerEnabled) {
+                metrics = new ConcurrentHashMap<>();
+                if (lightweightTracerEnabled)
+                    lightweightAnalyzerExecutor.scheduleWithFixedDelay(
+                            new LightweightAnalyzer(),
+                            120000, 450000, TimeUnit.MILLISECONDS);
+            }
 
         } catch (ConfigurationException e) {
             turnoff();
@@ -226,55 +243,79 @@ public class TracerAspect {
         //DEBUG: see if a method is being caught
         //DEBUG: traceSpecificMethod(joinPoint);
 
+//        long timeToCheckAllowed = currentTimeMillis();
+
         if (!isAllowed(joinPoint))
             return joinPoint.proceed();
 
-        //generate a hash of the method that will be used as: key to cache and compare if the method is allowed or not
-        Key key = new Key(joinPoint);
-        //when method is already cached and obtained from it, no trace will be generated
+        boolean detailedTrace = (!lightweightTracerEnabled ||
+                (lightweightTracerEnabled && LightweightAnalyzer.allowedFineGrained
+                        .contains(joinPoint.getSignature().toLongString())));
+//        boolean detailedTrace = (LightweightAnalyzer.allowedFineGrained
+//                        .contains(joinPoint.getSignature().toLongString()));
+
+//        timeToCheckAllowedTrace.addValue(currentTimeMillis() - timeToCheckAllowed);
+
+        boolean cacheable = false;
+        Key key = null;
+        if(detailedTrace) {
+            //generate a hash of the method that will be used as: key to cache and compare if the method is allowed or not
+            key = new Key(joinPoint);
 
-        boolean cacheable = cacheableMethodKeys.contains(key);
+            cacheable = cacheableMethodKeys.contains(key);
 
-        if (cacheable) {
-            Object cachedResult = this.cacher.getFromCache(key);
-            if(cachedResult != null)
-                return cachedResult;
+            if (cacheable) {
+                Object cachedResult = this.cacher.getFromCache(key);
+                if (cachedResult != null)
+                    return cachedResult;
+            }
         }
 
-        Object result = trace(key, joinPoint);
+        //when method is already cached and obtained from it, no trace will be generated
+        Object result = trace(key, joinPoint, detailedTrace);
 
-        if (cacheable && result != null) {
+        if (detailedTrace && cacheable && result != null) {
             this.cacher.putInCache(key, result);
-            logger.debug(key + " with value: " + result + " set in cachemanager");
         }
 
         return result;
     }
 
-    private int samplingIndex = 0;
-    private boolean shouldBeSampled() {
-        if(!samplingEnabled)
-            return true;
-
-//        if((rand.nextInt(10) + 1) > samplingChance)
+//    private int samplingIndex = 0;
+//    private boolean shouldBeSampled() {
+//        if(!samplingEnabled)
 //            return true;
-//        synchronized (this){
-            samplingIndex++;
-            if ((samplingIndex % samplingEach) == 0)
-                return true;
-            else return false;
-//        }
+//
+////        if((rand.nextInt(10) + 1) > samplingChance)
+////            return true;
+////        synchronized (this){
+//            samplingIndex++;
+//            if ((samplingIndex % samplingEach) == 0)
+//                return true;
+//            else return false;
+////        }
+//    }
+
+    private Random rand = new Random();
+    private boolean shouldBeSampled() {
+        return !samplingEnabled || ((rand.nextInt(100) + 1) > (100 - samplingPercentage));
     }
 
     private boolean isAllowed(ProceedingJoinPoint joinPoint) throws Throwable {
         String signature = joinPoint.getSignature().toString();
+        Boolean status = traceMethods.get(signature);
+        if(status != null)
+            return status;
+
         if (signature.contains("br.ufrgs.inf.prosoft.adaptivecaching")) {
+            traceMethods.put(signature, false);
             return false;
         }
 
         for (String p : notAllowed) {
             //toString to avoid get the return class as a false positive
             if (signature.contains(p)) {
+                traceMethods.put(signature, false);
                 return false;
             }
         }
@@ -282,23 +323,34 @@ public class TracerAspect {
         //trace only allowed packages
         for (String p : allowed) {
             if (joinPoint.getSignature().toLongString().contains(p)
-                    && !methodBlackList.contains(joinPoint.getSignature().toLongString()))
+                    && !methodBlackList.contains(joinPoint.getSignature().toLongString())) {
+                traceMethods.put(signature, true);
                 return true;
+            }
         }
 
+        traceMethods.put(signature, false);
         return false;
     }
 
-    private Object trace(Key key, ProceedingJoinPoint joinPoint) throws Throwable {
+    private Object trace(Key key, ProceedingJoinPoint joinPoint, boolean detailedTrace) throws Throwable {
 
+        Object[] joinPointArgs = null;
         //method calls can change the args, so it is better to get it at the beginning
-        Object[] joinPointArgs = joinPoint.getArgs();
+        if(detailedTrace)
+            joinPointArgs = joinPoint.getArgs();
 
         String signature = joinPoint.getSignature().toString();
 
-        LightweightMetrics metric = null;
+        long startTime = currentTimeMillis();
+        Object result = joinPoint.proceed();
+        long endTime = currentTimeMillis();
+
+        String user = userGetter.getCurrentUser();
+
         if(lightweightTracerEnabled) {
-            metric = metrics.get(signature);
+//            long timeToLightTrace = currentTimeMillis();
+            LightweightMetrics metric = metrics.get(signature);
             if (metric != null)
                 metric.incOccurrence();
             else {
@@ -309,24 +361,19 @@ public class TracerAspect {
                 if (TracerAspect.analyzerEnabled)
                     metrics.put(signature, metric);
             }
-        }
-
-        long startTime = currentTimeMillis();
-        Object result = joinPoint.proceed();
-        long endTime = currentTimeMillis();
-
-        if(lightweightTracerEnabled) {
             metric.addTime(startTime, endTime - startTime);
             metric.addReturnSize(result);
-            metric.addUser(userGetter.getCurrentUser());
+            metric.addUser(user);
+//            timeToLightweightTrace.addValue(currentTimeMillis() - timeToLightTrace);
         }
 
         //trace only allowed by lightweight metrics
         if(tracerEnabled
-            && ((lightweightTracerEnabled && LightweightAnalyzer.allowedFineGrained
-                    .contains(joinPoint.getSignature().toLongString()))
-                || !lightweightTracerEnabled)
+            && detailedTrace
             && shouldBeSampled()) {
+//            System.out.println("New trace: " + signature + LightweightAnalyzer.allowedFineGrained
+//                    .contains(joinPoint.getSignature().toLongString()));
+//            long timeToTrace = currentTimeMillis();
 
             //we do not cache null returns, but we trace them
             //maybe the method can sometimes return null... so there is not verification here
@@ -335,7 +382,7 @@ public class TracerAspect {
             logTrace.setEndTime(endTime);
 
             //TODO declare on properties the class name which implements UserGetter, parse and initialize
-            logTrace.setUserId(userGetter.getCurrentUser());
+            logTrace.setUserId(user);
 
             MethodInfo methodInfo = new MethodInfo(joinPoint.getSignature().toLongString(), joinPointArgs, result, key);
             logTrace.setMethodInfo(methodInfo);
@@ -351,6 +398,7 @@ public class TracerAspect {
                 logger.debug("Adding " + logTrace.getMethodInfo().getSignature() + " to blacklist");
                 TracerAspect.methodBlackList.add(logTrace.getMethodInfo().getSignature());
             }
+//            timeToStatefulTrace.addValue(currentTimeMillis() - timeToTrace);
         }
 
         return result;
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
index 15bb603..37280d9 100644
--- 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
@@ -96,16 +96,16 @@ public class DataFiltering {
         throw new RuntimeException("Não foi possível classificar...");
     }
 
-    public static String allMetricsToString(LightweightMetrics lightweightMetrics) {
+    public static String allMetricsToString(LightweightMetrics lightweightMetrics, StaticMetrics staticMetrics) {
         //frequency,maintainability,changeability,userBehavior,concurrency,errorprone,expensiveness,globalimpact,latency
         return lightweightMetrics.getFrequency() +
-                "," + lightweightMetrics.getMaintainability() +
+                "," + staticMetrics.getMetrics(lightweightMetrics.getName()).cyclomatic +
                 "," + lightweightMetrics.getChangeability() +
                 "," + lightweightMetrics.getUserBehavior() +
                 "," + lightweightMetrics.getConcurrency() +
-                "," + lightweightMetrics.getErrorprone() +
+                "," + staticMetrics.getMetrics(lightweightMetrics.getName()).maxNesting +
                 "," + lightweightMetrics.getExpensiveness() +
-                "," + lightweightMetrics.getGlobalImpact() +
+                "," + staticMetrics.getMetrics(lightweightMetrics.getName()).countOutput +
                 "," + lightweightMetrics.getLatency();
     }
 
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 b533011..a2ef9be 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
@@ -3,6 +3,7 @@ package br.ufrgs.inf.prosoft.adaptivecaching.sampling.metrics;
 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.monitoring.application.aspects.TracerAspect;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.aspects.support.Tracer;
 import br.ufrgs.inf.prosoft.adaptivecaching.sampling.statistics.StatisticalTest;
 import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
 import org.slf4j.Logger;
@@ -10,21 +11,26 @@ import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
 
 public class LightweightAnalyzer implements Runnable {
 
     static Logger logger = LoggerFactory.getLogger(LightweightAnalyzer.class);
 
-    public static Set<String> allowedFineGrained = new HashSet<>();
+    public static Set<String> allowedFineGrained = new ConcurrentSkipListSet<>();
 
-    public static void analyze() {
+    public static void analyze() throws IOException {
 
         logger.info("Analyzing {} lightweight methods for relevance...", TracerAspect.metrics.size());
 
+        StaticMetrics staticMetrics = new StaticMetrics(TracerAspect.staticFile);
+
         DescriptiveStatistics frequencies = new DescriptiveStatistics();
         DescriptiveStatistics changeabilities = new DescriptiveStatistics();
         DescriptiveStatistics errorprones = new DescriptiveStatistics();
@@ -34,17 +40,23 @@ public class LightweightAnalyzer implements Runnable {
         DescriptiveStatistics concurrencies = new DescriptiveStatistics();
         DescriptiveStatistics expensiveness = new DescriptiveStatistics();
         DescriptiveStatistics globalimpacts = new DescriptiveStatistics();
-        for (String method : TracerAspect.metrics.keySet()) {
-            LightweightMetrics sc = TracerAspect.metrics.get(method);
+        System.out.println("---------------------------");
+        Map<String, LightweightMetrics> mets = new HashMap<>(TracerAspect.metrics);
+        for (String method : mets.keySet()) {
+            System.out.println(method);
+            LightweightMetrics sc = mets.get(method);
+            StaticMetrics.StaticMetric staticMetric = staticMetrics.getMetrics(sc.getName());
+            if(staticMetric == null)
+                continue;
             frequencies.addValue(sc.getFrequency());
             changeabilities.addValue(sc.getChangeability());
-            errorprones.addValue(sc.getErrorprone());
+            errorprones.addValue(staticMetric.maxNesting);
             latencies.addValue(sc.getLatency());
-            maintainabilities.addValue(sc.getMaintainability());
+            maintainabilities.addValue(staticMetric.cyclomatic);
             userBehaviors.addValue(sc.getUserBehavior());
             concurrencies.addValue(sc.getConcurrency());
             expensiveness.addValue(sc.getExpensiveness());
-            globalimpacts.addValue(sc.getGlobalImpact());
+            globalimpacts.addValue(staticMetric.countOutput);
         }
 
         System.out.println("---------------------------");
@@ -68,14 +80,14 @@ public class LightweightAnalyzer implements Runnable {
                 ((StatisticalTest.isNormalDistribution(latencies.getValues(), 0.05)) ? "normal" : "not_normal"));
 
         //cleaning selected methods
-        allowedFineGrained = new HashSet<>();
+        allowedFineGrained = new ConcurrentSkipListSet<>();
 
         //TODO process SET operations dynamically
 //        LightweightMetricAspect.criteriaDSL
 
         //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);
+        for(String method : mets.keySet()) {
+            LightweightMetrics sc = mets.get(method);
 
 //           if ((DataFiltering.isGroup("less", changeabilities, sc.getChangeability())
 //                    || DataFiltering.isGroup("normal", changeabilities, sc.getChangeability()))
@@ -85,7 +97,7 @@ public class LightweightAnalyzer implements Runnable {
 //                    || 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("normal", 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))
@@ -118,33 +130,49 @@ public class LightweightAnalyzer implements Runnable {
         try {
             final PrintWriter pw = new PrintWriter(new File("lightweightanalysis.csv"));
             pw.write("method,frequency,maintainability,changeability,userBehavior,concurrency,errorprone,expensiveness,globalimpact,latency,vfrequency,vmaintainability,vchangeability,vuserBehavior,vconcurrency,verrorprone,vexpensiveness,vglobalimpact,vlatency\n");
-            for(String name : TracerAspect.metrics.keySet()){
-                pw.write(TracerAspect.metrics.get(name).getName() + "," +
-                    DataFiltering.getGroup(frequencies, TracerAspect.metrics.get(name).getFrequency()) +
-                    "," + DataFiltering.getGroup(maintainabilities, TracerAspect.metrics.get(name).getMaintainability()) +
-                    "," + DataFiltering.getGroup(changeabilities, TracerAspect.metrics.get(name).getChangeability()) +
-                    "," + DataFiltering.getGroup(userBehaviors, TracerAspect.metrics.get(name).getUserBehavior()) +
-                    "," + DataFiltering.getGroup(concurrencies, TracerAspect.metrics.get(name).getConcurrency()) +
-                    "," + DataFiltering.getGroup(errorprones, TracerAspect.metrics.get(name).getErrorprone()) +
-                    "," + DataFiltering.getGroup(expensiveness, TracerAspect.metrics.get(name).getExpensiveness()) +
-                    "," + DataFiltering.getGroup(globalimpacts, TracerAspect.metrics.get(name).getGlobalImpact()) +
-                    "," + DataFiltering.getGroup(latencies, TracerAspect.metrics.get(name).getLatency()) +
+            for(String name : mets.keySet()){
+                LightweightMetrics lm = mets.get(name);
+                StaticMetrics.StaticMetric staticMetric = staticMetrics.getMetrics(lm.getName());
+                if(staticMetric == null)
+                    continue;
+                pw.write(mets.get(name).getName() + "," +
+                    DataFiltering.getGroup(frequencies, mets.get(name).getFrequency()) +
+                    "," + DataFiltering.getGroup(maintainabilities, staticMetric.cyclomatic) +
+                    "," + DataFiltering.getGroup(changeabilities, lm.getChangeability()) +
+                    "," + DataFiltering.getGroup(userBehaviors, lm.getUserBehavior()) +
+                    "," + DataFiltering.getGroup(concurrencies, lm.getConcurrency()) +
+                    "," + DataFiltering.getGroup(errorprones, staticMetric.maxNesting) +
+                    "," + DataFiltering.getGroup(expensiveness, lm.getExpensiveness()) +
+                    "," + DataFiltering.getGroup(globalimpacts, staticMetric.countOutput) +
+                    "," + DataFiltering.getGroup(latencies, mets.get(name).getLatency()) +
                     "," +
-                        DataFiltering.allMetricsToString(TracerAspect.metrics.get(name)) + '\n');
+                        DataFiltering.allMetricsToString(lm, staticMetrics) + '\n');
             }
             pw.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }
+
+        //analyze once
+        TracerAspect.lightweightAnayzerEnabled = false;
+//        TracerAspect.lightweightTracerEnabled = false;
     }
 
     @Override
     public void run() {
-        if (!TracerAspect.lightweightTracerEnabled) {
-            logger.info("Lightweight monitoring disabled...");
+
+//        logger.info("Tracing stats....... \n Stateful trace: {} \n Light trace: {} \n Checking allow: {}", TracerAspect.timeToStatefulTrace.getMean() / 1000,
+//                TracerAspect.timeToLightweightTrace.getMean() / 1000, TracerAspect.timeToCheckAllowedTrace.getMean() / 1000);
+
+        if (!TracerAspect.lightweightAnayzerEnabled) {
+            logger.info("Lightweight analysis disabled...");
             return;
         }
 
-        analyze();
+        try {
+            analyze();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
     }
 }
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 eca170e..6f567ac 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
@@ -22,7 +22,6 @@ public class LightweightMetrics {
     private Set<String> users;
     private String name;
     private String longName;
-    private StaticMetrics staticMetrics;
 
     public LightweightMetrics(String name, String longName) throws IOException {
         this.name = name;
@@ -35,15 +34,12 @@ public class LightweightMetrics {
         intervalStatistics = new SummaryStatistics();
         intervalStatistics.addValue(0);
         users = new HashSet<>();
-        staticMetrics = new StaticMetrics();
     }
 
     public void addTime(long startTime, long time){
         startTimes.add(startTime);
         timeStatistics.addValue(time);
-        if(startTimes.size() == 1)
-            intervalStatistics.addValue(0);
-        else
+        if(startTimes.size() > 1)
             intervalStatistics.addValue(startTime - startTimes.get(startTimes.size() - 2));
     }
 
@@ -115,16 +111,16 @@ public class LightweightMetrics {
      * Cyclomatic complexity (Cyclomatic at understand tool)
      * @return Cyclomatic complexity from static metrics file
      */
-    public long getMaintainability(){
-        return staticMetrics.getMetrics(name).cyclomatic;
-    }
+//    public long getMaintainability(){
+//        return staticMetrics.getMetrics(name).cyclomatic;
+//    }
 
     /**
-     * Mean classSize of the return
+     * std classSize of the return
      * @return class size
      */
     public double getChangeability(){
-        return  returnSizeStatistics.getMean();
+        return  returnSizeStatistics.getStandardDeviation();
     }
 
     /**
@@ -147,9 +143,9 @@ public class LightweightMetrics {
      * Number of constructs (if, while, for) (MaxNesting at understand tool)
      * @return MaxNesting from static metrics file
      */
-    public long getErrorprone(){
-        return staticMetrics.getMetrics(name).maxNesting;
-    }
+//    public long getErrorprone(){
+//        return staticMetrics.getMetrics(name).maxNesting;
+//    }
 
     /**
      * Mean processing time
@@ -164,9 +160,9 @@ public class LightweightMetrics {
      * 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 long getGlobalImpact(){
+//        return staticMetrics.getMetrics(name).countOutput;
+//    }
 
     /**
      * Throughput
diff --git a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/StaticMetrics.java b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/StaticMetrics.java
index 0cac98d..32037a5 100644
--- a/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/StaticMetrics.java
+++ b/framework/autonomicmanager/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/sampling/metrics/StaticMetrics.java
@@ -11,16 +11,16 @@ public class StaticMetrics {
 
     private Map<String, StaticMetric> metrics;
 
-    public StaticMetrics() throws IOException {
-        loadMetrics();
+    public StaticMetrics(String filename) throws IOException {
+        loadMetrics(filename);
     }
 
     public StaticMetric getMetrics(String method){
         return metrics.get(method);
     }
 
-    public void loadMetrics() throws IOException {
-        BufferedReader br = new BufferedReader(new FileReader("/home/jhonnymertz/workspace/adaptive-caching-framework/understand/petclinic.csv"));
+    public void loadMetrics(String filename) throws IOException {
+        BufferedReader br = new BufferedReader(new FileReader(filename));
         String line = null;
         metrics = new HashMap<>();
 
diff --git a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/StaticMetricsTest.java b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/StaticMetricsTest.java
index 8968e61..70a4e26 100644
--- a/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/StaticMetricsTest.java
+++ b/framework/autonomicmanager/src/test/java/br/ufrgs/inf/prosoft/sampling/StaticMetricsTest.java
@@ -9,7 +9,7 @@ public class StaticMetricsTest {
 
     @Test
     public void loadMetrics() throws IOException {
-        StaticMetrics staticMetrics = new StaticMetrics();
+        StaticMetrics staticMetrics = new StaticMetrics("/home/jhonnymertz/workspace/adaptive-caching-framework/understand/shopizer.csv");
         System.out.println(staticMetrics.getAllMetrics());
     }
 }
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 4d750a0..b2d4956 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
@@ -75,4 +75,17 @@ public class Statistics {
         Assert.assertEquals(frequencies.getPercentile(75), 7.825, 0.1);
     }
 
+    @Test
+    public void test2Quantiles(){
+        DescriptiveStatistics frequencies = new DescriptiveStatistics();
+        double[] values = new double[]{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,4};
+        for(double d : values)
+            frequencies.addValue(d);
+
+        //then
+        System.out.println(frequencies.getPercentile(25));
+        System.out.println(frequencies.getPercentile(50));
+        System.out.println(frequencies.getPercentile(75));
+    }
+
 }