You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sh...@apache.org on 2016/11/21 11:07:26 UTC

[2/2] incubator-atlas git commit: ATLAS-1116 Performance monitoring of backend methods in API requests (shwethags)

ATLAS-1116 Performance monitoring of backend methods in API requests (shwethags)


Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/1fa05264
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/1fa05264
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/1fa05264

Branch: refs/heads/master
Commit: 1fa05264311fbdbaf7f4cb63bb7b3e09628f80f8
Parents: 94a8272
Author: Shwetha GS <ss...@hortonworks.com>
Authored: Mon Nov 21 16:36:45 2016 +0530
Committer: Shwetha GS <ss...@hortonworks.com>
Committed: Mon Nov 21 16:36:45 2016 +0530

----------------------------------------------------------------------
 distro/src/conf/atlas-log4j.xml                 |  29 ++--
 docs/src/site/twiki/Configuration.twiki         |  15 +-
 docs/src/site/twiki/InstallationSteps.twiki     |   4 +
 pom.xml                                         |  34 ++++-
 release-log.txt                                 |   1 +
 repository/pom.xml                              |  41 ++++++
 .../atlas/repository/graph/FullTextMapper.java  |   4 +-
 .../atlas/repository/graph/GraphHelper.java     |  59 +++++---
 .../graph/GraphToTypedInstanceMapper.java       |  25 ++--
 .../graph/TypedInstanceToGraphMapper.java       |  32 +++--
 .../store/graph/v1/AtlasGraphUtilsV1.java       |   2 +-
 server-api/pom.xml                              |  54 ++++++-
 .../java/org/apache/atlas/RequestContext.java   |   6 +
 .../org/apache/atlas/aspect/AtlasAspect.java    |  67 +++++++++
 .../java/org/apache/atlas/aspect/Loggable.java  |  29 ++++
 .../java/org/apache/atlas/aspect/Monitored.java |  29 ++++
 .../java/org/apache/atlas/metrics/Metrics.java  |  68 +++++++++
 .../org/apache/atlas/MonitoredAspectTest.java   |  47 ++++++
 typesystem/src/main/resources/atlas-log4j.xml   |  16 ---
 webapp/pom.xml                                  |  51 +++++++
 .../apache/atlas/web/filters/AuditFilter.java   |  11 ++
 .../atlas/web/resources/AdminResource.java      | 142 +++++++------------
 .../web/resources/DataSetLineageResource.java   |  25 +---
 .../atlas/web/resources/EntityResource.java     | 138 ++++--------------
 .../atlas/web/resources/LineageResource.java    |  25 +---
 .../resources/MetadataDiscoveryResource.java    |  32 +----
 .../atlas/web/resources/TypesResource.java      |  35 +----
 27 files changed, 638 insertions(+), 383 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/distro/src/conf/atlas-log4j.xml
----------------------------------------------------------------------
diff --git a/distro/src/conf/atlas-log4j.xml b/distro/src/conf/atlas-log4j.xml
index 400cd3a..81120e2 100755
--- a/distro/src/conf/atlas-log4j.xml
+++ b/distro/src/conf/atlas-log4j.xml
@@ -43,6 +43,14 @@
         </layout>
     </appender>
 
+    <appender name="METRICS" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="${atlas.log.dir}/metric.log"/>
+        <param name="Append" value="true"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d %x %m%n"/>
+        </layout>
+    </appender>
+
     <appender name="FAILED" class="org.apache.log4j.DailyRollingFileAppender">
         <param name="File" value="${atlas.log.dir}/failed.log"/>
         <param name="Append" value="true"/>
@@ -56,22 +64,6 @@
         <appender-ref ref="FILE"/>
     </logger>
 
-    <!-- uncomment this block to generate performance traces
-    <appender name="perf_appender" class="org.apache.log4j.DailyRollingFileAppender">
-        <param name="file" value="${atlas.log.dir}/atlas_perf.log" />
-        <param name="datePattern" value="'.'yyyy-MM-dd" />
-        <param name="append" value="true" />
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="%d|%t|%m%n" />
-        </layout>
-    </appender>
-
-    <logger name="org.apache.atlas.perf" additivity="false">
-        <level value="debug" />
-        <appender-ref ref="perf_appender" />
-    </logger>
-    -->
-
     <logger name="com.thinkaurelius.titan" additivity="false">
         <level value="warn"/>
         <appender-ref ref="FILE"/>
@@ -88,6 +80,11 @@
         <appender-ref ref="AUDIT"/>
     </logger>
 
+    <logger name="METRICS" additivity="false">
+        <level value="debug"/>
+        <appender-ref ref="METRICS"/>
+    </logger>
+
     <logger name="FAILED" additivity="false">
         <level value="info"/>
         <appender-ref ref="AUDIT"/>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/docs/src/site/twiki/Configuration.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/Configuration.twiki b/docs/src/site/twiki/Configuration.twiki
index 7f24f88..3c1978c 100644
--- a/docs/src/site/twiki/Configuration.twiki
+++ b/docs/src/site/twiki/Configuration.twiki
@@ -283,4 +283,17 @@ atlas.webserver.keepalivetimesecs=60
 
 # Queue size for the requests(when max threads are busy) for the atlas web server
 atlas.webserver.queuesize=100
-</verbatim>
\ No newline at end of file
+</verbatim>
+
+---+++ Recording performance metrics
+
+Atlas package should be built with '-P perf' to instrument atlas code to collect metrics. The metrics will be recorded in
+<atlas.log.dir>/metric.log, with one log line per API call. The metrics contain the number of times the instrumented methods
+are called and the total time spent in the instrumented method. Logging to metric.log is controlled through log4j configuration
+in atlas-log4j.xml. When the atlas code is instrumented, to disable logging to metric.log at runtime, set log level of METRICS logger to info level:
+<verbatim>
+<logger name="METRICS" additivity="false">
+    <level value="info"/>
+    <appender-ref ref="METRICS"/>
+</logger>
+</verbatim>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/docs/src/site/twiki/InstallationSteps.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/InstallationSteps.twiki b/docs/src/site/twiki/InstallationSteps.twiki
index 4dae7a3..bd6921e 100644
--- a/docs/src/site/twiki/InstallationSteps.twiki
+++ b/docs/src/site/twiki/InstallationSteps.twiki
@@ -18,6 +18,10 @@ mvn clean package -Pdist
 
 </verbatim>
 
+NOTE:
+1. Use option '-DskipTests' to skip running unit and integration tests
+2. Use option '-P perf' to instrument atlas to collect performance metrics
+
 To build a distribution that configures Atlas for external HBase and Solr, build with the external-hbase-solr profile.
 
 <verbatim>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1b3975f..87ec46a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -491,9 +491,23 @@
         <entity.repository.impl>org.apache.atlas.repository.audit.InMemoryEntityAuditRepository</entity.repository.impl>
 	    <graphdb.backend.impl>org.apache.atlas.repository.graphdb.titan0.Titan0GraphDatabase</graphdb.backend.impl>
         <atlas.surefire.options></atlas.surefire.options>
