DEV Community

Eduardo Issao Ito
Eduardo Issao Ito

Posted on • Edited on

Java Simon with Spring Boot 2

Java Simon is a simple monitoring API that allows you to follow and better understand your application.

Here I'll show some tips about how to use it with Spring Boot 2.

Add Java Simon dependencies in pom.xml

        <dependency>
            <groupId>org.javasimon</groupId>
            <artifactId>javasimon-spring</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.javasimon</groupId>
            <artifactId>javasimon-jdbc41</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.javasimon</groupId>
            <artifactId>javasimon-console-embed</artifactId>
            <version>4.2.0</version>
        </dependency>

Spring configuration

You can add configuration for Java Simon monitoring of JDBC and Spring Beans, publish the web console and export simons by JMX.

JDBC monitoring

import org.javasimon.jdbcx4.WrappingSimonDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;

@Configuration
@ConditionalOnProperty("javasimon.jdbc.enabled")
public class SimonJdbcConfiguration {

    private final Environment env;

    @Autowired
    public SimonJdbcConfiguration(Environment env) {
        this.env = env;
    }

    @Primary
    @Bean
    public WrappingSimonDataSource primaryDataSource(DataSourceProperties properties) {
        DataSource dataSource = properties.initializeDataSourceBuilder().build();
        Binder binder = Binder.get(env);
        binder.bind("spring.datasource.hikari", Bindable.ofInstance(dataSource).withExistingValue(dataSource));

        WrappingSimonDataSource wrapper = new WrappingSimonDataSource();
        wrapper.setDataSource(dataSource);
        wrapper.setPrefix(env.getProperty("javasimon.jdbc.prefix", "jdbc"));
        return wrapper;
    }

}

(If you know a better way to decorate the data source in Spring Boot without depending on Hikari, let me know!)

Spring monitoring

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ConditionalOnProperty("javasimon.spring.enabled")
@ImportResource("classpath:javasimon-spring.xml")
public class SimonSpringConfiguration {
}

Add javasimon-spring.xml to your classpath:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="javasimonInterceptor" class="org.javasimon.spring.MonitoringInterceptor"/>

    <aop:config>
        <aop:pointcut id="monitoringPointcut" expression="execution(* *ServiceImpl(..))"/>
        <aop:advisor pointcut-ref="monitoringPointcut" advice-ref="javasimonInterceptor"/>
    </aop:config>

</beans>

More about Spring AOP and Java Simon:
https://github.com/virgo47/javasimon/blob/master/spring/doc/monitoring.xml

Web console

import org.javasimon.console.SimonConsoleFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
@ConditionalOnProperty("javasimon.console.enabled")
public class SimonConsoleConfiguration {

    private final Environment env;

    @Autowired
    public SimonConsoleConfiguration(Environment env) {
        this.env = env;
    }

    @Bean
    public FilterRegistrationBean<SimonConsoleFilter> simonFilter() {
        FilterRegistrationBean<SimonConsoleFilter> registrationBean = new FilterRegistrationBean<>();

        String urlPrefix = env.getProperty("javasimon.console.prefix", "simon");

        registrationBean.setFilter(new SimonConsoleFilter());
        registrationBean.setName("simon-console-filter");
        registrationBean.addUrlPatterns("/" + urlPrefix + "/*");
        registrationBean.addInitParameter("url-prefix", "/" + urlPrefix);

        return registrationBean;
    }

}

JMX reporting

You can see simon information in any JMX tool like jconsole.

import org.javasimon.jmx.JmxReporter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Configuration
@ConditionalOnProperty("javasimon.jmx.enabled")
public class SimonJmxConfigurer {

    private JmxReporter reporter;

    @PostConstruct
    public void start() {
        reporter = JmxReporter.forDefaultManager().registerSimons().registerExistingSimons().start();
    }

    @PreDestroy
    public void stop() {
        reporter.stop();
    }

}

The application.properties

All this stuff can be enabled/disabled in the application.properties file. If the property is absent, the feature will be disabled by default.

javasimon.jdbc.enabled=true
javasimon.spring.enabled=true
javasimon.console.enabled=true
javasimon.jmx.enabled=true

The url of the web console defaults to "simon" and the name prefix of the jdbc simons is "jdbc". This can be changed by the properties below:

javasimon.jdbc.prefix=jdbc
javasimon.console.prefix=simon

Top comments (0)