You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sirona.apache.org by ol...@apache.org on 2014/02/18 07:00:05 UTC

svn commit: r1569203 - in /incubator/sirona/trunk: agent/javaagent/src/main/java/org/apache/sirona/pathtracking/ agent/javaagent/src/test/java/org/apache/sirona/pathtracking/ core/src/main/java/org/apache/sirona/store/tracking/ core/src/main/java/org/a...

Author: olamy
Date: Tue Feb 18 06:00:04 2014
New Revision: 1569203

URL: http://svn.apache.org/r1569203
Log:
use a Set

Added:
    incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java
      - copied, changed from r1569202, incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
Modified:
    incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java
    incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java
    incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java
    incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java
    incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java

Modified: incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java?rev=1569203&r1=1569202&r2=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java Tue Feb 18 06:00:04 2014
@@ -37,11 +37,16 @@ public class PathTrackingInvocationListe
 
     private static final Integer TIMESTAMP_KEY = "Sirona-path-tracking-key".hashCode();
 
+    private static final Integer PATH_TRACKING_LEVEL_KEY = "Sirona-path-tracking-level-key".hashCode();
+
     private static final boolean TRACKING_ACTIVATED =
         Configuration.is( Configuration.CONFIG_PROPERTY_PREFIX + "javaagent.path.tracking.activate", false );
 
-    PathTrackingDataStore pathTrackingDataStore = IoCs.findOrCreateInstance( DataStoreFactory.class )
-                                                        .getPathTrackingDataStore();
+    private PathTrackingDataStore pathTrackingDataStore =
+        IoCs.findOrCreateInstance( DataStoreFactory.class ).getPathTrackingDataStore();
+
+
+    private PathTracker.PathTrackingInformation pathTrackingInformation;
 
     /**
      * fqcn.methodName
@@ -70,6 +75,14 @@ public class PathTrackingInvocationListe
         }
 
         this.key = key;
+
+        int lastDot = this.key.lastIndexOf( "." );
+
+        String className = this.key.substring( 0, lastDot );
+        String methodName = this.key.substring( lastDot + 1, this.key.length() );
+
+        this.pathTrackingInformation = new PathTracker.PathTrackingInformation( className, methodName );
+
         return true;
     }
 
@@ -81,6 +94,8 @@ public class PathTrackingInvocationListe
             System.out.println( "PathTrackingInvocationListener#before:" + context.getKey() );
         }
         context.put( TIMESTAMP_KEY, Long.valueOf( System.nanoTime() ) );
+        context.put( PATH_TRACKING_LEVEL_KEY, PathTracker.start( this.pathTrackingInformation ) );
+
         context.getKey();
     }
 
@@ -95,22 +110,22 @@ public class PathTrackingInvocationListe
 
         Long end = System.nanoTime();
         Long start = Long.class.cast( context.get( TIMESTAMP_KEY, Long.class ) );
-        int lastDot = this.key.lastIndexOf( "." );
 
-        String className = this.key.substring( 0, lastDot );
-        String methodName = this.key.substring( lastDot + 1, this.key.length() );
+        String uuid = PathTracker.get();
 
         // FIXME get node from configuration!
         // FIXME correctly configure the level!
         PathTrackingEntry pathTrackingEntry =
-            new PathTrackingEntry( PathTracker.get(), "node", className, methodName, start, ( end - start ), 0 );
-
+            new PathTrackingEntry( uuid, "node", pathTrackingInformation.getClassName(), pathTrackingInformation.getMethodName(),
+                                   start, ( end - start ),
+                                   context.get( PATH_TRACKING_LEVEL_KEY, Integer.class ) );
 
         if ( SironaAgent.AGENT_DEBUG )
         {
             System.out.println( "PathTrackingInvocationListener: after: " + pathTrackingEntry.toString()
                                     + ", pathTrackingDataStore type:" + pathTrackingDataStore.getClass().getName() );
         }
+        PathTracker.stop( pathTrackingInformation );
 
         pathTrackingDataStore.store( pathTrackingEntry );
 

Modified: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java?rev=1569203&r1=1569202&r2=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java Tue Feb 18 06:00:04 2014
@@ -21,27 +21,28 @@ import org.apache.sirona.javaagent.Agent
 import org.apache.sirona.javaagent.JavaAgentRunner;
 import org.apache.sirona.store.DataStoreFactory;
 import org.apache.sirona.store.tracking.InMemoryPathTrackingDataStore;
-import org.apache.sirona.store.tracking.PathTrackingDataStore;
 import org.apache.sirona.tracking.PathTrackingEntry;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author Olivier Lamy
  */
