Skip to main content

Application Performance Monitoring

Atoti APM (Application Performance Monitoring) is a solution for monitoring the healthiness and performance of an application. It provides several features easing the support work, and reducing the burden of maintaining and troubleshooting Atoti Server.

Configuration

Adding APM in an Atoti project

You can use the APM starter to setup APM in our project.

<dependency>
<groupId>com.activeviam.springboot</groupId>
<artifactId>atoti-server-apm-starter</artifactId>
<version>${project.version}</version>
</dependency>

Logging

APM relies on SLF4J with a Logback binding for the logging part.

Configuration

Logback supports custom conversion specifiers allowing to display specific information properly within the logs. APM defines three custom converter detailed below:

ConverterDescription
com.activeviam.apm.api.logging.LogUserConverterAllow to display the current user for the thread. The user is either taken from the security layer or from the health event
com.activeviam.apm.api.logging.LogThreadConverterAllow to display the current thread. This is useful for the health event. This converter can override the default Logback one
com.activeviam.apm.api.logging.LogInstanceConverterRequired only if ELK setup and JSON logs are used. This converter provides the node instance name specified in property node.instance.name so the source node of a log can be identified in a centralized logging system like ELK

Then, Logback configuration example can make use of these converters as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Example LOGBACK Configuration File http://logback.qos.ch/manual/configuration.html -->
<configuration>
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<jmxConfigurator/>
<!-- Exposing the conversion rules -->
<conversionRule conversionWord="thread"
converterClass="com.activeviam.apm.api.logging.LogThreadConverter"/>
<conversionRule conversionWord="user"
converterClass="com.activeviam.apm.api.logging.LogUserConverter"/>

<appender name="MAIN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${custom.log.dir}/${project.artifactId}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${custom.log.dir}/${project.artifactId}_%d{yyyy-MM-dd}.log.gz
</fileNamePattern>
<maxHistory>30</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>

<encoder>
<!-- Using the converter in the appender pattern layout -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [Thread: %thread; User: %user] %-5level %logger{35} -
%msg%n
</pattern>
</encoder>
</appender>
[...]
<root level="INFO">
<appender-ref ref="MAIN"/>
</root>
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
</configuration>

Loggers Categorization

APM loggers could be categorized as follows:

CategoryLogger(s)
Feedingcom.activeviam.apm.feeding
Feed loadingcom.activeviam.apm.loaded.feed
Used if you choose the feed.loading.message.handler.type option 'LOG'. In this case you more likely prefer the output to be made in a separate file
Queriescom.activeviam.apm.queries
Distributioncom.activeviam.apm.distribution
Servicescom.activeviam.apm.services
System Healthcom.activeviam.apm.health
Springcom.activeviam.apm.spring

Data loading

The MonitoredDataLoadingConfig class provides the bean messageHandler() which creates the implementation of the IMessageHandler. In your source Spring config class you could do the following:

...
@Autowired
private MonitoredDataLoadingConfig monitoredDataLoadingConfig;

@Bean
protected IMessageHandler<IFileInfo<Path>> messageHandler() {
return monitoredDataLoadingConfig.messageHandler();
}

@Bean(destroyMethod = "close")
public CustomCsvSource dataCsvSource() {
final CsvSource csvSource = new CsvSource(DATA_TAG);
...
return csvSource;
}

protected List<IStoreMessageChannel<IFileInfo<Path>, ILineReader>> dataCsvChannels(
final CsvMessageChannelFactory<Path> dataCsvChannelFactory,
final IMessageHandler<IFileInfo<Path>> messageHandler) {

final List<IStoreMessageChannel<IFileInfo<Path>, ILineReader>> channels = new ArrayList<>();
ITuplePublisher<IFileInfo<Path>> tuplePublisher = ...;
IStoreMessageChannel<IFileInfo<Path>, ILineReader> channel = dataCsvChannelFactory.createChannel(topicName,
storeName, tuplePublisher);
channel.withPublisher(tuplePublisher);
channel.withMessageHandler(messageHandler());
channels.add(channel);
}

