Tigris Framework
=========

Tigris is a two-phase framework for filtering and sampling execution traces at runtime. It can be used within a feedback loop to effectively monitor a managed software system and provide information for different purposes, e.g. to identify security vulnerabilities, model inconsistencies or performance bugs and, eventually, adapt the system. Tigris includes a domain-specific language (DSL) that allows users to express the goal of monitoring in the form of high-level relevance criteria. At runtime, Tigris automatically instruments the monitored system according to the specified relevance criteria. In its first phase, the framework performs a lightweight and coarse-grained monitoring to collect the metrics needed to guide an in-depth monitoring. Software metrics and relevance criteria are derived from a systematic literature review. The framework identifies relevant parts of the software based on the information collected in the first phase and then, in the second phase, collects traces at a fine-grained level.

Features
------------
- Declarative configuration
- Enable and disable features by configurations or at runtime
- Relevance evaluation of executions
- Automatic monitoring of relevant executions

Tigris is implemented in Java and thus can be instantiated and integrated into monitoring-based approaches to leverage the monitoring results of Java-based approaches and applications.

Required Tools
--------------
- AOP-enabled compilation
- Maven 3
- Java 8

Build and Dependency
--------------------

Checkout the repository, go to the framework folder and build the `pom.xml` with Maven: `mvn clean install`

If your project is maven-based, in your `pom.xml`:
```xml
<dependencies>
    <dependency>
        <groupId>br.ufrgs.inf.prosoft</groupId>
        <artifactId>tigris</artifactId>
        <version>0.10.0-SNAPSHOT</version>
    </dependency>
</dependencies>
```

As Tigris is fully based on AOP, it is necessary to add it to your compiling configuration as well: 

```xml
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.7</version>
    <configuration>
        <showWeaveInfo>false</showWeaveInfo>
        <complianceLevel>1.8</complianceLevel>
        <source>1.8</source>
        <target>1.8</target>
        <Xlint>ignore</Xlint>
        <encoding>UTF-8</encoding>
        <verbose>false</verbose>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>br.ufrgs.inf.prosoft</groupId>
                <artifactId>tigris</artifactId>
            </aspectLibrary>
        </aspectLibraries>
    </configuration>
    <executions>
        <execution>
            <phase>process-sources</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>
</plugin>
```

If not using maven, the `.jar` produced by maven can be just added to the classpath of your project.

Usage
-----

### Application example

In order to have a practical reference, consider the project [`app-example`](./app-example). It should be found along with the source of the framework.

An example of such configuration is shown as follows. Create a configuration class which consists of `@TigrisConfiguration`, `@TigrisCriteria` and `@ComponentScan` annotations, on the root package of the system:

```
@TigrisConfiguration(
    logRepository = RepositoryType.MEMORY,
    staticMetricFile = "petclinic.csv",
    samplingPercentage = 0.5)
@TigrisCriteria(
    criteria = "more frequent '∪' more expensive '∪' least changeable",
    granularity = GranularityType.METHOD,
    frequencyMetric = Metrics.INVOCATION_FREQUENCY,
    expensivenessMetric = Metrics.EXECUTION_TIME,
    changeabilityMetric = Metrics.COMPUTATION_PATTERN
)
@ComponentScan(allowed = "org.springframework.samples.petclinic.*",
        denied = "org.springframework.samples.petclinic.model.*")
public class ApplicationInitializer { }
```

Inner workings
--------------

To collect data during the coarse-grained and fine-grained monitoring phases, we intercept method executions with [AspectJ](https://eclipse.org/aspectj/), which allows Tigris to acquire lightweight and dynamic software metrics without changing the base code. Tigris also supports loading output metrics from [Understand](https://scitools.com/), to evaluate criteria that are based on static metrics. Metrics available in the framework are the most frequently used metrics in the literature, which are listed in table below.

| Metric | Description | Estimation |
|--------|-------------|------------|
| Concurrency Level | the number of times a method is executed concurrently | mean number of active threads during all calls of the method |
| Computation Pattern | the number of times that each pair of input and output of method occurs | standard deviation of the return size of all calls of a method  |
| Energy Consumption | the amount of energy demanded by a method | mean estimate of energy consumption of all calls of the method |        
| Error level | the number of times the execution of a method thrown exceptions | absolute number of exceptions raised by all calls of the method |
| Execution Time | the time taken to execute a method | mean execution time of all calls of the method |        
| Inter-Arrival Time | the time taken between executions of a method | mean time between each call of a method and the next |
| Invocation Frequency | the number of times a method occurs | absolute number of calls of a method |
| Memory Consumption | the amount of memory demanded by a method | mean estimate memory consumption of all calls of the method |
| User Behavior | the number of times a method is shared among different users | absolute number of user sessions that lead to calls of a method |

Tigris was designed to be extensible and flexible. New criteria and metrics can be included by extending and implementing interfaces provided by the framework. The same interfaces are used to customize and define how metrics should be calculated. It is also possible to configure the framework so that relevance criteria and metrics can change at runtime, and thus achieve increased adaptation levels. In addition to the usage of TigrisDSL filters to identify relevant event executions based on the goal of monitoring, Tigris also offers customizations. For example, it is possible to set up the framework to focus on specific monitoring locations, which can improve the set of events to be evaluated as relevant as well as exclude events that must not be monitored, thus reducing the time overhead for tracking them.


Contributing
--------------

Before building the project it is necessary to install the external jar dependencies:

```
mvn install:install-file -Dfile=lib\bullwinkle.jar -DgroupId=ca.uqac.lif -DartifactId=bullwinkle -Dversion=1.4.5 -Dpackaging=jar
```