APM Java Tracer

Documentation



Architecture

The tool is implemented as an Java agent and therefore it can be started with or connected on runtime with the application. During execution the agent collects and sends the encrypted data via REST api to a second system which holds the data. It provides a GUI to explore and visualize those for the developer.

The agent itself is implemented in Java 8.

Get started

There are several easy steps to start:

Start Explorer with
java -jar explorer-1.0-SNAPSHOT.jar.

Start your application with the tracer agent
java -javaagent:agent-1.0-SNAPSHOT.jar -jar my-application-to-observe.jar.

If you want to attach an agent with a running application use the agentloader. This runs via figuring out current pid of your running application using jps command :

$ jps
1234 my-application-to-observe.jar
23456 jps
        

Start the agentloader and provide agant and pid, here 1234:
java -jar agentloader-1.0-SNAPSHOT.jar agent-1.0-SNAPSHOT.jar 1234

Minimal configuration file

The only configuration option which must be defined is the web consumer to let agent know tho whom the data should be sent.
Furthermore we suggest to set the application name. The minimum configuration file looks like this:

consumer:
connectionUri: http://localhost:8080
        

Configuration options explained

Create a YAML file named 'configuration.yml'.

version
version number format of configuration file, currently 1.0

applicationName
Set applications name, needed by Explorer to distinguish between different applications.

instrumentationType
Choose agent's functionality:


Logging

loggerLevel
Valid values are OFF, DEBUG, INFO, WARN, ERROR. Default is ERROR.

adapter
Can be a list of adapters where we want to log to. Valid values are CONSOLE, FILE. Default is CONSOLE

fileName
If one adapter is of type FILE it represents the file name where it is logged to. Default is 'agent.log'


Instrumentation

All classes and methods with any access level are considered by agent.
Standard JDK packages are currently turned off for performance reasons: "java", "javax", "com.sun", "sun", "jdk".
When you need this please approach us.

This configuration part contains a list called configurations with following packageFormat
Naming of package. Can contain a "*" which stands for a variable package name or "**" at the end which stands for a variable package depth.

classFormat
Naming of a class, can contain multiple "*".

methodFormat
Naming of a method, can contain multiple "*".

statics
Also consider static methods.


Behavior

preserveHistory
Usually only on errors the call trace is kept. With this option the whole trace will be send to explorer. Default is false.
Be aware that transmitting complete in depth object states binds a lot of resources.

Next 3 values define detail level for object representation:

objectStateDetailLevel
Current object detail level.

parameterDetailLevel
Method and constructor parameter detail level.

resultDetailLevel
Returned object detail level.


Consumer

Defines a consumer which receives the collected data. The consumer is a REST endpoint which communicating over HTTP(s) receives the data via POST request. This is usually the bundled 'Explorer' which provides such an endpoint.
Basic authentication is provided.

The agent uses generated key in license to send payload encrypted to explorer if *type* is either EXPLORER (default), EXPLORER_NONENCRYPTED.
You can deactivate payload encryption by configuring *type* EXPLORER_NONENCRYPTED and using the explorer without *noencryption* profile. In this case explorer also does not need license in same directory.
connectionUri (required)
The URI where to send the data via POST.

userLicense
Used to create basic auth header in combination with 'password' Can be a list of adapters where we want to log to. Valid values are CONSOLE, FILE. Default is CONSOLE

password
The password used in combination with 'userLicense'.

headers
List of header directives send with the POST request.

type
Defines how the data er being sent. Valid values are EXPLORER (default), EXPLORER_NONENCRYPTED, ELASTIC_SEARCH (currently not supported), MONGO_DB (currently not supported), FILE_SYSTEM.

EXPLORER: payload is encrypted, content type is json and header is set.
connectionUri: https://localhost:8080/api/v1

EXPLORER_NONENCRYPTED: payload is not encrypted, content type is json and header is set.
connectionUri: https://localhost:8080/api/v1

ELASTIC_SEARCH: payload is created in ndjson format and content type header is set. Request is designed for bulk requests.
connectionUri: https://localhost:9200/{index}/_bulk

MONGO_DB: content type is json and header is set. Atlas API must be used to perform POST requests.
connectionUri: https://localhost:27017/app/{Mongo DB API key}/endpoint/data/beta/action/insertMany

An additional config strucure must be defined as follows to reformat payload matching Mongo DB's API requirements:
consumer:
    connectionUri: https://localhost:27017/app/{Mongo DB API key}/endpoint/data/beta/action/insertMany
    type: MONGO_DB
    mongoDb:
        dataSource: "i.e. cluster id"
        database: "database name"
        collection: "collection name"
        apiKey: "Mongo DB API key"
                
FILE_SYSTEM: only connectionUri is used to specifile file to write into in 'append' mode.
If one adapter is of type FILE it represents the file name where it is logged to. Default is 'agent.log'


Condition (currently not supported)

dateTime
Stops if a date and time specified in a sub configuration dateTime is reached. The format is YYYY-mm-dd hh:ss.

stopWatchTimeInSeconds
Stops after a specified time in seconds defined in a sub configuration timeInSeconds is reached.

method
Stops if a method signature specified in this section was called a certain amount whereby:

exception
Stops if an exception signature specified in this section was thrown a certain amount whereby:

Full example configuration

Here is an example configuration file with all default options as explained above. The instrumentation, consumer and condition are filled with an example but are empty by default.
The consumer must be defined according to the type with at least connectionUri for EXPLORER, ELASTIC_SEARCH and FILE

version: 1.0

applicationName: ""

instrumentationType: DEBUG

logging:
  loggerLevel: ERROR
  adapter:
  - CONSOLE
  fileName: agent.log

instrumentation:
  configurations:
    - packageFormat: com.example.*.app.**
      classFormat: My*Class
      methodFormat: method*
      statics: false

behavior:
  preserveHistory: false
  objectStateDetailLevel: NONE
  parameterDetailLevel: INDICATION
  resultDetailLevel: INDICATION

consumer:
  connectionUri: http://localhost:8080
  userLicense: userLicense
  password: password
  headers:
    - "X-Forwarded-For: 127.0.0.1"
  type = EXPLORER;

condition:
  exitOnCondition: true
  dateTime: "2022-12-24 18:00"
  stopWatchTimeInSeconds: 5
  method:
      occurrences: 10
      packageRegex: (com|de)\\.example\\.app
      methodRegex: ^create
      parameterCount: 1
      resultRegex: Class$
  exception:
    occurrences: 10
    packageRegex: (com|de)\\.example\\.app
    messageRegex: ^Error during
        

FAQ

Q: Are other JVM languages than Java supported?
A: We only tested Java.

Q: Does the Explorer persist the received data?
A: Currently not. When you exit the Explorer the date are lost. If you need persistence let us know.

Q: Will there be support for Java 18?
A: Yes!

Q: Is it planned to have a special support for Spring Boot?
A: We are on it!

Q: Is it planned adding support finding unused classes, uncalled methods or non thrown exceptions more easily?
A: We are on it!

Q: Is it planned giving an overview about the time used by methods like in NewRelic?
A: Yes!