Updates to redis repositories

* Ensure prefix ends with period
* Allow prefix and key index to be set separately
pull/272/head
Dave Syer 11 years ago
parent d64b18cca9
commit 195eb9f9bc

@ -22,8 +22,6 @@ import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -39,7 +37,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.StopWatch;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.UrlPathHelper;
/**
@ -72,23 +70,20 @@ public class MetricFilterAutoConfiguration {
* Filter that counts requests and measures processing times.
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
private final class MetricsFilter extends GenericFilterBean {
private final class MetricsFilter extends OncePerRequestFilter {
/*
* (non-Javadoc)
*
* @see
* org.springframework.web.filter.OncePerRequestFilter#doFilterInternal(javax.
* servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
* javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if ((request instanceof HttpServletRequest)
&& (response instanceof HttpServletResponse)) {
doFilter((HttpServletRequest) request, (HttpServletResponse) response,
chain);
}
else {
chain.doFilter(request, response);
}
}
public void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) throws ServletException,
IOException {
UrlPathHelper helper = new UrlPathHelper();
String suffix = helper.getPathWithinApplication(request);
StopWatch stopWatch = new StopWatch();

@ -0,0 +1,70 @@
/*
* Copyright 2012-2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.actuate.metrics.Metric;
/**
* @author Dave Syer
*/
public class CompositeMetricReader implements MetricReader {
private List<MetricReader> delegates = Collections.emptyList();
public void setDelegates(Collection<MetricReader> delegates) {
this.delegates = new ArrayList<MetricReader>(delegates);
}
@Override
public Metric<?> findOne(String metricName) {
for (MetricReader delegate : this.delegates) {
Metric<?> value = delegate.findOne(metricName);
if (value != null) {
return value;
}
}
return null;
}
@Override
public Iterable<Metric<?>> findAll() {
List<Metric<?>> values = new ArrayList<Metric<?>>((int) count());
for (MetricReader delegate : this.delegates) {
Iterable<Metric<?>> all = delegate.findAll();
for (Metric<?> value : all) {
values.add(value);
}
}
return values;
}
@Override
public long count() {
long count = 0;
for (MetricReader delegate : this.delegates) {
count += delegate.count();
}
return count;
}
}

@ -45,9 +45,9 @@ public class RedisMetricRepository implements MetricRepository {
private String prefix = DEFAULT_METRICS_PREFIX;
private String keys = this.prefix + "keys";
private String key = "keys." + DEFAULT_METRICS_PREFIX;
private final BoundZSetOperations<String, String> zSetOperations;
private BoundZSetOperations<String, String> zSetOperations;
private final RedisOperations<String, String> redisOperations;
@ -59,7 +59,7 @@ public class RedisMetricRepository implements MetricRepository {
RedisTemplate<String, Long> longRedisTemplate = RedisUtils.createRedisTemplate(
redisConnectionFactory, Long.class);
this.longOperations = longRedisTemplate.opsForValue();
this.zSetOperations = this.redisOperations.boundZSetOps(this.keys);
this.zSetOperations = this.redisOperations.boundZSetOps(this.key);
}
/**
@ -68,20 +68,30 @@ public class RedisMetricRepository implements MetricRepository {
* @param prefix the prefix to set for all metrics keys
*/
public void setPrefix(String prefix) {
if (!prefix.endsWith(".")) {
prefix = prefix + ".";
}
this.prefix = prefix;
this.keys = this.prefix + "keys";
}
/**
* The redis key to use to store the index of other keys. The redis store will hold a
* zset under this key. Defaults to "keys.spring.metrics". REad operations, especially
* {@link #findAll()} and {@link #count()}, will be much more efficient if the key is
* unique to the {@link #setPrefix(String) prefix} of this repository.
*
* @param key the key to set
*/
public void setKey(String key) {
this.key = key;
this.zSetOperations = this.redisOperations.boundZSetOps(this.key);
}
@Override
public Metric<?> findOne(String metricName) {
String redisKey = keyFor(metricName);
String raw = this.redisOperations.opsForValue().get(redisKey);
if (raw != null) {
return deserialize(redisKey, raw);
}
else {
return null;
}
return deserialize(redisKey, raw);
}
@Override
@ -94,7 +104,10 @@ public class RedisMetricRepository implements MetricRepository {
List<Metric<?>> result = new ArrayList<Metric<?>>(keys.size());
List<String> values = this.redisOperations.opsForValue().multiGet(keys);
for (String v : values) {
result.add(deserialize(keysIt.next(), v));
Metric<?> value = deserialize(keysIt.next(), v);
if (value != null) {
result.add(value);
}
}
return result;
@ -131,6 +144,9 @@ public class RedisMetricRepository implements MetricRepository {
}
private Metric<?> deserialize(String redisKey, String v) {
if (redisKey == null || v == null || !redisKey.startsWith(this.prefix)) {
return null;
}
String[] vals = v.split("@");
Double value = Double.valueOf(vals[0]);
Date timestamp = vals.length > 1 ? new Date(Long.valueOf(vals[1])) : new Date();
@ -146,8 +162,6 @@ public class RedisMetricRepository implements MetricRepository {
}
private String nameFor(String redisKey) {
Assert.state(redisKey != null && redisKey.startsWith(this.prefix),
"Invalid key does not start with prefix: " + redisKey);
return redisKey.substring(this.prefix.length());
}

@ -37,20 +37,23 @@ public class RedisMetricRepositoryTests {
@Rule
public RedisServer redis = RedisServer.running();
private RedisMetricRepository repository;
private String prefix;
@Before
public void init() {
this.repository = new RedisMetricRepository(this.redis.getResource());
this.prefix = "spring.test." + System.currentTimeMillis();
this.repository.setPrefix(this.prefix);
}
@After
public void clear() {
assertNotNull(new StringRedisTemplate(this.redis.getResource()).opsForValue()
.get("spring.metrics.foo"));
.get(this.prefix + ".foo"));
this.repository.reset("foo");
this.repository.reset("bar");
assertNull(new StringRedisTemplate(this.redis.getResource()).opsForValue().get(
"spring.metrics.foo"));
this.prefix + ".foo"));
}
@Test

@ -25,7 +25,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.PoolConfig;
@ -112,8 +111,13 @@ public class RedisAutoConfiguration {
}
}
@Bean(name = "org.springframework.autoconfigure.redis.RedisProperties")
@ConditionalOnMissingBean
public RedisProperties redisProperties() {
return new RedisProperties();
}
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
protected static class RedisConfiguration {
@Autowired

Loading…
Cancel
Save