eXo Platform 3.5

## Chapter 38. eXo JCR statistics

## Statistics on the Database Access Layer

In order to have a better idea of the time spent into the database access layer, it can be interesting to get some statistics on that part of the code, knowing that most of the time spent into eXo JCR is mainly the database access. This statistics will then allow you to identify without using any profiler what is normally slow in this layer, which could help to fix the problem quickly.

In case you use `org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer` or `org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer` as `WorkspaceDataContainer`, you can get statistics on the time spent into the database access layer. The database access layer (in eXo JCR) is represented by the methods of the interface `org.exoplatform.services.jcr.storage.WorkspaceStorageConnection`, so for all the methods defined in this interface, we can have the following figures:

- The minimum time spent into the method.

- The maximum time spent into the method.

- The average time spent into the method.

- The total amount of time spent into the method.

- The total amount of time the method has been called.

Those figures are also available globaly for all the methods which gives us the global behavior of this layer.

If you want to enable the statistics, you just need to set the JVM parameter called JDBCWorkspaceDataContainer.statistics.enabled to true. The corresponding CSV file is StatisticsJDBCStorageConnection-${creation-timestamp}.csv for more details about how the csv files are managed, please refer to the section dedicated to the statistics manager.

The format of each column header is ${method-alias}-${metric-alias}. The metric alias are described in the statistics manager section.

The name of the category of statistics corresponding to these statistics is JDBCStorageConnection, this name is mostly needed to access to the statistics through JMX.

global | This is the alias for all the methods.
getItemDataById | This is the alias for the method getItemData(String identifier).
getItemDataByNodeDataNQPathEntry | This is the alias for the method getItemData(NodeData parentData, QPathEntry name).
getChildNodesData | This is the alias for the method getChildNodesData(NodeData parent).
getChildNodesCount | This is the alias for the method getChildNodesCount(NodeData parent).
getChildPropertiesData | This is the alias for the method getChildPropertiesData(NodeData parent).
listChildPropertiesData | This is the alias for the method listChildPropertiesData(NodeData parent).
getReferencesData | This is the alias for the method getReferencesData(String nodeIdentifier).
commit | This is the alias for the method commit().
addNodeData | This is the alias for the method add(NodeData data).
addPropertyData | This is the alias for the method add(PropertyData data).
updateNodeData | This is the alias for the method update(NodeData data).
updatePropertyData | This is the alias for the method update(PropertyData data).
deleteNodeData | This is the alias for the method delete(NodeData data).
deletePropertyData | This is the alias for the method delete(PropertyData data).
renameNodeData | This is the alias for the method rename(NodeData data).
rollback | This is the alias for the method rollback().
isOpened | This is the alias for the method isOpened().
close | This is the alias for the method close().

## Statistics on the JCR API accesses

In order to know exactly how your application uses eXo JCR, it can be interesting to register all the JCR API accesses in order to easily create real life test scenario based on pure JCR calls and also to tune your eXo JCR to better fit your requirements.

In order to allow you to specify the configuration which part of eXo JCR needs to be monitored whithout applying any changes in your code and/or building anything, we choose to rely on the Load-time Weaving proposed by AspectJ.

To enable this feature, you will have to add in your classpath the following jar files:

- exo.jcr.component.statistics-X.Y.Z.jar corresponding to your eXo JCR version that you can get from the jboss maven repository https://repository.jboss.org/nexus/content/groups/public/org/exoplatform/jcr/exo.jcr.component.statistics.

- aspectjrt-1.6.8.jar that you can get from the main maven repository `http://repo2.maven.org/maven2/org/aspectj/aspectjrt`.

You will also need to get aspectjweaver-1.6.8.jar from the main maven repository http://repo2.maven.org/maven2/org/aspectj/aspectjweaver. At this stage, to enable the statistics on the JCR API accesses, you will need to add the JVM parameter -javaagent:${pathto}/aspectjweaver-1.6.8.jar to your command line, for more details please refer to http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html.

By default, the configuration will collect statistcs on all the methods of the internal interfaces org.exoplatform.services.jcr.core.ExtendedSession and org.exoplatform.services.jcr.core.ExtendedNode, and the JCR API interface javax.jcr.Property. To add and/or remove some interfaces to monitor, you have two configuration files to change that are bundled into the jar exo.jcr.component.statistics-X.Y.Z.jar, which are conf/configuration.xml and META-INF/aop.xml.