+
+        <aspectj.runtime.version>1.8.7</aspectj.runtime.version>
+        <aspectj.skip>true</aspectj.skip>
     </properties>
 
     <profiles>
+        <!-- Turn on this profile to instrument atlas server to collect performance metrics -->
+        <profile>
+            <id>perf</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <properties>
+                <aspectj.skip>false</aspectj.skip>
+            </properties>
+        </profile>
+
         <!-- Turning on this profile affects only tests and does not affect packaging -->
         <profile>
             <id>distributed</id>
@@ -618,6 +632,18 @@
 
     <dependencyManagement>
         <dependencies>
+            <!-- AOP dependencies. -->
+            <dependency>
+                <groupId>org.aspectj</groupId>
+                <artifactId>aspectjrt</artifactId>
+                <version>${aspectj.runtime.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.aspectj</groupId>
+                <artifactId>aspectjtools</artifactId>
+                <version>${aspectj.runtime.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-jsp</artifactId>
@@ -1631,6 +1657,12 @@
                         <excludeGroupIds>org.restlet.jee</excludeGroupIds>                       
                     </configuration>
                 </plugin>
+
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>aspectj-maven-plugin</artifactId>
+                    <version>1.8</version>
+                </plugin>
             </plugins>
         </pluginManagement>
 
@@ -1783,7 +1815,7 @@
                     <excludeSubProjects>true</excludeSubProjects>
                     <excludes>
                         <exclude>**/dependency-reduced-pom.xml</exclude>
-			<exclude>**/javax.script.ScriptEngineFactory</exclude>
+			            <exclude>**/javax.script.ScriptEngineFactory</exclude>
                         <exclude>.reviewboardrc</exclude>
                         <exclude>3party-licenses/**</exclude>
                         <exclude>**/.cache</exclude>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index a8f65c4..0f9d5db 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
 ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
 
 ALL CHANGES:
+ATLAS-1116 Performance monitoring of backend methods in API requests (shwethags)
 ATLAS-1310 attempt LDAP authentication only when enabled (mneethiraj)
 ATLAS-1309 updated HBase model with addition of column-family and column entity-defs (mneethiraj)
 ATLAS-916 Return System Attributes in get entity definition (svimal2106)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/repository/pom.xml
----------------------------------------------------------------------
diff --git a/repository/pom.xml b/repository/pom.xml
index 949118b..7db4f42 100755
--- a/repository/pom.xml
+++ b/repository/pom.xml
@@ -219,6 +219,47 @@
                 <groupId>net.alchim31.maven</groupId>
                 <artifactId>scala-maven-plugin</artifactId>
             </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>aspectj-maven-plugin</artifactId>
+                <configuration>
+                    <complianceLevel>1.7</complianceLevel>
+                    <includes>
+                        <include>**/*.java</include>
+                        <include>**/*.aj</include>
+                    </includes>
+                    <XaddSerialVersionUID>true</XaddSerialVersionUID>
+                    <showWeaveInfo>true</showWeaveInfo>
+                    <aspectLibraries>
+                        <aspectLibrary>
+                            <groupId>org.apache.atlas</groupId>
+                            <artifactId>atlas-server-api</artifactId>
+                        </aspectLibrary>
+                    </aspectLibraries>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>compile_with_aspectj</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.aspectj</groupId>
+                        <artifactId>aspectjtools</artifactId>
+                        <version>${aspectj.runtime.version}</version>
+                    </dependency>
+
+                    <dependency>
+                        <groupId>org.apache.atlas</groupId>
+                        <artifactId>atlas-server-api</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
         </plugins>
     </build>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/repository/src/main/java/org/apache/atlas/repository/graph/FullTextMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/FullTextMapper.java b/repository/src/main/java/org/apache/atlas/repository/graph/FullTextMapper.java
index 053e8ac..2c12bc3 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/FullTextMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/FullTextMapper.java
@@ -17,8 +17,9 @@
  */
 package org.apache.atlas.repository.graph;
 
-import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.AtlasException;
+import org.apache.atlas.aspect.Monitored;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.typesystem.ITypedInstance;
 import org.apache.atlas.typesystem.ITypedReferenceableInstance;
 import org.apache.atlas.typesystem.types.AttributeInfo;
@@ -49,6 +50,7 @@ public class FullTextMapper {
         instanceCache = new HashMap<>();
     }
 
+    @Monitored
     public String mapRecursive(AtlasVertex instanceVertex, boolean followReferences) throws AtlasException {
         String guid = GraphHelper.getIdFromVertex(instanceVertex);
         ITypedReferenceableInstance typedReference;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
index 4c2bd76..6cecd46 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
@@ -18,20 +18,13 @@
 
 package org.apache.atlas.repository.graph;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.Stack;
-import java.util.UUID;
-import java.util.Date;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
 import org.apache.atlas.ApplicationProperties;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.RequestContext;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.RepositoryException;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
@@ -65,9 +58,15 @@ import org.codehaus.jettison.json.JSONArray;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+import java.util.UUID;
 
 /**
  * Utility class for graph operations.
@@ -138,6 +137,7 @@ public final class GraphHelper {
         return vertexWithIdentity;
     }
 
+    @Monitored
     public AtlasVertex createVertexWithoutIdentity(String typeName, Id typedInstanceId, Set<String> superTypeNames) {
         LOG.debug("Creating AtlasVertex for type {} id {}", typeName,
                 typedInstanceId != null ? typedInstanceId._getId() : null);
@@ -165,6 +165,7 @@ public final class GraphHelper {
         return vertexWithoutIdentity;
     }
 
+    @Monitored
     private AtlasEdge addEdge(AtlasVertex fromVertex, AtlasVertex toVertex, String edgeLabel) {
         LOG.debug("Adding edge for {} -> label {} -> {}", string(fromVertex), edgeLabel, string(toVertex));
         AtlasEdge edge = graph.addEdge(fromVertex, toVertex, edgeLabel);
@@ -216,7 +217,7 @@ public final class GraphHelper {
         return null;
     }
 
-
+    @Monitored
     public AtlasEdge getEdgeByEdgeId(AtlasVertex outVertex, String edgeLabel, String edgeId) {
         if (edgeId == null) {
             return null;
@@ -242,6 +243,7 @@ public final class GraphHelper {
      * @return AtlasVertex with the given property keys
      * @throws EntityNotFoundException
      */
+    @Monitored
     public AtlasVertex findVertex(Object... args) throws EntityNotFoundException {
         StringBuilder condition = new StringBuilder();
         AtlasGraphQuery query = graph.query();
@@ -268,6 +270,7 @@ public final class GraphHelper {
 
     //In some cases of parallel APIs, the edge is added, but get edge by label doesn't return the edge. ATLAS-1104
     //So traversing all the edges
+    @Monitored
     public Iterator<AtlasEdge> getAdjacentEdgesByLabel(AtlasVertex instanceVertex, AtlasEdgeDirection direction, final String edgeLabel) {
         LOG.debug("Finding edges for {} with label {}", string(instanceVertex), edgeLabel);
         if(instanceVertex != null && edgeLabel != null) {
@@ -316,6 +319,7 @@ public final class GraphHelper {
      * @param edgeLabel
      * @return
      */
+    @Monitored
     public AtlasEdge getEdgeForLabel(AtlasVertex vertex, String edgeLabel) {
         Iterator<AtlasEdge> iterator = getAdjacentEdgesByLabel(vertex, AtlasEdgeDirection.OUT, edgeLabel);
         AtlasEdge latestDeletedEdge = null;
@@ -340,6 +344,7 @@ public final class GraphHelper {
         return latestDeletedEdge;
     }
 
+    @Monitored
     public static String vertexString(final AtlasVertex vertex) {
         StringBuilder properties = new StringBuilder();
         for (String propertyKey : vertex.getPropertyKeys()) {
@@ -350,11 +355,13 @@ public final class GraphHelper {
         return "v[" + vertex.getIdForDisplay() + "], Properties[" + properties + "]";
     }
 
+    @Monitored
     public static String edgeString(final AtlasEdge edge) {
         return "e[" + edge.getLabel() + "], [" + edge.getOutVertex() + " -> " + edge.getLabel() + " -> "
                 + edge.getInVertex() + "]";
     }
 
+    @Monitored
     public static <T extends AtlasElement> void setProperty(T element, String propertyName, Object value) {
         String elementStr = string(element);
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
@@ -383,6 +390,7 @@ public final class GraphHelper {
      * @param clazz
      * @return
      */
+    @Monitored
     public static <T> T getSingleValuedProperty(AtlasElement element, String propertyName, Class<T> clazz) {
         String elementStr = string(element);
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
@@ -390,8 +398,9 @@ public final class GraphHelper {
        
         return (T)element.getProperty(actualPropertyName, clazz);              
     }
-    
-    
+
+
+    @Monitored
     public static Object getProperty(AtlasVertex<?,?> vertex, String propertyName) {
         String elementStr = string(vertex);
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
@@ -403,9 +412,9 @@ public final class GraphHelper {
         else {
             return vertex.getProperty(actualPropertyName, Object.class);
         }
-        
     }
-    
+
+    @Monitored
     public static Object getProperty(AtlasEdge<?,?> edge, String propertyName) {
         String elementStr = string(edge);
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
@@ -429,6 +438,7 @@ public final class GraphHelper {
      * @param propertyName
      * @param value
      */
+    @Monitored
     public static void addProperty(AtlasVertex vertex, String propertyName, Object value) {
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
         LOG.debug("Adding property {} = \"{}\" to vertex {}", actualPropertyName, value, string(vertex));
@@ -440,6 +450,7 @@ public final class GraphHelper {
      *
      * @param edge
      */
+    @Monitored
     public void removeEdge(AtlasEdge edge) {
         String edgeString = string(edge);
         LOG.debug("Removing {}", edgeString);
@@ -450,8 +461,9 @@ public final class GraphHelper {
     /**
      * Remove the specified AtlasVertex from the graph.
      *
-     * @param AtlasVertex
+     * @param vertex
      */
+    @Monitored
     public void removeVertex(AtlasVertex vertex) {
         String vertexString = string(vertex);
         LOG.debug("Removing {}", vertexString);
@@ -746,6 +758,7 @@ public final class GraphHelper {
 
     }
 
+    @Monitored
     public static void setArrayElementsProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName, List<Object> values) {
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
         if(GraphHelper.isReference(elementType)) {
@@ -756,6 +769,7 @@ public final class GraphHelper {
         }
     }
 
+    @Monitored
     public static void setMapValueProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName, Object value) {
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
         if(GraphHelper.isReference(elementType)) {
@@ -766,6 +780,7 @@ public final class GraphHelper {
         }
     }
 
+    @Monitored
     public static Object getMapValueProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName) {
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
         if(GraphHelper.isReference(elementType)) {
@@ -776,6 +791,7 @@ public final class GraphHelper {
         }
     }
 
+    @Monitored
     public static List<Object> getArrayElementsProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName) {
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
         if(GraphHelper.isReference(elementType)) {
@@ -918,7 +934,4 @@ public final class GraphHelper {
         String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
         return instanceVertex.getListProperty(actualPropertyName);    
     }
-    
-
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
index 8dd548a..84608d9 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
@@ -17,17 +17,9 @@
  */
 package org.apache.atlas.repository.graph;
 
-import static org.apache.atlas.repository.graph.GraphHelper.string;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.google.inject.Singleton;
 import org.apache.atlas.AtlasException;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
@@ -51,7 +43,15 @@ import org.apache.atlas.typesystem.types.TypeSystem;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Singleton;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.atlas.repository.graph.GraphHelper.string;
 
 @Singleton
 public final class GraphToTypedInstanceMapper {
@@ -66,6 +66,7 @@ public final class GraphToTypedInstanceMapper {
         this.graph = graph;
     }
 
+    @Monitored
     public ITypedReferenceableInstance mapGraphToTypedInstance(String guid, AtlasVertex instanceVertex)
         throws AtlasException {
 
@@ -95,6 +96,7 @@ public final class GraphToTypedInstanceMapper {
         return typedInstance;
     }
 
+    @Monitored
     private void mapVertexToInstanceTraits(AtlasVertex instanceVertex, ITypedReferenceableInstance typedInstance,
         List<String> traits) throws AtlasException {
         for (String traitName : traits) {
@@ -104,6 +106,7 @@ public final class GraphToTypedInstanceMapper {
         }
     }
 
+    @Monitored
     public void mapVertexToInstance(AtlasVertex instanceVertex, ITypedInstance typedInstance,
         Map<String, AttributeInfo> fields) throws AtlasException {
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
index 62b0be0..78e276e 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
@@ -17,21 +17,10 @@
  */
 package org.apache.atlas.repository.graph;
 
-import static org.apache.atlas.repository.graph.GraphHelper.string;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.inject.Inject;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.RequestContext;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.RepositoryException;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
@@ -59,7 +48,18 @@ import org.apache.atlas.utils.MD5Utils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.atlas.repository.graph.GraphHelper.string;
 
 public final class TypedInstanceToGraphMapper {
 
@@ -85,9 +85,9 @@ public final class TypedInstanceToGraphMapper {
         UPDATE_FULL
     }
 
+    @Monitored
     void mapTypedInstanceToGraph(Operation operation, ITypedReferenceableInstance... typedInstances)
             throws AtlasException {
-
         RequestContext requestContext = RequestContext.get();
         for (ITypedReferenceableInstance typedInstance : typedInstances) {
             LOG.debug("Adding/updating entity {}", typedInstance);
@@ -150,6 +150,7 @@ public final class TypedInstanceToGraphMapper {
         return guids;
     }
 
+    @Monitored
     private String addOrUpdateAttributesAndTraits(Operation operation, ITypedReferenceableInstance typedInstance)
             throws AtlasException {
         LOG.debug("Adding/Updating typed instance {}", typedInstance.toShortString());
@@ -235,6 +236,7 @@ public final class TypedInstanceToGraphMapper {
         }
     }
 
+    @Monitored
     private TypeUtils.Pair<List<ITypedReferenceableInstance>, List<ITypedReferenceableInstance>> createVerticesAndDiscoverInstances(
             Collection<IReferenceableInstance> instances) throws AtlasException {
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java
index cb389a9..bef6d18 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java
@@ -142,7 +142,7 @@ public class AtlasGraphUtilsV1 {
         return returnType.cast(property);
     }
 
-    private static <T extends AtlasElement> String toString(T element) {
+    private static String toString(AtlasElement element) {
         if (element instanceof AtlasVertex) {
             return toString((AtlasVertex) element);
         } else if (element instanceof AtlasEdge) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/pom.xml
----------------------------------------------------------------------
diff --git a/server-api/pom.xml b/server-api/pom.xml
index c183468..42c2f9a 100644
--- a/server-api/pom.xml
+++ b/server-api/pom.xml
@@ -60,6 +60,58 @@
             <groupId>org.apache.atlas</groupId>
             <artifactId>atlas-client</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjrt</artifactId>
+        </dependency>
     </dependencies>
 
-</project>
\ No newline at end of file
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>aspectj-maven-plugin</artifactId>
+                <configuration>
+                    <complianceLevel>1.7</complianceLevel>
+                    <showWeaveInfo>true</showWeaveInfo>
+                    <verbose>true</verbose>
+                    <forceAjcCompile>true</forceAjcCompile>
+                    <includes>
+                        <include>**/*.java</include>
+                        <include>**/*.aj</include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>compile_with_aspectj</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <aspectDirectory>src/main/java</aspectDirectory>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>test-compile_with_aspectj</id>
+                        <goals>
+                            <goal>test-compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.aspectj</groupId>
+                        <artifactId>aspectjrt</artifactId>
+                        <version>${aspectj.runtime.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.aspectj</groupId>
+                        <artifactId>aspectjtools</artifactId>
+                        <version>${aspectj.runtime.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/src/main/java/org/apache/atlas/RequestContext.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/RequestContext.java b/server-api/src/main/java/org/apache/atlas/RequestContext.java
index ec38c11..651a71d 100644
--- a/server-api/src/main/java/org/apache/atlas/RequestContext.java
+++ b/server-api/src/main/java/org/apache/atlas/RequestContext.java
@@ -18,6 +18,7 @@
 
 package org.apache.atlas;
 
+import org.apache.atlas.metrics.Metrics;
 import org.apache.atlas.typesystem.ITypedReferenceableInstance;
 import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.types.ClassType;
@@ -45,6 +46,7 @@ public class RequestContext {
     private long requestTime;
 
     TypeSystem typeSystem = TypeSystem.getInstance();
+    private Metrics metrics = new Metrics();
 
     private RequestContext() {
     }
@@ -124,4 +126,8 @@ public class RequestContext {
     public boolean isDeletedEntity(String entityGuid) {
         return deletedEntityIds.contains(entityGuid);
     }
+
+    public static Metrics getMetrics() {
+        return get().metrics;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/src/main/java/org/apache/atlas/aspect/AtlasAspect.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/aspect/AtlasAspect.java b/server-api/src/main/java/org/apache/atlas/aspect/AtlasAspect.java
new file mode 100644
index 0000000..2801750
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/aspect/AtlasAspect.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.aspect;
+
+import org.apache.atlas.RequestContext;
+import org.apache.atlas.metrics.Metrics;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+@Aspect
+public class AtlasAspect {
+
+    public static final Logger LOG = LoggerFactory.getLogger(AtlasAspect.class);
+
+    @Around("@annotation(org.apache.atlas.aspect.Monitored) && execution(* *(..))")
+    public Object collectMetricsForMonitored(ProceedingJoinPoint joinPoint) throws Throwable {
+        Signature methodSign = joinPoint.getSignature();
+        Metrics metrics = RequestContext.getMetrics();
+        String metricName = methodSign.getDeclaringType().getSimpleName() + "." + methodSign.getName();
+        long start = System.currentTimeMillis();
+
+        try {
+            Object response = joinPoint.proceed();
+            return response;
+        } finally {
+            metrics.record(metricName, (System.currentTimeMillis() - start));
+        }
+    }
+
+    @Around("@annotation(org.apache.atlas.aspect.Loggable) && execution(* *(..))")
+    public Object logAroundLoggable(ProceedingJoinPoint joinPoint) throws Throwable {
+        Signature methodSign = joinPoint.getSignature();
+        String methodName = methodSign.getDeclaringType().getSimpleName() + "." + methodSign.getName();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(String.format("==> %s(%s)", methodName, joinPoint.getArgs()));
+        }
+        Object response = joinPoint.proceed();
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(String.format("<== %s(%s): %s", methodName, joinPoint.getArgs(),
+                    response instanceof List ? ((List)response).size() : response));
+        }
+        return response;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/src/main/java/org/apache/atlas/aspect/Loggable.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/aspect/Loggable.java b/server-api/src/main/java/org/apache/atlas/aspect/Loggable.java
new file mode 100644
index 0000000..64f2169
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/aspect/Loggable.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Loggable {
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/src/main/java/org/apache/atlas/aspect/Monitored.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/aspect/Monitored.java b/server-api/src/main/java/org/apache/atlas/aspect/Monitored.java
new file mode 100644
index 0000000..909fab6
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/aspect/Monitored.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Monitored {
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/src/main/java/org/apache/atlas/metrics/Metrics.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/metrics/Metrics.java b/server-api/src/main/java/org/apache/atlas/metrics/Metrics.java
new file mode 100644
index 0000000..e0f4e49
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/metrics/Metrics.java
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.metrics;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class Metrics {
+    public static class Counters {
+        private short invocations = 0;
+        private long totalTimeMSecs = 0;
+
+        @Override
+        public String toString() {
+            return "[count=" + invocations + ", totalTimeMSec=" + totalTimeMSecs + "]";
+        }
+
+        public short getInvocations() {
+            return invocations;
+        }
+
+        public long getTotalTimeMSecs() {
+            return totalTimeMSecs;
+        }
+    }
+
+    Map<String, Counters> countersMap = new LinkedHashMap<>();
+
+    public void record(String name, long timeMsecs) {
+        Counters counter = countersMap.get(name);
+        if (counter == null) {
+            counter = new Counters();
+            countersMap.put(name, counter);
+        }
+
+        counter.invocations++;
+        counter.totalTimeMSecs += timeMsecs;
+    }
+
+    @Override
+    public String toString() {
+        return countersMap.toString();
+    }
+
+    public boolean isEmpty() {
+        return countersMap.isEmpty();
+    }
+
+    public Counters getCounters(String name) {
+        return countersMap.get(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/server-api/src/test/aspect/org/apache/atlas/MonitoredAspectTest.java
----------------------------------------------------------------------
diff --git a/server-api/src/test/aspect/org/apache/atlas/MonitoredAspectTest.java b/server-api/src/test/aspect/org/apache/atlas/MonitoredAspectTest.java
new file mode 100644
index 0000000..a53d97c
--- /dev/null
+++ b/server-api/src/test/aspect/org/apache/atlas/MonitoredAspectTest.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas;
+
+import org.apache.atlas.aspect.Monitored;
+import org.apache.atlas.metrics.Metrics;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+public class MonitoredAspectTest {
+
+    @Monitored
+    public void monitoredMethod() throws InterruptedException {
+        Thread.sleep(1);
+    }
+
+    @Test
+    public void testMonitoredAspect() throws Exception {
+        RequestContext.clear();
+        monitoredMethod();
+
+        Metrics metrics = RequestContext.getMetrics();
+        Metrics.Counters counters = metrics.getCounters("MonitoredAspectTest.monitoredMethod");
+        assertNotNull(counters);
+        assertEquals(counters.getInvocations(), 1);
+        assertTrue(counters.getTotalTimeMSecs() > 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/typesystem/src/main/resources/atlas-log4j.xml
----------------------------------------------------------------------
diff --git a/typesystem/src/main/resources/atlas-log4j.xml b/typesystem/src/main/resources/atlas-log4j.xml
index 8312657..a58898c 100755
--- a/typesystem/src/main/resources/atlas-log4j.xml
+++ b/typesystem/src/main/resources/atlas-log4j.xml
@@ -41,22 +41,6 @@
         <appender-ref ref="console"/>
     </logger>
 
-    <!-- uncomment this block to generate performance traces
-    <appender name="perf_appender" class="org.apache.log4j.DailyRollingFileAppender">
-        <param name="file" value="${atlas.log.dir}/atlas_perf.log" />
-        <param name="datePattern" value="'.'yyyy-MM-dd" />
-        <param name="append" value="true" />
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="%d|%t|%m%n" />
-        </layout>
-    </appender>
-
-    <logger name="org.apache.atlas.perf" additivity="false">
-        <level value="debug" />
-        <appender-ref ref="perf_appender" />
-    </logger>
-    -->
-
     <appender name="FAILED" class="org.apache.log4j.DailyRollingFileAppender">
         <param name="File" value="${atlas.log.dir}/failed.log"/>
         <param name="Append" value="true"/>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/webapp/pom.xml b/webapp/pom.xml
index 2bef274..09701e1 100755
--- a/webapp/pom.xml
+++ b/webapp/pom.xml
@@ -384,6 +384,16 @@
                 </exclusion>
             </exclusions>
         </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjrt</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.atlas</groupId>
+            <artifactId>atlas-server-api</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
@@ -607,6 +617,47 @@
                     </execution>
                 </executions>
             </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>aspectj-maven-plugin</artifactId>
+                <configuration>
+                    <complianceLevel>1.7</complianceLevel>
+                    <includes>
+                        <include>**/*.java</include>
+                        <include>**/*.aj</include>
+                    </includes>
+                    <XaddSerialVersionUID>true</XaddSerialVersionUID>
+                    <showWeaveInfo>true</showWeaveInfo>
+                    <aspectLibraries>
+                        <aspectLibrary>
+                            <groupId>org.apache.atlas</groupId>
+                            <artifactId>atlas-server-api</artifactId>
+                        </aspectLibrary>
+                    </aspectLibraries>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>compile_with_aspectj</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.aspectj</groupId>
+                        <artifactId>aspectjtools</artifactId>
+                        <version>${aspectj.runtime.version}</version>
+                    </dependency>
+
+                    <dependency>
+                        <groupId>org.apache.atlas</groupId>
+                        <artifactId>atlas-server-api</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
         </plugins>
     </build>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java b/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
index 79b5be4..7499cde 100755
--- a/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
@@ -21,6 +21,7 @@ package org.apache.atlas.web.filters;
 import com.google.inject.Singleton;
 import org.apache.atlas.AtlasClient;
 import org.apache.atlas.RequestContext;
+import org.apache.atlas.metrics.Metrics;
 import org.apache.atlas.web.util.DateTimeHelper;
 import org.apache.atlas.web.util.Servlets;
 import org.slf4j.Logger;
@@ -47,6 +48,7 @@ public class AuditFilter implements Filter {
 
     private static final Logger AUDIT_LOG = LoggerFactory.getLogger("AUDIT");
     private static final Logger LOG = LoggerFactory.getLogger(AuditFilter.class);
+    private static final Logger METRICS_LOG = LoggerFactory.getLogger("METRICS");
 
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
@@ -73,6 +75,7 @@ public class AuditFilter implements Filter {
             // put the request id into the response so users can trace logs for this request
             ((HttpServletResponse) response).setHeader(AtlasClient.REQUEST_ID, requestId);
             currentThread.setName(oldName);
+            recordMetrics();
             RequestContext.clear();
         }
     }
@@ -103,6 +106,14 @@ public class AuditFilter implements Filter {
                 whatAddrs, whenISO9601);
     }
 
+    public static void recordMetrics() {
+        //record metrics
+        Metrics requestMetrics = RequestContext.getMetrics();
+        if (!requestMetrics.isEmpty()) {
+            METRICS_LOG.info("{}", requestMetrics);
+        }
+     }
+
     @Override
     public void destroy() {
         // do nothing

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
index 4b45927..ec5d891 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
@@ -18,19 +18,9 @@
 
 package org.apache.atlas.web.resources;
 
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
+import com.google.inject.Inject;
 import org.apache.atlas.AtlasClient;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.utils.AtlasPerfTracer;
 import org.apache.atlas.web.filters.AtlasCSRFPreventionFilter;
 import org.apache.atlas.web.service.ServiceState;
@@ -45,7 +35,16 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 
-import com.google.inject.Inject;
+import javax.inject.Singleton;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Jersey Resource for admin operations.
@@ -74,36 +73,27 @@ public class AdminResource {
      *
      * @return json representing the thread stack dump.
      */
+    @Monitored
     @GET
     @Path("stack")
     @Produces(MediaType.TEXT_PLAIN)
     public String getThreadDump() {
-        AtlasPerfTracer perf = null;
+        ThreadGroup topThreadGroup = Thread.currentThread().getThreadGroup();
 
-        try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "AdminResource.getThreadDump()");
-            }
-
-            ThreadGroup topThreadGroup = Thread.currentThread().getThreadGroup();
-
-            while (topThreadGroup.getParent() != null) {
-                topThreadGroup = topThreadGroup.getParent();
-            }
-            Thread[] threads = new Thread[topThreadGroup.activeCount()];
-
-            int nr = topThreadGroup.enumerate(threads);
-            StringBuilder builder = new StringBuilder();
-            for (int i = 0; i < nr; i++) {
-                builder.append(threads[i].getName()).append("\nState: ").
-                        append(threads[i].getState()).append("\n");
-                String stackTrace = StringUtils.join(threads[i].getStackTrace(), "\n");
-                builder.append(stackTrace);
-            }
-            return builder.toString();
-        } finally {
-            AtlasPerfTracer.log(perf);
+        while (topThreadGroup.getParent() != null) {
+            topThreadGroup = topThreadGroup.getParent();
         }
+        Thread[] threads = new Thread[topThreadGroup.activeCount()];
+
+        int nr = topThreadGroup.enumerate(threads);
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < nr; i++) {
+            builder.append(threads[i].getName()).append("\nState: ").
+                    append(threads[i].getState()).append("\n");
+            String stackTrace = StringUtils.join(threads[i].getStackTrace(), "\n");
+            builder.append(stackTrace);
+        }
+        return builder.toString();
     }
 
     /**
@@ -111,77 +101,55 @@ public class AdminResource {
      *
      * @return json representing the version.
      */
+    @Monitored
     @GET
     @Path("version")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getVersion() {
-        AtlasPerfTracer perf = null;
-
-        try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "AdminResource.getVersion()");
-            }
-
-            if (version == null) {
-                try {
-                    PropertiesConfiguration configProperties = new PropertiesConfiguration("atlas-buildinfo.properties");
-
-                    JSONObject response = new JSONObject();
-                    response.put("Version", configProperties.getString("build.version", "UNKNOWN"));
-                    response.put("Name", configProperties.getString("project.name", "apache-atlas"));
-                    response.put("Description", configProperties.getString("project.description",
-                            "Metadata Management and Data Governance Platform over Hadoop"));
-
-                    // todo: add hadoop version?
-                    // response.put("Hadoop", VersionInfo.getVersion() + "-r" + VersionInfo.getRevision());
-                    version = Response.ok(response).build();
-                } catch (JSONException | ConfigurationException e) {
-                    throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-                }
+        if (version == null) {
+            try {
+                PropertiesConfiguration configProperties = new PropertiesConfiguration("atlas-buildinfo.properties");
+
+                JSONObject response = new JSONObject();
+                response.put("Version", configProperties.getString("build.version", "UNKNOWN"));
+                response.put("Name", configProperties.getString("project.name", "apache-atlas"));
+                response.put("Description", configProperties.getString("project.description",
+                        "Metadata Management and Data Governance Platform over Hadoop"));
+
+                // todo: add hadoop version?
+                // response.put("Hadoop", VersionInfo.getVersion() + "-r" + VersionInfo.getRevision());
+                version = Response.ok(response).build();
+            } catch (JSONException | ConfigurationException e) {
+                throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
             }
-
-            return version;
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
+
+        return version;
     }
 
+    @Monitored
     @GET
     @Path("status")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getStatus() {
-        AtlasPerfTracer perf = null;
-
+        JSONObject responseData = new JSONObject();
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "AdminResource.getStatus()");
-            }
-
-            JSONObject responseData = new JSONObject();
-            try {
-                responseData.put(AtlasClient.STATUS, serviceState.getState().toString());
-                Response response = Response.ok(responseData).build();
-                return response;
-            } catch (JSONException e) {
-                throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-            }
-        } finally {
-            AtlasPerfTracer.log(perf);
+            responseData.put(AtlasClient.STATUS, serviceState.getState().toString());
+            Response response = Response.ok(responseData).build();
+            return response;
+        } catch (JSONException e) {
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
         }
     }
-    
+
+    @Monitored
     @GET
     @Path("session")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getUserProfile() {
         JSONObject responseData = new JSONObject();
         Boolean enableTaxonomy = null;
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "AdminResource.getUserProfile()");
-            }
-
             PropertiesConfiguration configProperties = new PropertiesConfiguration("atlas-application.properties");
             enableTaxonomy = new Boolean(configProperties.getString(isTaxonomyEnabled, "false"));
             Authentication auth = SecurityContextHolder.getContext().getAuthentication();
@@ -208,8 +176,6 @@ public class AdminResource {
             return response;
         } catch (JSONException | ConfigurationException e) {
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java
index a11c0cf..8192b07 100644
--- a/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java
@@ -19,6 +19,7 @@
 package org.apache.atlas.web.resources;
 
 import org.apache.atlas.AtlasClient;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.discovery.DiscoveryException;
 import org.apache.atlas.discovery.LineageService;
 import org.apache.atlas.typesystem.exception.EntityNotFoundException;
@@ -68,6 +69,7 @@ public class DataSetLineageResource {
      *
      * @param tableName table name
      */
+    @Monitored
     @GET
     @Path("table/{tableName}/inputs/graph")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
@@ -75,12 +77,7 @@ public class DataSetLineageResource {
     public Response inputsGraph(@Context HttpServletRequest request, @PathParam("tableName") String tableName) {
         LOG.info("Fetching lineage inputs graph for tableName={}", tableName);
 
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DataSetLineageResource.inputsGraph(" + tableName + ")");
-            }
-
             final String jsonResult = lineageService.getInputsGraph(tableName);
 
             JSONObject response = new JSONObject();
@@ -98,8 +95,6 @@ public class DataSetLineageResource {
         } catch (Throwable e) {
             LOG.error("Unable to get lineage inputs graph for table {}", tableName, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -108,6 +103,7 @@ public class DataSetLineageResource {
      *
      * @param tableName table name
      */
+    @Monitored
     @GET
     @Path("table/{tableName}/outputs/graph")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
@@ -115,12 +111,7 @@ public class DataSetLineageResource {
     public Response outputsGraph(@Context HttpServletRequest request, @PathParam("tableName") String tableName) {
         LOG.info("Fetching lineage outputs graph for tableName={}", tableName);
 
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DataSetLineageResource.outputsGraph(" + tableName + ")");
-            }
-
             final String jsonResult = lineageService.getOutputsGraph(tableName);
 
             JSONObject response = new JSONObject();
@@ -138,8 +129,6 @@ public class DataSetLineageResource {
         } catch (Throwable e) {
             LOG.error("Unable to get lineage outputs graph for table {}", tableName, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -148,6 +137,7 @@ public class DataSetLineageResource {
      *
      * @param tableName table name
      */
+    @Monitored
     @GET
     @Path("table/{tableName}/schema")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
@@ -155,12 +145,7 @@ public class DataSetLineageResource {
     public Response schema(@Context HttpServletRequest request, @PathParam("tableName") String tableName) {
         LOG.info("Fetching schema for tableName={}", tableName);
 
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DataSetLineageResource.schema(" + tableName + ")");
-            }
-
             final String jsonResult = lineageService.getSchema(tableName);
 
             JSONObject response = new JSONObject();
@@ -178,8 +163,6 @@ public class DataSetLineageResource {
         } catch (Throwable e) {
             LOG.error("Unable to get schema for table {}", tableName, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
index 230265b..8a663c2 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
@@ -24,6 +24,7 @@ import org.apache.atlas.AtlasClient;
 import org.apache.atlas.AtlasConstants;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.EntityAuditEvent;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.services.MetadataService;
 import org.apache.atlas.typesystem.IStruct;
 import org.apache.atlas.typesystem.Referenceable;
@@ -33,8 +34,8 @@ import org.apache.atlas.typesystem.exception.TraitNotFoundException;
 import org.apache.atlas.typesystem.exception.TypeNotFoundException;
 import org.apache.atlas.typesystem.json.InstanceSerialization;
 import org.apache.atlas.typesystem.types.ValueConversionException;
-import org.apache.atlas.utils.ParamChecker;
 import org.apache.atlas.utils.AtlasPerfTracer;
+import org.apache.atlas.utils.ParamChecker;
 import org.apache.atlas.web.util.Servlets;
 import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
@@ -104,18 +105,13 @@ public class EntityResource {
      * The body contains the JSONArray of entity json. The service takes care of de-duping the entities based on any
      * unique attribute for the give type.
      */
+    @Monitored
     @POST
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response submit(@Context HttpServletRequest request) {
-
         String entityJson = null;
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.submit()");
-            }
-
             String entities = Servlets.getRequestPayload(request);
 
             //Handle backward compatibility - if entities is not JSONArray, convert to JSONArray
@@ -151,8 +147,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to persist entity instance entityDef={}", entityJson, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -190,18 +184,13 @@ public class EntityResource {
      * Adds/Updates given entities identified by its GUID or unique attribute
      * @return response payload as json
      */
+    @Monitored
     @PUT
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response updateEntities(@Context HttpServletRequest request) {
-
         String entityJson = null;
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.updateEntities()");
-            }
-
             final String entities = Servlets.getRequestPayload(request);
 
             entityJson = AtlasClient.toString(new JSONArray(entities));
@@ -224,8 +213,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to persist entity instance entityDef={}", entityJson, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -258,6 +245,7 @@ public class EntityResource {
      * The body contains the JSONArray of entity json. The service takes care of de-duping the entities based on any
      * unique attribute for the give type.
      */
+    @Monitored
     @POST
     @Path("qualifiedName")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
@@ -265,14 +253,8 @@ public class EntityResource {
     public Response updateByUniqueAttribute(@QueryParam("type") String entityType,
                                             @QueryParam("property") String attribute,
                                             @QueryParam("value") String value, @Context HttpServletRequest request) {
-
         String entityJson = null;
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.updateByUniqueAttribute()");
-            }
-
             entityJson = Servlets.getRequestPayload(request);
 
             LOG.info("Partially updating entity by unique attribute {} {} {} {} ", entityType, attribute, value, entityJson);
@@ -301,8 +283,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to partially update entity {} {} " + entityType + ":" + attribute + "." + value, entityJson, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -321,22 +301,14 @@ public class EntityResource {
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response updateEntityByGuid(@PathParam("guid") String guid, @QueryParam("property") String attribute,
                                        @Context HttpServletRequest request) {
-        AtlasPerfTracer perf = null;
-        try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.updateEntityByGuid()");
-            }
-
-            if (StringUtils.isEmpty(attribute)) {
-                return updateEntityPartialByGuid(guid, request);
-            } else {
-                return updateEntityAttributeByGuid(guid, attribute, request);
-            }
-        } finally {
-            AtlasPerfTracer.log(perf);
+        if (StringUtils.isEmpty(attribute)) {
+            return updateEntityPartialByGuid(guid, request);
+        } else {
+            return updateEntityAttributeByGuid(guid, attribute, request);
         }
     }
-    
+
+    @Monitored
     private Response updateEntityPartialByGuid(String guid, HttpServletRequest request) {
         String entityJson = null;
         try {
@@ -374,6 +346,7 @@ public class EntityResource {
      * @postbody property's value
      * @return response payload as json
      */
+    @Monitored
     private Response updateEntityAttributeByGuid(String guid, String property, HttpServletRequest request) {
         String value = null;
         try {
@@ -411,19 +384,14 @@ public class EntityResource {
      * @param value the unique attribute value used to identify the entity
      * @return response payload as json - including guids of entities(including composite references from that entity) that were deleted
      */
+    @Monitored
     @DELETE
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response deleteEntities(@QueryParam("guid") List<String> guids,
         @QueryParam("type") String entityType,
         @QueryParam("property") String attribute,
         @QueryParam("value") String value) {
-
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.deleteEntities()");
-            }
-
             AtlasClient.EntityResult entityResult;
             if (guids != null && !guids.isEmpty()) {
                 LOG.info("Deleting entities {}", guids);
@@ -448,8 +416,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to delete entities {} {} {} {} ", guids, entityType, attribute, value, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -458,16 +424,12 @@ public class EntityResource {
      *
      * @param guid GUID for the entity
      */
+    @Monitored
     @GET
     @Path("{guid}")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getEntityDefinition(@PathParam("guid") String guid) {
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getEntityDefinition()");
-            }
-
             LOG.debug("Fetching entity definition for guid={} ", guid);
             guid = ParamChecker.notEmpty(guid, "guid cannot be null");
             final String entityDefinition = metadataService.getEntityDefinitionJson(guid);
@@ -495,8 +457,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to get instance definition for GUID {}", guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -505,6 +465,7 @@ public class EntityResource {
      *
      * @param entityType name of a type which is unique
      */
+    @Monitored
     public Response getEntityListByType(String entityType) {
         try {
             Preconditions.checkNotNull(entityType, "Entity type cannot be null");
@@ -537,21 +498,12 @@ public class EntityResource {
     public Response getEntity(@QueryParam("type") String entityType,
                               @QueryParam("property") String attribute,
                               @QueryParam("value") String value) {
-        AtlasPerfTracer perf = null;
-        try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getEntity(" + entityType + ", " + attribute + ", " + value + ")");
-            }
-
-            if (StringUtils.isEmpty(attribute)) {
-                //List API
-                return getEntityListByType(entityType);
-            } else {
-                //Get entity by unique attribute
-                return getEntityDefinitionByAttribute(entityType, attribute, value);
-            }
-        } finally {
-            AtlasPerfTracer.log(perf);
+        if (StringUtils.isEmpty(attribute)) {
+            //List API
+            return getEntityListByType(entityType);
+        } else {
+            //Get entity by unique attribute
+            return getEntityDefinitionByAttribute(entityType, attribute, value);
         }
     }
 
@@ -562,6 +514,7 @@ public class EntityResource {
      * @param attribute
      * @param value
      */
+    @Monitored
     public Response getEntityDefinitionByAttribute(String entityType, String attribute, String value) {
         try {
             LOG.debug("Fetching entity definition for type={}, qualified name={}", entityType, value);
@@ -606,16 +559,12 @@ public class EntityResource {
      * @param guid globally unique identifier for the entity
      * @return a list of trait names for the given entity guid
      */
+    @Monitored
     @GET
     @Path("{guid}/traits")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getTraitNames(@PathParam("guid") String guid) {
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getTraitNames(" + guid + ")");
-            }
-
             LOG.debug("Fetching trait names for entity={}", guid);
             final List<String> traitNames = metadataService.getTraitNames(guid);
 
@@ -634,8 +583,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to get trait names for entity {}", guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -643,15 +590,12 @@ public class EntityResource {
      * Fetches the trait definitions of all the traits associated to the given entity
      * @param guid globally unique identifier for the entity
      */
+    @Monitored
     @GET
     @Path("{guid}/traitDefinitions")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getTraitDefinitionsForEntity(@PathParam("guid") String guid){
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getTraitDefinitionsForEntity(" + guid + ")");
-            }
             LOG.debug("Fetching all trait definitions for entity={}", guid);
             final String entityDefinition = metadataService.getEntityDefinitionJson(guid);
 
@@ -677,10 +621,7 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to get trait definitions for entity {}", guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
-
     }
 
     /**
@@ -689,15 +630,12 @@ public class EntityResource {
      * @param guid globally unique identifier for the entity
      * @param traitName name of the trait
      */
+    @Monitored
     @GET
     @Path("{guid}/traitDefinitions/{traitName}")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response getTraitDefinitionForEntity(@PathParam("guid") String guid, @PathParam("traitName") String traitName){
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getTraitDefinitionForEntity(" + guid + ", " + traitName + ")");
-            }
             LOG.debug("Fetching trait definition for entity {} and trait name {}", guid, traitName);
             final IStruct traitDefinition = metadataService.getTraitDefinition(guid, traitName);
 
@@ -716,8 +654,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to get trait definition for entity {} and trait {}", guid, traitName, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -726,18 +662,14 @@ public class EntityResource {
      *
      * @param guid globally unique identifier for the entity
      */
+    @Monitored
     @POST
     @Path("{guid}/traits")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public Response addTrait(@Context HttpServletRequest request, @PathParam("guid") final String guid) {
         String traitDefinition = null;
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.addTrait(" + guid + ")");
-            }
-
             traitDefinition = Servlets.getRequestPayload(request);
             LOG.info("Adding trait={} for entity={} ", traitDefinition, guid);
             metadataService.addTrait(guid, traitDefinition);
@@ -759,8 +691,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to add trait for entity={} traitDef={}", guid, traitDefinition, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -770,6 +700,7 @@ public class EntityResource {
      * @param guid      globally unique identifier for the entity
      * @param traitName name of the trait
      */
+    @Monitored
     @DELETE
     @Path("{guid}/traits/{traitName}")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
@@ -777,12 +708,7 @@ public class EntityResource {
     public Response deleteTrait(@Context HttpServletRequest request, @PathParam("guid") String guid,
             @PathParam(TRAIT_NAME) String traitName) {
         LOG.info("Deleting trait={} from entity={} ", traitName, guid);
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.deleteTrait(" + guid + ", " + traitName + ")");
-            }
-
             metadataService.deleteTrait(guid, traitName);
 
             JSONObject response = new JSONObject();
@@ -802,8 +728,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to delete trait name={} for entity={}", traitName, guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -817,6 +741,7 @@ public class EntityResource {
      * @param count number of events required
      * @return
      */
+    @Monitored
     @GET
     @Path("{guid}/audit")
     @Produces(Servlets.JSON_MEDIA_TYPE)
@@ -824,12 +749,7 @@ public class EntityResource {
                                    @QueryParam("count") @DefaultValue("100") short count) {
         LOG.debug("Audit events request for entity {}, start key {}, number of results required {}", guid, startKey,
                 count);
-        AtlasPerfTracer perf = null;
         try {
-            if(AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getAuditEvents(" + guid + ", " + startKey + ", " + count + ")");
-            }
-
             List<EntityAuditEvent> events = metadataService.getAuditEvents(guid, startKey, count);
 
             JSONObject response = new JSONObject();
@@ -842,8 +762,6 @@ public class EntityResource {
         } catch (Throwable e) {
             LOG.error("Unable to get audit events for entity guid={} startKey={}", guid, startKey, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1fa05264/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java
index 811c486..983bbb8 100644
--- a/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java
@@ -19,6 +19,7 @@
 package org.apache.atlas.web.resources;
 
 import org.apache.atlas.AtlasClient;
+import org.apache.atlas.aspect.Monitored;
 import org.apache.atlas.discovery.DiscoveryException;
 import org.apache.atlas.discovery.LineageService;
 import org.apache.atlas.typesystem.exception.EntityNotFoundException;
@@ -63,6 +64,7 @@ public class LineageResource {
      * @param guid dataset entity id
      * @return
      */
+    @Monitored
     @GET
     @Path("{guid}/inputs/graph")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
@@ -70,12 +72,7 @@ public class LineageResource {
     public Response inputsGraph(@PathParam("guid") String guid) {
         LOG.info("Fetching lineage inputs graph for guid={}", guid);
 
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "LineageResource.inputsGraph(" + guid + ")");
-            }
-
             final String jsonResult = lineageService.getInputsGraphForEntity(guid);
 
             JSONObject response = new JSONObject();
@@ -92,8 +89,6 @@ public class LineageResource {
         } catch (Throwable e) {
             LOG.error("Unable to get lineage inputs graph for entity guid={}", guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -102,6 +97,7 @@ public class LineageResource {
      *
      * @param guid dataset entity id
      */
+    @Monitored
     @GET
     @Path("{guid}/outputs/graph")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
@@ -109,12 +105,7 @@ public class LineageResource {
     public Response outputsGraph(@PathParam("guid") String guid) {
         LOG.info("Fetching lineage outputs graph for entity guid={}", guid);
 
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "LineageResource.outputsGraph(" + guid + ")");
-            }
-
             final String jsonResult = lineageService.getOutputsGraphForEntity(guid);
 
             JSONObject response = new JSONObject();
@@ -131,8 +122,6 @@ public class LineageResource {
         } catch (Throwable e) {
             LOG.error("Unable to get lineage outputs graph for entity guid={}", guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 
@@ -141,6 +130,7 @@ public class LineageResource {
      *
      * @param guid dataset entity id
      */
+    @Monitored
     @GET
     @Path("{guid}/schema")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
@@ -148,12 +138,7 @@ public class LineageResource {
     public Response schema(@PathParam("guid") String guid) {
         LOG.info("Fetching schema for entity guid={}", guid);
 
-        AtlasPerfTracer perf = null;
         try {
-            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
-                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "LineageResource.schema(" + guid + ")");
-            }
-
             final String jsonResult = lineageService.getSchemaForEntity(guid);
 
             JSONObject response = new JSONObject();
@@ -173,8 +158,6 @@ public class LineageResource {
         } catch (Throwable e) {
             LOG.error("Unable to get schema for entity={}", guid, e);
             throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        } finally {
-            AtlasPerfTracer.log(perf);
         }
     }
 }