Depending on the properties, the bean allows to:

  • log start/end processing of some input data, as well as the errors, through the logger com.activeviam.apm.source
  • log the rejections of the input data through the logger com.activeviam.apm.source.rejection
  • specify the property feed.loading.message.handler.type to select the type of the message handler: ** if set to DEFAULT, simply logs detailed information about loading file ** if set to LOG, logs the feed loading in an external file (CSV style) upon completion using the logger com.activeviam.apm.loaded.feed ** if set to WEBHOOK, call a webhook (external service) upon completion of the file loading

Properties exposed

List of the properties exposed as well as their default value

PropertyDescriptionDefault value
activeviam.apm.config.hide.properties.patternSpecifies the pattern used to hide sensitive properties when logged*(password|key).*
activeviam.apm.enable.all.apmanager.statisticsEnable the MBeans statistics for the ActivePivot managertrue
activeviam.apm.enable.xmla.servlet.loggingEnable the logging of the XMLA Servlettrue
activeviam.apm.enable.json.queries.service.loggingEnable the logging of the JSON Queries Servicetrue
activeviam.apm.enable.json.queries.service.detailed.loggingEnable the detailed logging of the JSON Queries Servicefalse
activeviam.apm.enable.json.queries.service.log.memory.statsEnable the logging of the memory stats for the JSON Queries Servicefalse
activeviam.apm.enable.queries.service.loggingEnable the logging of the Queries Servicetrue
activeviam.apm.enable.queries.service.detailed.loggingEnable the detailed logging of the Queries Servicefalse
activeviam.apm.enable.queries.service.log.memory.statsEnable the logging of the memory stats for the Queries Servicefalse
activeviam.apm.enable.streaming.service.loggingEnable the logging of the Streaming Servicetrue
activeviam.apm.enable.streaming.service.detailed.loggingEnable the detailed logging of the Streaming Servicefalse
activeviam.apm.enable.streaming.service.log.memory.statsEnable the logging of the memory stats for the Streaming Servicefalse
activeviam.apm.enable.web.socket.loggingEnable the logging of Web Sockettrue
activeviam.apm.enable.web.socket.detailed.loggingEnable the detailed logging of the Web Socketfalse
activeviam.apm.enable.web.socket.log.memory.statsEnable the logging of the memory stats for the Web Socketfalse
activeviam.apm.feed.loading.cache.loaded.files.num.entriesProperty defining the number of entries kept in the feed loading cache1,000,000
activeviam.apm.feed.loading.message.handler.typeProperty defining the feed loading message handler typeDEFAULT
activeviam.apm.feed.loading.message.handler.webhook.urlProperty defining the webhook URL for the feed loading message handler
activeviam.apm.feed.loading.message.handler.webhook.num.retriesProperty defining the number of retries for the webhook feed loading message handlerInteger.MAX_VALUE
activeviam.apm.feed.loading.message.handler.webhook.time.to.waitProperty defining the time to wait (ms) between each retry for the webhook feed loading message handler3000 (3s)
activeviam.apm.jmx.thread.status.cache.timeoutThread status cache value timeout in milliseconds. Thread status cache value is refreshed automatically when timeout.60000 (60s)
activeviam.apm.node.instance.nameUnique name of the current node. It must be provided if logging/monitoring stack (e.g. ELK) is used.activepivot
activeviam.apm.consul.hostHost or IP of the consul service
activeviam.apm.consul.portPort of the consul service8500
activeviam.apm.activepivot.service.nameService name of the instance. This is for service grouping and filtering in consulactivepivot
activeviam.apm.node.hostHost or IP of the node instance for registering to consulThe first non loop back host ip found in network interfaces
activeviam.apm.node.healthcheck.portPort which consul should call for healthcheck. This should be port used for jmx explorer, e.g. -javaagent:jmx_prometheus_javaagent-0.3.1.jar=80818081
activeviam.apm.node.healthcheck.pathPath which consul should call for healthcheckmetrics
activeviam.apm.node.healthcheck.intervalInterval between health check attempts5m
activeviam.apm.node.healthcheck.timeoutTimeout for a health check attempt30s
activeviam.apm.node.healthcheck.deregister.timeConsul will de-register the instance from the registry if it loses contact for more that a specific time30m
activeviam.apm.query.performance.evaluation.min.sample.sizeThe minimum amount of past performance required as samples for evaluation10
activeviam.apm.query.performance.evaluation.max.sample.sizeThe maximum amount of past performance taken into account for evaluation30
activeviam.apm.query.performance.evaluation.coefficientThe coefficient for adjusting the threshold1