The file content below is the content of conf/configuration.xml that you will need to modify to add and/or remove the full qualified name of the interfaces to monitor, into the list of parameter values of the init param called targetInterfaces.

    <configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplatform.org/xml/ns/kernel_1_2.xsd http://www.exoplatform.org/xml/ns/kernel_1_2.xsd"

     xmlns="http://www.exoplatform.org/xml/ns/kernel_1_2.xsd">

     <component>

       <type>org.exoplatform.services.jcr.statistics.JCRAPIAspectConfig</type>

       <init-params>

         <values-param>

           <name>targetInterfaces</name>

           <value>org.exoplatform.services.jcr.core.ExtendedSession</value>

           <value>org.exoplatform.services.jcr.core.ExtendedNode</value>

           <value>javax.jcr.Property</value>

         </values-param>

       </init-params>

      </component>

    </configuration>

The file content below is the content of META-INF/aop.xml that you will to need to modify to add and/or remove the full qualified name of the interfaces to monitor, into the expression filter of the pointcut called JCRAPIPointcut. As you can see below, by default only JCR API calls from the exoplatform packages are took into account, don't hesistate to modify this filter to add your own package names.

    <aspectj>

      <aspects>

        <concrete-aspect name="org.exoplatform.services.jcr.statistics.JCRAPIAspectImpl" extends="org.exoplatform.services.jcr.statistics.JCRAPIAspect">

          <pointcut name="JCRAPIPointcut"

            expression="(target(org.exoplatform.services.jcr.core.ExtendedSession) || target(org.exoplatform.services.jcr.core.ExtendedNode) || target(javax.jcr.Property)) &amp;&amp; call(public * *(..))" />

        </concrete-aspect>

      </aspects>

      <weaver options="-XnoInline">

        <include within="org.exoplatform..*" />

      </weaver>

    </aspectj>

The corresponding CSV files are of type Statistics${interface-name}-${creation-timestamp}.csv for more details about how the csv files are managed, please refer to the section dedicated to the statistics manager.

The format of each column header is ${method-alias}-${metric-alias}. The method alias will be of type ${method-name}(list of parameter types separeted by ; to be compatible with the CSV format).

The metric alias are described in the statistics manager section.

The name of the category of statistics corresponding to these statistics is the simple name of the monitored interface (e.g. ExtendedSession for org.exoplatform.services.jcr.core.ExtendedSession), this name is mostly needed to access to the statistics through JMX.

Please note that this feature will affect the performances of eXo JCR so it must be used with caution.

## Statistics Manager

The statistics manager manages all the statistics provided by eXo JCR, it is responsible of printing the data into the CSV files and also exposing the statistics through JMX and/or Rest.

The statistics manager will create all the CSV files for each category of statistics that it manages, the format of those files is Statistics${category-name}-${creation-timestamp}.csv. Those files will be created into the user directory if it is possible otherwise it will create them into the temporary directory. The format of those files is `CSV` (i.e. Comma-Seperated Values), one new line will be added regularily (every 5 seconds by default) and one last line will be added at JVM exit. Each line, will be composed of the 5 figures described below for each method and globaly for all the methods.

Min | The minimum time spent into the method expressed in milliseconds.
Max | The maximum time spent into the method expressed in milliseconds.
Total | The total amount of time spent into the method expressed in milliseconds.
Avg | The average time spent into the method expressed in milliseconds.
Times | The total amount of times the method has been called.

You can disable the persistence of the statistics by setting the JVM parameter called JCRStatisticsManager.persistence.enabled to false, by default, it is set to true. You can aslo define the period of time between each record (i.e. line of data into the file) by setting the JVM parameter called JCRStatisticsManager.persistence.timeout to your expected value expressed in milliseconds, by default it is set to 5000.

You can also access to the statistics thanks to JMX, the available methods are the following:

getMin | Give the minimum time spent into the method corresponding to the given category name and statistics name. The expected arguments are the name of the category of statistics (e.g. JDBCStorageConnection) and the name of the expected method or global for the global value.
getMax | Give the maximum time spent into the method corresponding to the given category name and statistics name. The expected arguments are the name of the category of statistics (e.g. JDBCStorageConnection) and the name of the expected method or global for the global value.
getTotal | Give the total amount of time spent into the method corresponding to the given category name and statistics name. The expected arguments are the name of the category of statistics (e.g. JDBCStorageConnection) and the name of the expected method or global for the global value.
getAvg | Give the average time spent into the method corresponding to the given category name and statistics name. The expected arguments are the name of the category of statistics (e.g. JDBCStorageConnection) and the name of the expected method or global for the global value.
getTimes | Give the total amount of times the method has been called corresponding to the given ,category name and statistics name. The expected arguments are the name of the category of statistics (e.g. JDBCStorageConnection) and the name of the expected method or global for the global value.
reset | Reset the statistics for the given category name and statistics name. The expected arguments are the name of the category of statistics (e.g. JDBCStorageConnection) and the name of the expected method or global for the global value.
resetAll | Reset all the statistics for the given category name. The expected argument is the name of the category of statistics (e.g. JDBCStorageConnection).

The full name of the related MBean is exo:service=statistic, view=jcr.