-@RunWith( JavaAgentRunner.class )
+@RunWith(JavaAgentRunner.class)
 public class PathTrackingInvocationListenerTest
 {
 
     @Test
-    @AgentArgs( value ="",
-    sysProps = "project.build.directory=${project.build.directory}|sirona.agent.debug=${sirona.agent.debug}|org.apache.sirona.configuration.sirona.properties=${project.build.directory}/test-classes/pathtracking/sirona.properties")
+    @AgentArgs(value = "",
+               sysProps = "project.build.directory=${project.build.directory}|sirona.agent.debug=${sirona.agent.debug}|org.apache.sirona.configuration.sirona.properties=${project.build.directory}/test-classes/pathtracking/sirona.properties")
     public void simpleTest()
-    throws Exception
+        throws Exception
     {
 
         App app = new App();
@@ -52,25 +53,41 @@ public class PathTrackingInvocationListe
         InMemoryPathTrackingDataStore ptds =
             InMemoryPathTrackingDataStore.class.cast( dataStoreFactory.getPathTrackingDataStore() );
 
-        Map<String, List<PathTrackingEntry>> all = ptds.retrieveAll();
+        Map<String, Set<PathTrackingEntry>> all = ptds.retrieveAll();
 
         Assert.assertTrue( !all.isEmpty() );
 
-        PathTrackingEntry first = all.entrySet().iterator().next().getValue().get( 0 );
+        List<PathTrackingEntry> entries = new ArrayList<PathTrackingEntry>( all.values().iterator().next() );
 
-        System.out.println("first entry: " + first);
+        PathTrackingEntry first = entries.get( 0 );
 
+        System.out.println( "first entry: " + first );
+
+        PathTrackingEntry second = entries.get( 1 );
+
+        System.out.println( "second entry: " + second );
+
+        PathTrackingEntry last = entries.get( entries.size() - 1 );
+
+        System.out.println( "last entry: " + last );
+
+        for ( PathTrackingEntry entry : entries )
+        {
+            System.out.println( "entry:" + entry );
+        }
     }
 
 
     public static class App
     {
-        public void foo() throws Exception
+        public void foo()
+            throws Exception
         {
             Thread.sleep( 1000 );
         }
 
-        public void beer() throws Exception
+        public void beer()
+            throws Exception
         {
             this.foo();
         }

Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java (original)
+++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java Tue Feb 18 06:00:04 2014
@@ -17,39 +17,48 @@
 package org.apache.sirona.store.tracking;
 
 import org.apache.sirona.tracking.PathTrackingEntry;
+import org.apache.sirona.tracking.PathTrackingEntryComparator;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 /**
  * Very simple in memory storage for Path tracking feature
  * <b>MUST NOT be used in production</b>
+ *
  * @author Olivier Lamy
  */
-public class InMemoryPathTrackingDataStore implements PathTrackingDataStore
+public class InMemoryPathTrackingDataStore
+    implements PathTrackingDataStore
 {
     /**
      * store path track tracking entries list per path tracking id
      */
-    private ConcurrentHashMap<String, List<PathTrackingEntry>> pathTrackingEntries = new ConcurrentHashMap<String, List<PathTrackingEntry>>( 50 );
+    private ConcurrentMap<String, Set<PathTrackingEntry>> pathTrackingEntries =
+        new ConcurrentHashMap<String, Set<PathTrackingEntry>>( 50 );
 
     @Override
     public void store( PathTrackingEntry pathTrackingEntry )
     {
-        List<PathTrackingEntry> pathTrackingEntries = this.pathTrackingEntries.get( pathTrackingEntry.getTrackingId() );
+        Set<PathTrackingEntry> pathTrackingEntries = this.pathTrackingEntries.get( pathTrackingEntry.getTrackingId() );
 
-        if (pathTrackingEntries == null) {
-            pathTrackingEntries = new ArrayList<PathTrackingEntry>( );
+        if ( pathTrackingEntries == null )
+        {
+            pathTrackingEntries = new TreeSet<PathTrackingEntry>( PathTrackingEntryComparator.INSTANCE );
         }
         pathTrackingEntries.add( pathTrackingEntry );
         this.pathTrackingEntries.put( pathTrackingEntry.getTrackingId(), pathTrackingEntries );
     }
 
     @Override
-    public List<PathTrackingEntry> retrieve( String trackingId )
+    public Collection<PathTrackingEntry> retrieve( String trackingId )
     {
         return this.pathTrackingEntries.get( trackingId );
     }
@@ -57,27 +66,33 @@ public class InMemoryPathTrackingDataSto
     @Override
     public List<String> retrieveTrackingIds( Date startTime, Date endTime )
     {
-        List<String> trackingIds = new ArrayList<String>(  );
-        for ( List<PathTrackingEntry> pathTrackingEntries : this.pathTrackingEntries.values() )
+        List<String> trackingIds = new ArrayList<String>();
+        for ( Set<PathTrackingEntry> pathTrackingEntries : this.pathTrackingEntries.values() )
         {
-            if (pathTrackingEntries.isEmpty()) {
+            if ( pathTrackingEntries.isEmpty() )
+            {
                 continue;
             }
-            if (pathTrackingEntries.get( 0 ).getStartTime() / 1000000 > startTime.getTime() //
-                && pathTrackingEntries.get( 0 ).getStartTime() / 1000000 < endTime.getTime()) {
-              trackingIds.add( pathTrackingEntries.get( 0 ).getTrackingId() );
+
+            PathTrackingEntry first = pathTrackingEntries.iterator().next();
+
+            if ( first.getStartTime() / 1000000 > startTime.getTime() //
+                && first.getStartTime() / 1000000 < endTime.getTime() )
+            {
+                trackingIds.add( first.getTrackingId() );
             }
         }
         return trackingIds;
     }
 
     /**
-     *
      * <b>use with CAUTION as can return a lot of data</b>
      * <p>This method is use for testing purpose</p>
+     *
      * @return {@link List} containing all {@link PathTrackingEntry}
      */
-    public Map<String, List<PathTrackingEntry>> retrieveAll() {
+    public Map<String, Set<PathTrackingEntry>> retrieveAll()
+    {
         return this.pathTrackingEntries;
     }
 }

Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java (original)
+++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java Tue Feb 18 06:00:04 2014
@@ -18,6 +18,7 @@ package org.apache.sirona.store.tracking
 
 import org.apache.sirona.tracking.PathTrackingEntry;
 
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
@@ -34,14 +35,14 @@ public interface PathTrackingDataStore
      * @param trackingId
      * @return {@link List} of {@link org.apache.sirona.tracking.PathTrackingEntry} related to a tracking id
      */
-    List<PathTrackingEntry> retrieve( String trackingId );
+    Collection<PathTrackingEntry> retrieve( String trackingId );
 
     /**
      * @param startTime
      * @param endTime
      * @return {@link java.lang.String} of all trackingIds available in the system between startTime and endTime
      */
-    List<String> retrieveTrackingIds( Date startTime, Date endTime );
+    Collection<String> retrieveTrackingIds( Date startTime, Date endTime );
 
 
 

Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java?rev=1569203&r1=1569202&r2=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java (original)
+++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java Tue Feb 18 06:00:04 2014
@@ -17,6 +17,7 @@
 package org.apache.sirona.tracking;
 
 import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @author Olivier Lamy
@@ -24,12 +25,14 @@ import java.util.UUID;
 public class PathTracker
 {
 
-    private static final boolean DEBUG = Boolean.getBoolean( "sirona.agent.debug" );
-
     // FIXME olamy: so not using InheritableThreadLocal will create a new uuid in case of thread creation
     // whereas it's technically the same "transaction" (ie jvm call path)
-    //private static final InheritableThreadLocal<String> THREAD_LOCAL = new InheritableThreadLocal<String>()
-    private static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<String>()
+    //private static final InheritableThreadLocal<String> THREAD_LOCAL_TX = new InheritableThreadLocal<String>()
+
+    /**
+     * Thread local to store a "transaction id" (i.e a java call)
+     */
+    private static final ThreadLocal<String> THREAD_LOCAL_TX = new ThreadLocal<String>()
     {
         @Override
         protected String initialValue()
@@ -47,25 +50,150 @@ public class PathTracker
 
     };
 
+    // FIXME olamy: AtomicInteger because of starting multiple level but that's not supported with the THREAD_LOCAL_TX
+    // because it doesn't use an InheritableThreadLocal so really sure :-)
+
+    /**
+     * Thread Local to store current call tree level
+     */
+    private static final ThreadLocal<AtomicInteger> THREAD_LOCAL_LEVEL = new ThreadLocal<AtomicInteger>()
+    {
+        @Override
+        protected AtomicInteger initialValue()
+        {
+            return new AtomicInteger( 1 );
+        }
+    };
+
+    public static class PathTrackingInformation
+    {
+        private String className;
+
+        private String methodName;
+
+        private PathTrackingInformation parent;
+
+        public PathTrackingInformation( String className, String methodName )
+        {
+            this.className = className;
+            this.methodName = methodName;
+        }
+
+        public String getClassName()
+        {
+            return className;
+        }
+
+        public String getMethodName()
+        {
+            return methodName;
+        }
+
+        public PathTrackingInformation getParent()
+        {
+            return parent;
+        }
+
+        public void setParent( PathTrackingInformation parent )
+        {
+            this.parent = parent;
+        }
+
+        @Override
+        public String toString()
+        {
+            final StringBuilder sb = new StringBuilder( "PathTrackingInformation{" );
+            sb.append( "className='" ).append( className ).append( '\'' );
+            sb.append( ", methodName='" ).append( methodName ).append( '\'' );
+            sb.append( ", parent=" ).append( parent );
+            sb.append( '}' );
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Thread local to store the current Class#Method used
+     * prevent to inc level in same class used
+     */
+    private static final ThreadLocal<PathTrackingInformation> THREAD_LOCAL_LEVEL_INFO =
+        new ThreadLocal<PathTrackingInformation>()
+        {
+            // no op
+        };
+
+
     // Returns the current thread's unique ID, assigning it if necessary
     public static String get()
     {
-        return THREAD_LOCAL.get();
+        return THREAD_LOCAL_TX.get();
     }
 
     public static void set( String uuid )
     {
-        THREAD_LOCAL.set( uuid );
+        THREAD_LOCAL_TX.set( uuid );
     }
 
-    public static void start()
+    /**
+     * FIXME not sure we really need the uuid but just in case for future usage :-)
+     */
+    public static int start( PathTrackingInformation pathTrackingInformation )
     {
+        int level = 0;
+        PathTrackingInformation current = THREAD_LOCAL_LEVEL_INFO.get();
+        if ( current  == null )
+        {
+            level = THREAD_LOCAL_LEVEL.get().incrementAndGet();
+        }
+        else
+        {
+            // same class so no inc
+            if ( current.className.equals( pathTrackingInformation.className ) //
+                && current.methodName.equals( pathTrackingInformation.methodName ) )
+            {
+                // yup sounds to be the same level so no level inc!
+                level = THREAD_LOCAL_LEVEL.get().get();
+            }
+            else
+            {
+                level = THREAD_LOCAL_LEVEL.get().incrementAndGet();
+            }
 
-    }
+            pathTrackingInformation.setParent( current );
+        }
+
+        THREAD_LOCAL_LEVEL_INFO.set( pathTrackingInformation );
 
+        //System.out.println("start level: " + level + " for key " + key);
+
+        return level;
+    }
 
-    public static void stop()
+    /**
+     * FIXME not sure we really need the uuid but just in case for future usage :-)
+     */
+    public static int stop( PathTrackingInformation pathTrackingInformation )
     {
+        int level = 0;
 
+        PathTrackingInformation current = THREAD_LOCAL_LEVEL_INFO.get();
+        // same class so no inc
+        if ( current.className.equals( pathTrackingInformation.className ) //
+            && current.methodName.equals( pathTrackingInformation.methodName ) )
+        {
+            // yup sounds to be the same level so no level inc!
+            level = THREAD_LOCAL_LEVEL.get().get();
+        }
+        else
+        {
+            level = THREAD_LOCAL_LEVEL.get().decrementAndGet();
+        }
+
+        THREAD_LOCAL_LEVEL_INFO.set( pathTrackingInformation );
+
+        //System.out.println("start level: " + level + " for key " + key);
+
+        return level;
     }
+
+
 }

Copied: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java (from r1569202, incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java)
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java?p2=incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java&p1=incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java&r1=1569202&r2=1569203&rev=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java (original)
+++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java Tue Feb 18 06:00:04 2014
@@ -14,37 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.sirona.tracking;
 
-package org.apache.sirona.cassandra.pathtracking;
-
-import org.apache.sirona.store.tracking.PathTrackingDataStore;
-import org.apache.sirona.tracking.PathTrackingEntry;
-
-import java.util.Date;
-import java.util.List;
+import java.util.Comparator;
 
 /**
  * @author Olivier Lamy
  */
-public class CassandraPathTrackingDataStore
-    implements PathTrackingDataStore
+public class PathTrackingEntryComparator
+    implements Comparator<PathTrackingEntry>
 {
 
-    @Override
-    public void store( PathTrackingEntry pathTrackingEntry )
-    {
-
-    }
-
-    @Override
-    public List<PathTrackingEntry> retrieve( String trackingId )
-    {
-        return null;
-    }
+    public static final PathTrackingEntryComparator INSTANCE = new PathTrackingEntryComparator();
 
     @Override
-    public List<String> retrieveTrackingIds( Date startTime, Date endTime )
+    public int compare( PathTrackingEntry pathTrackingEntry, PathTrackingEntry pathTrackingEntry2 )
     {
-        return null;
+        // TODO add level in comparator
+        return Long.valueOf( pathTrackingEntry.getStartTime() ).compareTo(
+            Long.valueOf( pathTrackingEntry2.getStartTime() ) );
     }
 }

Modified: incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
==============================================================================
--- incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java (original)
+++ incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java Tue Feb 18 06:00:04 2014
@@ -20,6 +20,7 @@ package org.apache.sirona.cassandra.path
 import org.apache.sirona.store.tracking.PathTrackingDataStore;
 import org.apache.sirona.tracking.PathTrackingEntry;
 
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
@@ -37,13 +38,13 @@ public class CassandraPathTrackingDataSt
     }
 
     @Override
-    public List<PathTrackingEntry> retrieve( String trackingId )
+    public Collection<PathTrackingEntry> retrieve( String trackingId )
     {
         return null;
     }
 
     @Override
-    public List<String> retrieveTrackingIds( Date startTime, Date endTime )
+    public Collection<String> retrieveTrackingIds( Date startTime, Date endTime )
     {
         return null;
     }



Re: svn commit: r1569203 - in /incubator/sirona/trunk: agent/javaagent/src/main/java/org/apache/sirona/pathtracking/ agent/javaagent/src/test/java/org/apache/sirona/pathtracking/ core/src/main/java/org/apache/sirona/store/tracking/ core/src/main/java/org/a...

Posted by Olivier Lamy <ol...@apache.org>.
On 18 February 2014 17:41, Romain Manni-Bucau <rm...@gmail.com> wrote:
> Hi
>
> 1) I think pathTrackingDataStore can be static
yes and changed in a later commit :-)
> 2) seems stop misses threadlocal.remove()
Oh I changed something and remove that but there are weird cases :-)
> 3) open question: do we keep or remove @author? (tried to not put them
> until now)
I don't care that's just my idea template I will remove
> Romain Manni-Bucau
> Twitter: @rmannibucau
> Blog: http://rmannibucau.wordpress.com/
> LinkedIn: http://fr.linkedin.com/in/rmannibucau
> Github: https://github.com/rmannibucau
>
>
>
> 2014-02-18 7:00 GMT+01:00  <ol...@apache.org>:
>> Author: olamy
>> Date: Tue Feb 18 06:00:04 2014
>> New Revision: 1569203
>>
>> URL: http://svn.apache.org/r1569203
>> Log:
>> use a Set
>>
>> Added:
>>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java
>>       - copied, changed from r1569202, incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
>> Modified:
>>     incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java
>>     incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java
>>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java
>>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java
>>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java
>>     incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
>>
>> Modified: incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java?rev=1569203&r1=1569202&r2=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java (original)
>> +++ incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java Tue Feb 18 06:00:04 2014
>> @@ -37,11 +37,16 @@ public class PathTrackingInvocationListe
>>
>>      private static final Integer TIMESTAMP_KEY = "Sirona-path-tracking-key".hashCode();
>>
>> +    private static final Integer PATH_TRACKING_LEVEL_KEY = "Sirona-path-tracking-level-key".hashCode();
>> +
>>      private static final boolean TRACKING_ACTIVATED =
>>          Configuration.is( Configuration.CONFIG_PROPERTY_PREFIX + "javaagent.path.tracking.activate", false );
>>
>> -    PathTrackingDataStore pathTrackingDataStore = IoCs.findOrCreateInstance( DataStoreFactory.class )
>> -                                                        .getPathTrackingDataStore();
>> +    private PathTrackingDataStore pathTrackingDataStore =
>> +        IoCs.findOrCreateInstance( DataStoreFactory.class ).getPathTrackingDataStore();
>> +
>> +
>> +    private PathTracker.PathTrackingInformation pathTrackingInformation;
>>
>>      /**
>>       * fqcn.methodName
>> @@ -70,6 +75,14 @@ public class PathTrackingInvocationListe
>>          }
>>
>>          this.key = key;
>> +
>> +        int lastDot = this.key.lastIndexOf( "." );
>> +
>> +        String className = this.key.substring( 0, lastDot );
>> +        String methodName = this.key.substring( lastDot + 1, this.key.length() );
>> +
>> +        this.pathTrackingInformation = new PathTracker.PathTrackingInformation( className, methodName );
>> +
>>          return true;
>>      }
>>
>> @@ -81,6 +94,8 @@ public class PathTrackingInvocationListe
>>              System.out.println( "PathTrackingInvocationListener#before:" + context.getKey() );
>>          }
>>          context.put( TIMESTAMP_KEY, Long.valueOf( System.nanoTime() ) );
>> +        context.put( PATH_TRACKING_LEVEL_KEY, PathTracker.start( this.pathTrackingInformation ) );
>> +
>>          context.getKey();
>>      }
>>
>> @@ -95,22 +110,22 @@ public class PathTrackingInvocationListe
>>
>>          Long end = System.nanoTime();
>>          Long start = Long.class.cast( context.get( TIMESTAMP_KEY, Long.class ) );
>> -        int lastDot = this.key.lastIndexOf( "." );
>>
>> -        String className = this.key.substring( 0, lastDot );
>> -        String methodName = this.key.substring( lastDot + 1, this.key.length() );
>> +        String uuid = PathTracker.get();
>>
>>          // FIXME get node from configuration!
>>          // FIXME correctly configure the level!
>>          PathTrackingEntry pathTrackingEntry =
>> -            new PathTrackingEntry( PathTracker.get(), "node", className, methodName, start, ( end - start ), 0 );
>> -
>> +            new PathTrackingEntry( uuid, "node", pathTrackingInformation.getClassName(), pathTrackingInformation.getMethodName(),
>> +                                   start, ( end - start ),
>> +                                   context.get( PATH_TRACKING_LEVEL_KEY, Integer.class ) );
>>
>>          if ( SironaAgent.AGENT_DEBUG )
>>          {
>>              System.out.println( "PathTrackingInvocationListener: after: " + pathTrackingEntry.toString()
>>                                      + ", pathTrackingDataStore type:" + pathTrackingDataStore.getClass().getName() );
>>          }
>> +        PathTracker.stop( pathTrackingInformation );
>>
>>          pathTrackingDataStore.store( pathTrackingEntry );
>>
>>
>> Modified: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java?rev=1569203&r1=1569202&r2=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java (original)
>> +++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java Tue Feb 18 06:00:04 2014
>> @@ -21,27 +21,28 @@ import org.apache.sirona.javaagent.Agent
>>  import org.apache.sirona.javaagent.JavaAgentRunner;
>>  import org.apache.sirona.store.DataStoreFactory;
>>  import org.apache.sirona.store.tracking.InMemoryPathTrackingDataStore;
>> -import org.apache.sirona.store.tracking.PathTrackingDataStore;
>>  import org.apache.sirona.tracking.PathTrackingEntry;
>>  import org.junit.Assert;
>>  import org.junit.Test;
>>  import org.junit.runner.RunWith;
>>
>> +import java.util.ArrayList;
>>  import java.util.List;
>>  import java.util.Map;
>> +import java.util.Set;
>>
>>  /**
>>   * @author Olivier Lamy
>>   */
>> -@RunWith( JavaAgentRunner.class )
>> +@RunWith(JavaAgentRunner.class)
>>  public class PathTrackingInvocationListenerTest
>>  {
>>
>>      @Test
>> -    @AgentArgs( value ="",
>> -    sysProps = "project.build.directory=${project.build.directory}|sirona.agent.debug=${sirona.agent.debug}|org.apache.sirona.configuration.sirona.properties=${project.build.directory}/test-classes/pathtracking/sirona.properties")
>> +    @AgentArgs(value = "",
>> +               sysProps = "project.build.directory=${project.build.directory}|sirona.agent.debug=${sirona.agent.debug}|org.apache.sirona.configuration.sirona.properties=${project.build.directory}/test-classes/pathtracking/sirona.properties")
>>      public void simpleTest()
>> -    throws Exception
>> +        throws Exception
>>      {
>>
>>          App app = new App();
>> @@ -52,25 +53,41 @@ public class PathTrackingInvocationListe
>>          InMemoryPathTrackingDataStore ptds =
>>              InMemoryPathTrackingDataStore.class.cast( dataStoreFactory.getPathTrackingDataStore() );
>>
>> -        Map<String, List<PathTrackingEntry>> all = ptds.retrieveAll();
>> +        Map<String, Set<PathTrackingEntry>> all = ptds.retrieveAll();
>>
>>          Assert.assertTrue( !all.isEmpty() );
>>
>> -        PathTrackingEntry first = all.entrySet().iterator().next().getValue().get( 0 );
>> +        List<PathTrackingEntry> entries = new ArrayList<PathTrackingEntry>( all.values().iterator().next() );
>>
>> -        System.out.println("first entry: " + first);
>> +        PathTrackingEntry first = entries.get( 0 );
>>
>> +        System.out.println( "first entry: " + first );
>> +
>> +        PathTrackingEntry second = entries.get( 1 );
>> +
>> +        System.out.println( "second entry: " + second );
>> +
>> +        PathTrackingEntry last = entries.get( entries.size() - 1 );
>> +
>> +        System.out.println( "last entry: " + last );
>> +
>> +        for ( PathTrackingEntry entry : entries )
>> +        {
>> +            System.out.println( "entry:" + entry );
>> +        }
>>      }
>>
>>
>>      public static class App
>>      {
>> -        public void foo() throws Exception
>> +        public void foo()
>> +            throws Exception
>>          {
>>              Thread.sleep( 1000 );
>>          }
>>
>> -        public void beer() throws Exception
>> +        public void beer()
>> +            throws Exception
>>          {
>>              this.foo();
>>          }
>>
>> Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java (original)
>> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java Tue Feb 18 06:00:04 2014
>> @@ -17,39 +17,48 @@
>>  package org.apache.sirona.store.tracking;
>>
>>  import org.apache.sirona.tracking.PathTrackingEntry;
>> +import org.apache.sirona.tracking.PathTrackingEntryComparator;
>>
>>  import java.util.ArrayList;
>> +import java.util.Collection;
>>  import java.util.Date;
>>  import java.util.List;
>>  import java.util.Map;
>> +import java.util.Set;
>> +import java.util.TreeSet;
>>  import java.util.concurrent.ConcurrentHashMap;
>> +import java.util.concurrent.ConcurrentMap;
>>
>>  /**
>>   * Very simple in memory storage for Path tracking feature
>>   * <b>MUST NOT be used in production</b>
>> + *
>>   * @author Olivier Lamy
>>   */
>> -public class InMemoryPathTrackingDataStore implements PathTrackingDataStore
>> +public class InMemoryPathTrackingDataStore
>> +    implements PathTrackingDataStore
>>  {
>>      /**
>>       * store path track tracking entries list per path tracking id
>>       */
>> -    private ConcurrentHashMap<String, List<PathTrackingEntry>> pathTrackingEntries = new ConcurrentHashMap<String, List<PathTrackingEntry>>( 50 );
>> +    private ConcurrentMap<String, Set<PathTrackingEntry>> pathTrackingEntries =
>> +        new ConcurrentHashMap<String, Set<PathTrackingEntry>>( 50 );
>>
>>      @Override
>>      public void store( PathTrackingEntry pathTrackingEntry )
>>      {
>> -        List<PathTrackingEntry> pathTrackingEntries = this.pathTrackingEntries.get( pathTrackingEntry.getTrackingId() );
>> +        Set<PathTrackingEntry> pathTrackingEntries = this.pathTrackingEntries.get( pathTrackingEntry.getTrackingId() );
>>
>> -        if (pathTrackingEntries == null) {
>> -            pathTrackingEntries = new ArrayList<PathTrackingEntry>( );
>> +        if ( pathTrackingEntries == null )
>> +        {
>> +            pathTrackingEntries = new TreeSet<PathTrackingEntry>( PathTrackingEntryComparator.INSTANCE );
>>          }
>>          pathTrackingEntries.add( pathTrackingEntry );
>>          this.pathTrackingEntries.put( pathTrackingEntry.getTrackingId(), pathTrackingEntries );
>>      }
>>
>>      @Override
>> -    public List<PathTrackingEntry> retrieve( String trackingId )
>> +    public Collection<PathTrackingEntry> retrieve( String trackingId )
>>      {
>>          return this.pathTrackingEntries.get( trackingId );
>>      }
>> @@ -57,27 +66,33 @@ public class InMemoryPathTrackingDataSto
>>      @Override
>>      public List<String> retrieveTrackingIds( Date startTime, Date endTime )
>>      {
>> -        List<String> trackingIds = new ArrayList<String>(  );
>> -        for ( List<PathTrackingEntry> pathTrackingEntries : this.pathTrackingEntries.values() )
>> +        List<String> trackingIds = new ArrayList<String>();
>> +        for ( Set<PathTrackingEntry> pathTrackingEntries : this.pathTrackingEntries.values() )
>>          {
>> -            if (pathTrackingEntries.isEmpty()) {
>> +            if ( pathTrackingEntries.isEmpty() )
>> +            {
>>                  continue;
>>              }
>> -            if (pathTrackingEntries.get( 0 ).getStartTime() / 1000000 > startTime.getTime() //
>> -                && pathTrackingEntries.get( 0 ).getStartTime() / 1000000 < endTime.getTime()) {
>> -              trackingIds.add( pathTrackingEntries.get( 0 ).getTrackingId() );
>> +
>> +            PathTrackingEntry first = pathTrackingEntries.iterator().next();
>> +
>> +            if ( first.getStartTime() / 1000000 > startTime.getTime() //
>> +                && first.getStartTime() / 1000000 < endTime.getTime() )
>> +            {
>> +                trackingIds.add( first.getTrackingId() );
>>              }
>>          }
>>          return trackingIds;
>>      }
>>
>>      /**
>> -     *
>>       * <b>use with CAUTION as can return a lot of data</b>
>>       * <p>This method is use for testing purpose</p>
>> +     *
>>       * @return {@link List} containing all {@link PathTrackingEntry}
>>       */
>> -    public Map<String, List<PathTrackingEntry>> retrieveAll() {
>> +    public Map<String, Set<PathTrackingEntry>> retrieveAll()
>> +    {
>>          return this.pathTrackingEntries;
>>      }
>>  }
>>
>> Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java (original)
>> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java Tue Feb 18 06:00:04 2014
>> @@ -18,6 +18,7 @@ package org.apache.sirona.store.tracking
>>
>>  import org.apache.sirona.tracking.PathTrackingEntry;
>>
>> +import java.util.Collection;
>>  import java.util.Date;
>>  import java.util.List;
>>
>> @@ -34,14 +35,14 @@ public interface PathTrackingDataStore
>>       * @param trackingId
>>       * @return {@link List} of {@link org.apache.sirona.tracking.PathTrackingEntry} related to a tracking id
>>       */
>> -    List<PathTrackingEntry> retrieve( String trackingId );
>> +    Collection<PathTrackingEntry> retrieve( String trackingId );
>>
>>      /**
>>       * @param startTime
>>       * @param endTime
>>       * @return {@link java.lang.String} of all trackingIds available in the system between startTime and endTime
>>       */
>> -    List<String> retrieveTrackingIds( Date startTime, Date endTime );
>> +    Collection<String> retrieveTrackingIds( Date startTime, Date endTime );
>>
>>
>>
>>
>> Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java?rev=1569203&r1=1569202&r2=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java (original)
>> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java Tue Feb 18 06:00:04 2014
>> @@ -17,6 +17,7 @@
>>  package org.apache.sirona.tracking;
>>
>>  import java.util.UUID;
>> +import java.util.concurrent.atomic.AtomicInteger;
>>
>>  /**
>>   * @author Olivier Lamy
>> @@ -24,12 +25,14 @@ import java.util.UUID;
>>  public class PathTracker
>>  {
>>
>> -    private static final boolean DEBUG = Boolean.getBoolean( "sirona.agent.debug" );
>> -
>>      // FIXME olamy: so not using InheritableThreadLocal will create a new uuid in case of thread creation
>>      // whereas it's technically the same "transaction" (ie jvm call path)
>> -    //private static final InheritableThreadLocal<String> THREAD_LOCAL = new InheritableThreadLocal<String>()
>> -    private static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<String>()
>> +    //private static final InheritableThreadLocal<String> THREAD_LOCAL_TX = new InheritableThreadLocal<String>()
>> +
>> +    /**
>> +     * Thread local to store a "transaction id" (i.e a java call)
>> +     */
>> +    private static final ThreadLocal<String> THREAD_LOCAL_TX = new ThreadLocal<String>()
>>      {
>>          @Override
>>          protected String initialValue()
>> @@ -47,25 +50,150 @@ public class PathTracker
>>
>>      };
>>
>> +    // FIXME olamy: AtomicInteger because of starting multiple level but that's not supported with the THREAD_LOCAL_TX
>> +    // because it doesn't use an InheritableThreadLocal so really sure :-)
>> +
>> +    /**
>> +     * Thread Local to store current call tree level
>> +     */
>> +    private static final ThreadLocal<AtomicInteger> THREAD_LOCAL_LEVEL = new ThreadLocal<AtomicInteger>()
>> +    {
>> +        @Override
>> +        protected AtomicInteger initialValue()
>> +        {
>> +            return new AtomicInteger( 1 );
>> +        }
>> +    };
>> +
>> +    public static class PathTrackingInformation
>> +    {
>> +        private String className;
>> +
>> +        private String methodName;
>> +
>> +        private PathTrackingInformation parent;
>> +
>> +        public PathTrackingInformation( String className, String methodName )
>> +        {
>> +            this.className = className;
>> +            this.methodName = methodName;
>> +        }
>> +
>> +        public String getClassName()
>> +        {
>> +            return className;
>> +        }
>> +
>> +        public String getMethodName()
>> +        {
>> +            return methodName;
>> +        }
>> +
>> +        public PathTrackingInformation getParent()
>> +        {
>> +            return parent;
>> +        }
>> +
>> +        public void setParent( PathTrackingInformation parent )
>> +        {
>> +            this.parent = parent;
>> +        }
>> +
>> +        @Override
>> +        public String toString()
>> +        {
>> +            final StringBuilder sb = new StringBuilder( "PathTrackingInformation{" );
>> +            sb.append( "className='" ).append( className ).append( '\'' );
>> +            sb.append( ", methodName='" ).append( methodName ).append( '\'' );
>> +            sb.append( ", parent=" ).append( parent );
>> +            sb.append( '}' );
>> +            return sb.toString();
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Thread local to store the current Class#Method used
>> +     * prevent to inc level in same class used
>> +     */
>> +    private static final ThreadLocal<PathTrackingInformation> THREAD_LOCAL_LEVEL_INFO =
>> +        new ThreadLocal<PathTrackingInformation>()
>> +        {
>> +            // no op
>> +        };
>> +
>> +
>>      // Returns the current thread's unique ID, assigning it if necessary
>>      public static String get()
>>      {
>> -        return THREAD_LOCAL.get();
>> +        return THREAD_LOCAL_TX.get();
>>      }
>>
>>      public static void set( String uuid )
>>      {
>> -        THREAD_LOCAL.set( uuid );
>> +        THREAD_LOCAL_TX.set( uuid );
>>      }
>>
>> -    public static void start()
>> +    /**
>> +     * FIXME not sure we really need the uuid but just in case for future usage :-)
>> +     */
>> +    public static int start( PathTrackingInformation pathTrackingInformation )
>>      {
>> +        int level = 0;
>> +        PathTrackingInformation current = THREAD_LOCAL_LEVEL_INFO.get();
>> +        if ( current  == null )
>> +        {
>> +            level = THREAD_LOCAL_LEVEL.get().incrementAndGet();
>> +        }
>> +        else
>> +        {
>> +            // same class so no inc
>> +            if ( current.className.equals( pathTrackingInformation.className ) //
>> +                && current.methodName.equals( pathTrackingInformation.methodName ) )
>> +            {
>> +                // yup sounds to be the same level so no level inc!
>> +                level = THREAD_LOCAL_LEVEL.get().get();
>> +            }
>> +            else
>> +            {
>> +                level = THREAD_LOCAL_LEVEL.get().incrementAndGet();
>> +            }
>>
>> -    }
>> +            pathTrackingInformation.setParent( current );
>> +        }
>> +
>> +        THREAD_LOCAL_LEVEL_INFO.set( pathTrackingInformation );
>>
>> +        //System.out.println("start level: " + level + " for key " + key);
>> +
>> +        return level;
>> +    }
>>
>> -    public static void stop()
>> +    /**
>> +     * FIXME not sure we really need the uuid but just in case for future usage :-)
>> +     */
>> +    public static int stop( PathTrackingInformation pathTrackingInformation )
>>      {
>> +        int level = 0;
>>
>> +        PathTrackingInformation current = THREAD_LOCAL_LEVEL_INFO.get();
>> +        // same class so no inc
>> +        if ( current.className.equals( pathTrackingInformation.className ) //
>> +            && current.methodName.equals( pathTrackingInformation.methodName ) )
>> +        {
>> +            // yup sounds to be the same level so no level inc!
>> +            level = THREAD_LOCAL_LEVEL.get().get();
>> +        }
>> +        else
>> +        {
>> +            level = THREAD_LOCAL_LEVEL.get().decrementAndGet();
>> +        }
>> +
>> +        THREAD_LOCAL_LEVEL_INFO.set( pathTrackingInformation );
>> +
>> +        //System.out.println("start level: " + level + " for key " + key);
>> +
>> +        return level;
>>      }
>> +
>> +
>>  }
>>
>> Copied: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java (from r1569202, incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java)
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java?p2=incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java&p1=incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java&r1=1569202&r2=1569203&rev=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java (original)
>> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java Tue Feb 18 06:00:04 2014
>> @@ -14,37 +14,24 @@
>>   * See the License for the specific language governing permissions and
>>   * limitations under the License.
>>   */
>> +package org.apache.sirona.tracking;
>>
>> -package org.apache.sirona.cassandra.pathtracking;
>> -
>> -import org.apache.sirona.store.tracking.PathTrackingDataStore;
>> -import org.apache.sirona.tracking.PathTrackingEntry;
>> -
>> -import java.util.Date;
>> -import java.util.List;
>> +import java.util.Comparator;
>>
>>  /**
>>   * @author Olivier Lamy
>>   */
>> -public class CassandraPathTrackingDataStore
>> -    implements PathTrackingDataStore
>> +public class PathTrackingEntryComparator
>> +    implements Comparator<PathTrackingEntry>
>>  {
>>
>> -    @Override
>> -    public void store( PathTrackingEntry pathTrackingEntry )
>> -    {
>> -
>> -    }
>> -
>> -    @Override
>> -    public List<PathTrackingEntry> retrieve( String trackingId )
>> -    {
>> -        return null;
>> -    }
>> +    public static final PathTrackingEntryComparator INSTANCE = new PathTrackingEntryComparator();
>>
>>      @Override
>> -    public List<String> retrieveTrackingIds( Date startTime, Date endTime )
>> +    public int compare( PathTrackingEntry pathTrackingEntry, PathTrackingEntry pathTrackingEntry2 )
>>      {
>> -        return null;
>> +        // TODO add level in comparator
>> +        return Long.valueOf( pathTrackingEntry.getStartTime() ).compareTo(
>> +            Long.valueOf( pathTrackingEntry2.getStartTime() ) );
>>      }
>>  }
>>
>> Modified: incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
>> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
>> ==============================================================================
>> --- incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java (original)
>> +++ incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java Tue Feb 18 06:00:04 2014
>> @@ -20,6 +20,7 @@ package org.apache.sirona.cassandra.path
>>  import org.apache.sirona.store.tracking.PathTrackingDataStore;
>>  import org.apache.sirona.tracking.PathTrackingEntry;
>>
>> +import java.util.Collection;
>>  import java.util.Date;
>>  import java.util.List;
>>
>> @@ -37,13 +38,13 @@ public class CassandraPathTrackingDataSt
>>      }
>>
>>      @Override
>> -    public List<PathTrackingEntry> retrieve( String trackingId )
>> +    public Collection<PathTrackingEntry> retrieve( String trackingId )
>>      {
>>          return null;
>>      }
>>
>>      @Override
>> -    public List<String> retrieveTrackingIds( Date startTime, Date endTime )
>> +    public Collection<String> retrieveTrackingIds( Date startTime, Date endTime )
>>      {
>>          return null;
>>      }
>>
>>



-- 
Olivier Lamy
Ecetera: http://ecetera.com.au
http://twitter.com/olamy | http://linkedin.com/in/olamy

Re: svn commit: r1569203 - in /incubator/sirona/trunk: agent/javaagent/src/main/java/org/apache/sirona/pathtracking/ agent/javaagent/src/test/java/org/apache/sirona/pathtracking/ core/src/main/java/org/apache/sirona/store/tracking/ core/src/main/java/org/a...

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi

1) I think pathTrackingDataStore can be static
2) seems stop misses threadlocal.remove()
3) open question: do we keep or remove @author? (tried to not put them
until now)
Romain Manni-Bucau
Twitter: @rmannibucau
Blog: http://rmannibucau.wordpress.com/
LinkedIn: http://fr.linkedin.com/in/rmannibucau
Github: https://github.com/rmannibucau



2014-02-18 7:00 GMT+01:00  <ol...@apache.org>:
> Author: olamy
> Date: Tue Feb 18 06:00:04 2014
> New Revision: 1569203
>
> URL: http://svn.apache.org/r1569203
> Log:
> use a Set
>
> Added:
>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java
>       - copied, changed from r1569202, incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
> Modified:
>     incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java
>     incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java
>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java
>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java
>     incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java
>     incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
>
> Modified: incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java?rev=1569203&r1=1569202&r2=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java (original)
> +++ incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/pathtracking/PathTrackingInvocationListener.java Tue Feb 18 06:00:04 2014
> @@ -37,11 +37,16 @@ public class PathTrackingInvocationListe
>
>      private static final Integer TIMESTAMP_KEY = "Sirona-path-tracking-key".hashCode();
>
> +    private static final Integer PATH_TRACKING_LEVEL_KEY = "Sirona-path-tracking-level-key".hashCode();
> +
>      private static final boolean TRACKING_ACTIVATED =
>          Configuration.is( Configuration.CONFIG_PROPERTY_PREFIX + "javaagent.path.tracking.activate", false );
>
> -    PathTrackingDataStore pathTrackingDataStore = IoCs.findOrCreateInstance( DataStoreFactory.class )
> -                                                        .getPathTrackingDataStore();
> +    private PathTrackingDataStore pathTrackingDataStore =
> +        IoCs.findOrCreateInstance( DataStoreFactory.class ).getPathTrackingDataStore();
> +
> +
> +    private PathTracker.PathTrackingInformation pathTrackingInformation;
>
>      /**
>       * fqcn.methodName
> @@ -70,6 +75,14 @@ public class PathTrackingInvocationListe
>          }
>
>          this.key = key;
> +
> +        int lastDot = this.key.lastIndexOf( "." );
> +
> +        String className = this.key.substring( 0, lastDot );
> +        String methodName = this.key.substring( lastDot + 1, this.key.length() );
> +
> +        this.pathTrackingInformation = new PathTracker.PathTrackingInformation( className, methodName );
> +
>          return true;
>      }
>
> @@ -81,6 +94,8 @@ public class PathTrackingInvocationListe
>              System.out.println( "PathTrackingInvocationListener#before:" + context.getKey() );
>          }
>          context.put( TIMESTAMP_KEY, Long.valueOf( System.nanoTime() ) );
> +        context.put( PATH_TRACKING_LEVEL_KEY, PathTracker.start( this.pathTrackingInformation ) );
> +
>          context.getKey();
>      }
>
> @@ -95,22 +110,22 @@ public class PathTrackingInvocationListe
>
>          Long end = System.nanoTime();
>          Long start = Long.class.cast( context.get( TIMESTAMP_KEY, Long.class ) );
> -        int lastDot = this.key.lastIndexOf( "." );
>
> -        String className = this.key.substring( 0, lastDot );
> -        String methodName = this.key.substring( lastDot + 1, this.key.length() );
> +        String uuid = PathTracker.get();
>
>          // FIXME get node from configuration!
>          // FIXME correctly configure the level!
>          PathTrackingEntry pathTrackingEntry =
> -            new PathTrackingEntry( PathTracker.get(), "node", className, methodName, start, ( end - start ), 0 );
> -
> +            new PathTrackingEntry( uuid, "node", pathTrackingInformation.getClassName(), pathTrackingInformation.getMethodName(),
> +                                   start, ( end - start ),
> +                                   context.get( PATH_TRACKING_LEVEL_KEY, Integer.class ) );
>
>          if ( SironaAgent.AGENT_DEBUG )
>          {
>              System.out.println( "PathTrackingInvocationListener: after: " + pathTrackingEntry.toString()
>                                      + ", pathTrackingDataStore type:" + pathTrackingDataStore.getClass().getName() );
>          }
> +        PathTracker.stop( pathTrackingInformation );
>
>          pathTrackingDataStore.store( pathTrackingEntry );
>
>
> Modified: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java?rev=1569203&r1=1569202&r2=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java (original)
> +++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/pathtracking/PathTrackingInvocationListenerTest.java Tue Feb 18 06:00:04 2014
> @@ -21,27 +21,28 @@ import org.apache.sirona.javaagent.Agent
>  import org.apache.sirona.javaagent.JavaAgentRunner;
>  import org.apache.sirona.store.DataStoreFactory;
>  import org.apache.sirona.store.tracking.InMemoryPathTrackingDataStore;
> -import org.apache.sirona.store.tracking.PathTrackingDataStore;
>  import org.apache.sirona.tracking.PathTrackingEntry;
>  import org.junit.Assert;
>  import org.junit.Test;
>  import org.junit.runner.RunWith;
>
> +import java.util.ArrayList;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.Set;
>
>  /**
>   * @author Olivier Lamy
>   */
> -@RunWith( JavaAgentRunner.class )
> +@RunWith(JavaAgentRunner.class)
>  public class PathTrackingInvocationListenerTest
>  {
>
>      @Test
> -    @AgentArgs( value ="",
> -    sysProps = "project.build.directory=${project.build.directory}|sirona.agent.debug=${sirona.agent.debug}|org.apache.sirona.configuration.sirona.properties=${project.build.directory}/test-classes/pathtracking/sirona.properties")
> +    @AgentArgs(value = "",
> +               sysProps = "project.build.directory=${project.build.directory}|sirona.agent.debug=${sirona.agent.debug}|org.apache.sirona.configuration.sirona.properties=${project.build.directory}/test-classes/pathtracking/sirona.properties")
>      public void simpleTest()
> -    throws Exception
> +        throws Exception
>      {
>
>          App app = new App();
> @@ -52,25 +53,41 @@ public class PathTrackingInvocationListe
>          InMemoryPathTrackingDataStore ptds =
>              InMemoryPathTrackingDataStore.class.cast( dataStoreFactory.getPathTrackingDataStore() );
>
> -        Map<String, List<PathTrackingEntry>> all = ptds.retrieveAll();
> +        Map<String, Set<PathTrackingEntry>> all = ptds.retrieveAll();
>
>          Assert.assertTrue( !all.isEmpty() );
>
> -        PathTrackingEntry first = all.entrySet().iterator().next().getValue().get( 0 );
> +        List<PathTrackingEntry> entries = new ArrayList<PathTrackingEntry>( all.values().iterator().next() );
>
> -        System.out.println("first entry: " + first);
> +        PathTrackingEntry first = entries.get( 0 );
>
> +        System.out.println( "first entry: " + first );
> +
> +        PathTrackingEntry second = entries.get( 1 );
> +
> +        System.out.println( "second entry: " + second );
> +
> +        PathTrackingEntry last = entries.get( entries.size() - 1 );
> +
> +        System.out.println( "last entry: " + last );
> +
> +        for ( PathTrackingEntry entry : entries )
> +        {
> +            System.out.println( "entry:" + entry );
> +        }
>      }
>
>
>      public static class App
>      {
> -        public void foo() throws Exception
> +        public void foo()
> +            throws Exception
>          {
>              Thread.sleep( 1000 );
>          }
>
> -        public void beer() throws Exception
> +        public void beer()
> +            throws Exception
>          {
>              this.foo();
>          }
>
> Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java (original)
> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/InMemoryPathTrackingDataStore.java Tue Feb 18 06:00:04 2014
> @@ -17,39 +17,48 @@
>  package org.apache.sirona.store.tracking;
>
>  import org.apache.sirona.tracking.PathTrackingEntry;
> +import org.apache.sirona.tracking.PathTrackingEntryComparator;
>
>  import java.util.ArrayList;
> +import java.util.Collection;
>  import java.util.Date;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.Set;
> +import java.util.TreeSet;
>  import java.util.concurrent.ConcurrentHashMap;
> +import java.util.concurrent.ConcurrentMap;
>
>  /**
>   * Very simple in memory storage for Path tracking feature
>   * <b>MUST NOT be used in production</b>
> + *
>   * @author Olivier Lamy
>   */
> -public class InMemoryPathTrackingDataStore implements PathTrackingDataStore
> +public class InMemoryPathTrackingDataStore
> +    implements PathTrackingDataStore
>  {
>      /**
>       * store path track tracking entries list per path tracking id
>       */
> -    private ConcurrentHashMap<String, List<PathTrackingEntry>> pathTrackingEntries = new ConcurrentHashMap<String, List<PathTrackingEntry>>( 50 );
> +    private ConcurrentMap<String, Set<PathTrackingEntry>> pathTrackingEntries =
> +        new ConcurrentHashMap<String, Set<PathTrackingEntry>>( 50 );
>
>      @Override
>      public void store( PathTrackingEntry pathTrackingEntry )
>      {
> -        List<PathTrackingEntry> pathTrackingEntries = this.pathTrackingEntries.get( pathTrackingEntry.getTrackingId() );
> +        Set<PathTrackingEntry> pathTrackingEntries = this.pathTrackingEntries.get( pathTrackingEntry.getTrackingId() );
>
> -        if (pathTrackingEntries == null) {
> -            pathTrackingEntries = new ArrayList<PathTrackingEntry>( );
> +        if ( pathTrackingEntries == null )
> +        {
> +            pathTrackingEntries = new TreeSet<PathTrackingEntry>( PathTrackingEntryComparator.INSTANCE );
>          }
>          pathTrackingEntries.add( pathTrackingEntry );
>          this.pathTrackingEntries.put( pathTrackingEntry.getTrackingId(), pathTrackingEntries );
>      }
>
>      @Override
> -    public List<PathTrackingEntry> retrieve( String trackingId )
> +    public Collection<PathTrackingEntry> retrieve( String trackingId )
>      {
>          return this.pathTrackingEntries.get( trackingId );
>      }
> @@ -57,27 +66,33 @@ public class InMemoryPathTrackingDataSto
>      @Override
>      public List<String> retrieveTrackingIds( Date startTime, Date endTime )
>      {
> -        List<String> trackingIds = new ArrayList<String>(  );
> -        for ( List<PathTrackingEntry> pathTrackingEntries : this.pathTrackingEntries.values() )
> +        List<String> trackingIds = new ArrayList<String>();
> +        for ( Set<PathTrackingEntry> pathTrackingEntries : this.pathTrackingEntries.values() )
>          {
> -            if (pathTrackingEntries.isEmpty()) {
> +            if ( pathTrackingEntries.isEmpty() )
> +            {
>                  continue;
>              }
> -            if (pathTrackingEntries.get( 0 ).getStartTime() / 1000000 > startTime.getTime() //
> -                && pathTrackingEntries.get( 0 ).getStartTime() / 1000000 < endTime.getTime()) {
> -              trackingIds.add( pathTrackingEntries.get( 0 ).getTrackingId() );
> +
> +            PathTrackingEntry first = pathTrackingEntries.iterator().next();
> +
> +            if ( first.getStartTime() / 1000000 > startTime.getTime() //
> +                && first.getStartTime() / 1000000 < endTime.getTime() )
> +            {
> +                trackingIds.add( first.getTrackingId() );
>              }
>          }
>          return trackingIds;
>      }
>
>      /**
> -     *
>       * <b>use with CAUTION as can return a lot of data</b>
>       * <p>This method is use for testing purpose</p>
> +     *
>       * @return {@link List} containing all {@link PathTrackingEntry}
>       */
> -    public Map<String, List<PathTrackingEntry>> retrieveAll() {
> +    public Map<String, Set<PathTrackingEntry>> retrieveAll()
> +    {
>          return this.pathTrackingEntries;
>      }
>  }
>
> Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java (original)
> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/store/tracking/PathTrackingDataStore.java Tue Feb 18 06:00:04 2014
> @@ -18,6 +18,7 @@ package org.apache.sirona.store.tracking
>
>  import org.apache.sirona.tracking.PathTrackingEntry;
>
> +import java.util.Collection;
>  import java.util.Date;
>  import java.util.List;
>
> @@ -34,14 +35,14 @@ public interface PathTrackingDataStore
>       * @param trackingId
>       * @return {@link List} of {@link org.apache.sirona.tracking.PathTrackingEntry} related to a tracking id
>       */
> -    List<PathTrackingEntry> retrieve( String trackingId );
> +    Collection<PathTrackingEntry> retrieve( String trackingId );
>
>      /**
>       * @param startTime
>       * @param endTime
>       * @return {@link java.lang.String} of all trackingIds available in the system between startTime and endTime
>       */
> -    List<String> retrieveTrackingIds( Date startTime, Date endTime );
> +    Collection<String> retrieveTrackingIds( Date startTime, Date endTime );
>
>
>
>
> Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java?rev=1569203&r1=1569202&r2=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java (original)
> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTracker.java Tue Feb 18 06:00:04 2014
> @@ -17,6 +17,7 @@
>  package org.apache.sirona.tracking;
>
>  import java.util.UUID;
> +import java.util.concurrent.atomic.AtomicInteger;
>
>  /**
>   * @author Olivier Lamy
> @@ -24,12 +25,14 @@ import java.util.UUID;
>  public class PathTracker
>  {
>
> -    private static final boolean DEBUG = Boolean.getBoolean( "sirona.agent.debug" );
> -
>      // FIXME olamy: so not using InheritableThreadLocal will create a new uuid in case of thread creation
>      // whereas it's technically the same "transaction" (ie jvm call path)
> -    //private static final InheritableThreadLocal<String> THREAD_LOCAL = new InheritableThreadLocal<String>()
> -    private static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<String>()
> +    //private static final InheritableThreadLocal<String> THREAD_LOCAL_TX = new InheritableThreadLocal<String>()
> +
> +    /**
> +     * Thread local to store a "transaction id" (i.e a java call)
> +     */
> +    private static final ThreadLocal<String> THREAD_LOCAL_TX = new ThreadLocal<String>()
>      {
>          @Override
>          protected String initialValue()
> @@ -47,25 +50,150 @@ public class PathTracker
>
>      };
>
> +    // FIXME olamy: AtomicInteger because of starting multiple level but that's not supported with the THREAD_LOCAL_TX
> +    // because it doesn't use an InheritableThreadLocal so really sure :-)
> +
> +    /**
> +     * Thread Local to store current call tree level
> +     */
> +    private static final ThreadLocal<AtomicInteger> THREAD_LOCAL_LEVEL = new ThreadLocal<AtomicInteger>()
> +    {
> +        @Override
> +        protected AtomicInteger initialValue()
> +        {
> +            return new AtomicInteger( 1 );
> +        }
> +    };
> +
> +    public static class PathTrackingInformation
> +    {
> +        private String className;
> +
> +        private String methodName;
> +
> +        private PathTrackingInformation parent;
> +
> +        public PathTrackingInformation( String className, String methodName )
> +        {
> +            this.className = className;
> +            this.methodName = methodName;
> +        }
> +
> +        public String getClassName()
> +        {
> +            return className;
> +        }
> +
> +        public String getMethodName()
> +        {
> +            return methodName;
> +        }
> +
> +        public PathTrackingInformation getParent()
> +        {
> +            return parent;
> +        }
> +
> +        public void setParent( PathTrackingInformation parent )
> +        {
> +            this.parent = parent;
> +        }
> +
> +        @Override
> +        public String toString()
> +        {
> +            final StringBuilder sb = new StringBuilder( "PathTrackingInformation{" );
> +            sb.append( "className='" ).append( className ).append( '\'' );
> +            sb.append( ", methodName='" ).append( methodName ).append( '\'' );
> +            sb.append( ", parent=" ).append( parent );
> +            sb.append( '}' );
> +            return sb.toString();
> +        }
> +    }
> +
> +    /**
> +     * Thread local to store the current Class#Method used
> +     * prevent to inc level in same class used
> +     */
> +    private static final ThreadLocal<PathTrackingInformation> THREAD_LOCAL_LEVEL_INFO =
> +        new ThreadLocal<PathTrackingInformation>()
> +        {
> +            // no op
> +        };
> +
> +
>      // Returns the current thread's unique ID, assigning it if necessary
>      public static String get()
>      {
> -        return THREAD_LOCAL.get();
> +        return THREAD_LOCAL_TX.get();
>      }
>
>      public static void set( String uuid )
>      {
> -        THREAD_LOCAL.set( uuid );
> +        THREAD_LOCAL_TX.set( uuid );
>      }
>
> -    public static void start()
> +    /**
> +     * FIXME not sure we really need the uuid but just in case for future usage :-)
> +     */
> +    public static int start( PathTrackingInformation pathTrackingInformation )
>      {
> +        int level = 0;
> +        PathTrackingInformation current = THREAD_LOCAL_LEVEL_INFO.get();
> +        if ( current  == null )
> +        {
> +            level = THREAD_LOCAL_LEVEL.get().incrementAndGet();
> +        }
> +        else
> +        {
> +            // same class so no inc
> +            if ( current.className.equals( pathTrackingInformation.className ) //
> +                && current.methodName.equals( pathTrackingInformation.methodName ) )
> +            {
> +                // yup sounds to be the same level so no level inc!
> +                level = THREAD_LOCAL_LEVEL.get().get();
> +            }
> +            else
> +            {
> +                level = THREAD_LOCAL_LEVEL.get().incrementAndGet();
> +            }
>
> -    }
> +            pathTrackingInformation.setParent( current );
> +        }
> +
> +        THREAD_LOCAL_LEVEL_INFO.set( pathTrackingInformation );
>
> +        //System.out.println("start level: " + level + " for key " + key);
> +
> +        return level;
> +    }
>
> -    public static void stop()
> +    /**
> +     * FIXME not sure we really need the uuid but just in case for future usage :-)
> +     */
> +    public static int stop( PathTrackingInformation pathTrackingInformation )
>      {
> +        int level = 0;
>
> +        PathTrackingInformation current = THREAD_LOCAL_LEVEL_INFO.get();
> +        // same class so no inc
> +        if ( current.className.equals( pathTrackingInformation.className ) //
> +            && current.methodName.equals( pathTrackingInformation.methodName ) )
> +        {
> +            // yup sounds to be the same level so no level inc!
> +            level = THREAD_LOCAL_LEVEL.get().get();
> +        }
> +        else
> +        {
> +            level = THREAD_LOCAL_LEVEL.get().decrementAndGet();
> +        }
> +
> +        THREAD_LOCAL_LEVEL_INFO.set( pathTrackingInformation );
> +
> +        //System.out.println("start level: " + level + " for key " + key);
> +
> +        return level;
>      }
> +
> +
>  }
>
> Copied: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java (from r1569202, incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java)
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java?p2=incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java&p1=incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java&r1=1569202&r2=1569203&rev=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java (original)
> +++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/tracking/PathTrackingEntryComparator.java Tue Feb 18 06:00:04 2014
> @@ -14,37 +14,24 @@
>   * See the License for the specific language governing permissions and
>   * limitations under the License.
>   */
> +package org.apache.sirona.tracking;
>
> -package org.apache.sirona.cassandra.pathtracking;
> -
> -import org.apache.sirona.store.tracking.PathTrackingDataStore;
> -import org.apache.sirona.tracking.PathTrackingEntry;
> -
> -import java.util.Date;
> -import java.util.List;
> +import java.util.Comparator;
>
>  /**
>   * @author Olivier Lamy
>   */
> -public class CassandraPathTrackingDataStore
> -    implements PathTrackingDataStore
> +public class PathTrackingEntryComparator
> +    implements Comparator<PathTrackingEntry>
>  {
>
> -    @Override
> -    public void store( PathTrackingEntry pathTrackingEntry )
> -    {
> -
> -    }
> -
> -    @Override
> -    public List<PathTrackingEntry> retrieve( String trackingId )
> -    {
> -        return null;
> -    }
> +    public static final PathTrackingEntryComparator INSTANCE = new PathTrackingEntryComparator();
>
>      @Override
> -    public List<String> retrieveTrackingIds( Date startTime, Date endTime )
> +    public int compare( PathTrackingEntry pathTrackingEntry, PathTrackingEntry pathTrackingEntry2 )
>      {
> -        return null;
> +        // TODO add level in comparator
> +        return Long.valueOf( pathTrackingEntry.getStartTime() ).compareTo(
> +            Long.valueOf( pathTrackingEntry2.getStartTime() ) );
>      }
>  }
>
> Modified: incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java
> URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java?rev=1569203&r1=1569202&r2=1569203&view=diff
> ==============================================================================
> --- incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java (original)
> +++ incubator/sirona/trunk/server/store/cassandra/src/main/java/org/apache/sirona/cassandra/pathtracking/CassandraPathTrackingDataStore.java Tue Feb 18 06:00:04 2014
> @@ -20,6 +20,7 @@ package org.apache.sirona.cassandra.path
>  import org.apache.sirona.store.tracking.PathTrackingDataStore;
>  import org.apache.sirona.tracking.PathTrackingEntry;
>
> +import java.util.Collection;
>  import java.util.Date;
>  import java.util.List;
>
> @@ -37,13 +38,13 @@ public class CassandraPathTrackingDataSt
>      }
>
>      @Override
> -    public List<PathTrackingEntry> retrieve( String trackingId )
> +    public Collection<PathTrackingEntry> retrieve( String trackingId )
>      {
>          return null;
>      }
>
>      @Override
> -    public List<String> retrieveTrackingIds( Date startTime, Date endTime )
> +    public Collection<String> retrieveTrackingIds( Date startTime, Date endTime )
>      {
>          return null;
>      }
>
>