Fixes to actuator metrics

- Quick fix to get something out from
  new boot 2.x metrics.
- Change source to java 8 compat
- Add new micrometer deps to build
- Docs and further changes will get done
  when new boot metric system completes.
- Fixes #410
This commit is contained in:
Janne Valkealahti
2017-09-15 16:01:44 +01:00
parent 5035a08e1b
commit 29303eb5f4
7 changed files with 78 additions and 43 deletions

View File

@@ -60,8 +60,8 @@ configure(allprojects) {
}
compileJava {
sourceCompatibility = 1.7
targetCompatibility = 1.7
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
compileTestJava {
@@ -195,6 +195,7 @@ project('spring-statemachine-boot') {
optional project(":spring-statemachine-data-common:spring-statemachine-data-jpa")
optional project(":spring-statemachine-data-common:spring-statemachine-data-redis")
optional project(":spring-statemachine-data-common:spring-statemachine-data-mongodb")
optional "io.micrometer:micrometer-core"
optional "org.eclipse.persistence:javax.persistence"
optional "org.springframework.boot:spring-boot-starter-data-jpa"
optional "org.springframework.boot:spring-boot-starter-data-redis"

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package org.springframework.statemachine.boot.autoconfigure;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.boot.actuate.metrics.GaugeService;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -28,6 +26,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.boot.StateMachineProperties;
import org.springframework.statemachine.boot.support.BootStateMachineMonitor;
import io.micrometer.core.instrument.MeterRegistry;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Statemachine.
*
@@ -39,25 +39,22 @@ import org.springframework.statemachine.boot.support.BootStateMachineMonitor;
public class StateMachineAutoConfiguration {
@Configuration
@ConditionalOnClass(CounterService.class)
@ConditionalOnClass(MeterRegistry.class)
@ConditionalOnProperty(prefix = "spring.statemachine.monitor", name = "enabled", havingValue = "true", matchIfMissing = true)
public static class StateMachineMonitoringConfiguration {
private final CounterService counterService;
private final GaugeService gaugeService;
private final MeterRegistry meterRegistry;
private final TraceRepository traceRepository;
public StateMachineMonitoringConfiguration(ObjectProvider<CounterService> counterServiceProvider,
ObjectProvider<GaugeService> gaugeServiceProvider,
public StateMachineMonitoringConfiguration(ObjectProvider<MeterRegistry> meterRegistryProvider,
ObjectProvider<TraceRepository> traceRepositoryProvider) {
this.counterService = counterServiceProvider.getIfAvailable();
this.gaugeService = gaugeServiceProvider.getIfAvailable();
this.meterRegistry = meterRegistryProvider.getIfAvailable();
this.traceRepository = traceRepositoryProvider.getIfAvailable();
}
@Bean
public BootStateMachineMonitor<?, ?> bootStateMachineMonitor() {
return new BootStateMachineMonitor<>(counterService, gaugeService, traceRepository);
return new BootStateMachineMonitor<>(meterRegistry, traceRepository);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,8 @@ package org.springframework.statemachine.boot.support;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.boot.actuate.metrics.GaugeService;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
@@ -29,6 +28,11 @@ import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
import org.springframework.util.ObjectUtils;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.stats.hist.Histogram;
/**
* Implementation of a {@link StateMachineMonitor} which converts monitoring
* events and bridges those into supported format handled by Spring Boot's
@@ -41,31 +45,24 @@ import org.springframework.util.ObjectUtils;
*/
public class BootStateMachineMonitor<S, E> extends AbstractStateMachineMonitor<S, E> {
private final String METRIC_TRANSITION_BASE = "ssm.transition";
private final String METRIC_ACTION_BASE = "ssm.action";
private final CounterService counterService;
private final GaugeService gaugeService;
private final TraceRepository traceRepository;
private final MeterRegistry meterRegistry;
/**
* Instantiates a new boot state machine monitor.
*
* @param counterService the counter service
* @param gaugeService the gauge service
* @param meterRegistry the meter registry
* @param traceRepository the trace repository
*/
public BootStateMachineMonitor(CounterService counterService, GaugeService gaugeService,
TraceRepository traceRepository) {
this.counterService = counterService;
this.gaugeService = gaugeService;
public BootStateMachineMonitor(MeterRegistry meterRegistry, TraceRepository traceRepository) {
this.meterRegistry = meterRegistry;
this.traceRepository = traceRepository;
}
@Override
public void transition(StateMachine<S, E> stateMachine, Transition<S, E> transition, long duration) {
String transitionName = transitionToName(transition);
this.counterService.increment(METRIC_TRANSITION_BASE + "." + transitionName + ".transit");
this.gaugeService.submit(METRIC_TRANSITION_BASE + "." + transitionName + ".duration", duration);
getTransitionCounterBuilder(transition).register(meterRegistry).increment();
getTransitionTimerBuilder(transition).register(meterRegistry).record(duration, TimeUnit.MILLISECONDS);
Map<String, Object> traceInfo = new HashMap<>();
traceInfo.put("transition", transitionToName(transition));
traceInfo.put("duration", duration);
@@ -76,8 +73,8 @@ public class BootStateMachineMonitor<S, E> extends AbstractStateMachineMonitor<S
@Override
public void action(StateMachine<S, E> stateMachine, Action<S, E> action, long duration) {
String actionName = actionToName(action);
this.counterService.increment(METRIC_ACTION_BASE + "." + actionName + ".execute");
this.gaugeService.submit(METRIC_ACTION_BASE + "." + actionName + ".duration", duration);
getActionCounterBuilder(action).register(meterRegistry).increment();
getActionTimerBuilder(action).register(meterRegistry).record(duration, TimeUnit.MILLISECONDS);
Map<String, Object> traceInfo = new HashMap<>();
traceInfo.put("action", actionName);
traceInfo.put("duration", duration);
@@ -85,6 +82,40 @@ public class BootStateMachineMonitor<S, E> extends AbstractStateMachineMonitor<S
traceRepository.add(traceInfo);
}
private Counter.Builder getTransitionCounterBuilder(Transition<S, E> transition) {
String transitionName = transitionToName(transition);
Counter.Builder builder = Counter.builder("ssm.transition.transit")
.tags("transitionName", transitionName)
.description("Counter of Transition");
return builder;
}
private Timer.Builder getTransitionTimerBuilder(Transition<S, E> transition) {
String transitionName = transitionToName(transition);
Timer.Builder builder = Timer.builder("ssm.transition.duration")
.tags("transitionName", transitionName)
.description("Timer of Transition");
builder.histogram(Histogram.percentilesTime());
return builder;
}
private Counter.Builder getActionCounterBuilder(Action<S, E> action) {
String actionName = actionToName(action);
Counter.Builder builder = Counter.builder("ssm.action.execute")
.tags("actionName", actionName)
.description("Counter of Action");
return builder;
}
private Timer.Builder getActionTimerBuilder(Action<S, E> action) {
String actionName = actionToName(action);
Timer.Builder builder = Timer.builder("ssm.action.duration")
.tags("actionName", actionName)
.description("Timer of Action");
builder.histogram(Histogram.percentilesTime());
return builder;
}
private static <S, E> String transitionToName(Transition<S, E> transition) {
String sourceId = nullStateId(transition.getSource());
String targetId = nullStateId(transition.getTarget());

View File

@@ -131,9 +131,9 @@ project('spring-statemachine-samples-monitoring') {
description = 'Spring State Machine Monitoring Sample'
dependencies {
compile project(":spring-statemachine-boot")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
testCompile("com.jayway.jsonpath:json-path")
testCompile("com.jayway.jsonpath:json-path-assert")
}

View File

@@ -1,12 +1,10 @@
logging:
level:
root: INFO
management:
security:
enabled: false
security:
basic:
enabled: false
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
endpoints:
default:
web:

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,13 @@
*/
package demo.monitoring;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -80,7 +82,11 @@ public class MonitoringTests {
andExpect(status().isOk());
mvc.
perform(get("/application/metrics")).
andExpect(jsonPath("$.['counter.ssm.transition.INITIAL_S1.transit']", is(1)));
andExpect(jsonPath("$.names", hasItems("ssm.transition.duration", "ssm.transition.transit")));
mvc.
perform(get("/application/metrics/ssm.transition.duration")).
andDo(print()).
andExpect(jsonPath("$['ssmTransitionDuration.transitionname.INITIAL_S1']", notNullValue()));
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package demo.web;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
@@ -41,7 +43,7 @@ public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfig
@Bean
public MapSessionRepository mapSessionRepository() {
return new MapSessionRepository();
return new MapSessionRepository(new ConcurrentHashMap<>());
}
}