update ServerMetricCollector to include instance and statistic tags if present.
fixes gh-348
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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.cloud.netflix.servo;
|
||||
|
||||
import com.netflix.servo.Metric;
|
||||
import com.netflix.servo.annotations.DataSourceType;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.tag.Tag;
|
||||
import com.netflix.servo.tag.TagList;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DefaultServoMetricNaming implements ServoMetricNaming {
|
||||
private static final String JMX_DOMAIN_KEY = "JmxDomain";
|
||||
public static final String SERVO = "servo.";
|
||||
|
||||
@Override
|
||||
public String getName(Metric metric) {
|
||||
MonitorConfig config = metric.getConfig();
|
||||
TagList tags = config.getTags();
|
||||
|
||||
Tag domainTag = tags.getTag(JMX_DOMAIN_KEY);
|
||||
String name;
|
||||
if (domainTag != null) { // jmx metric
|
||||
name = handleJmxMetric(config, tags);
|
||||
}
|
||||
else {
|
||||
name = handleMetric(config, tags);
|
||||
}
|
||||
return name.toLowerCase();
|
||||
}
|
||||
|
||||
private String handleMetric(MonitorConfig config, TagList tags) {
|
||||
String type = cleanValue(tags.getTag(DataSourceType.KEY), false);
|
||||
String instanceName = cleanValue(tags.getTag("instance"), false);
|
||||
String name = cleanupIllegalCharacters(config.getName(), false);
|
||||
String statistic = cleanValue(tags.getTag("statistic"), false);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
if (type != null) {
|
||||
nameBuilder.append(type).append(".");
|
||||
}
|
||||
nameBuilder.append(SERVO);
|
||||
if (instanceName != null) {
|
||||
nameBuilder.append(instanceName).append(".");
|
||||
}
|
||||
if (name != null) {
|
||||
nameBuilder.append(name).append(".");
|
||||
}
|
||||
if (statistic != null) {
|
||||
nameBuilder.append(statistic).append(".");
|
||||
}
|
||||
// remove trailing "."
|
||||
nameBuilder.deleteCharAt(nameBuilder.lastIndexOf("."));
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
|
||||
private String handleJmxMetric(MonitorConfig config, TagList tags) {
|
||||
String domain = cleanValue(tags.getTag(JMX_DOMAIN_KEY), true);
|
||||
String type = cleanValue(tags.getTag("Jmx.type"), false);
|
||||
String instanceName = cleanValue(tags.getTag("Jmx.instance"), false);
|
||||
String name = cleanValue(tags.getTag("Jmx.name"), false);
|
||||
String fieldName = cleanupIllegalCharacters(config.getName(), false);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
nameBuilder.append(domain).append(".");
|
||||
if (type != null) {
|
||||
nameBuilder.append(type).append(".");
|
||||
}
|
||||
nameBuilder.append(SERVO);
|
||||
if (instanceName != null) {
|
||||
nameBuilder.append(instanceName).append(".");
|
||||
}
|
||||
if (name != null) {
|
||||
nameBuilder.append(name).append(".");
|
||||
}
|
||||
if (fieldName != null) {
|
||||
nameBuilder.append(fieldName).append(".");
|
||||
}
|
||||
// remove trailing "."
|
||||
nameBuilder.deleteCharAt(nameBuilder.lastIndexOf("."));
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
|
||||
private String cleanValue(Tag tag, boolean allowPeriodsInName) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return cleanupIllegalCharacters(tag.getValue(), allowPeriodsInName);
|
||||
}
|
||||
|
||||
private String cleanupIllegalCharacters(String s, boolean allowPeriodsInName) {
|
||||
if (!allowPeriodsInName) {
|
||||
s = s.replace(".", "_");
|
||||
}
|
||||
return s.replace(" ", "_");
|
||||
}
|
||||
}
|
||||
@@ -17,19 +17,15 @@
|
||||
package org.springframework.cloud.netflix.servo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.publish.BaseMetricObserver;
|
||||
import com.netflix.servo.publish.BasicMetricFilter;
|
||||
import com.netflix.servo.publish.MetricObserver;
|
||||
import com.netflix.servo.publish.MonitorRegistryMetricPoller;
|
||||
@@ -46,9 +42,9 @@ import com.netflix.servo.publish.PollScheduler;
|
||||
@CommonsLog
|
||||
public class ServoMetricCollector implements DisposableBean {
|
||||
|
||||
public ServoMetricCollector(MetricWriter metrics) {
|
||||
List<MetricObserver> observers = new ArrayList<MetricObserver>();
|
||||
observers.add(new ServoMetricObserver(metrics));
|
||||
public ServoMetricCollector(MetricWriter metrics, ServoMetricNaming naming) {
|
||||
List<MetricObserver> observers = new ArrayList<>();
|
||||
observers.add(new ServoMetricObserver(metrics, naming));
|
||||
PollRunnable task = new PollRunnable(new MonitorRegistryMetricPoller(),
|
||||
BasicMetricFilter.MATCH_ALL, true, observers);
|
||||
|
||||
@@ -80,35 +76,4 @@ public class ServoMetricCollector implements DisposableBean {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MetricObserver} to convert Servo metrics into Spring Boot {@link Metric}
|
||||
* instances.
|
||||
*/
|
||||
private static final class ServoMetricObserver extends BaseMetricObserver {
|
||||
|
||||
private final MetricWriter metrics;
|
||||
|
||||
public ServoMetricObserver(MetricWriter metrics) {
|
||||
super("spring-boot");
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateImpl(List<com.netflix.servo.Metric> servoMetrics) {
|
||||
for (com.netflix.servo.Metric servoMetric : servoMetrics) {
|
||||
MonitorConfig config = servoMetric.getConfig();
|
||||
String type = config.getTags().getValue("type");
|
||||
String key = new StringBuilder(type).append(".servo.")
|
||||
.append(config.getName()).toString().toLowerCase();
|
||||
|
||||
if (servoMetric.hasNumberValue()) {
|
||||
this.metrics.set(new Metric<Number>(key,
|
||||
servoMetric.getNumberValue(), new Date(servoMetric
|
||||
.getTimestamp())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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.cloud.netflix.servo;
|
||||
|
||||
import com.netflix.servo.Metric;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface ServoMetricNaming {
|
||||
String getName(Metric metric);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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.cloud.netflix.servo;
|
||||
|
||||
import com.netflix.servo.Metric;
|
||||
import com.netflix.servo.publish.BaseMetricObserver;
|
||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link com.netflix.servo.publish.MetricObserver} to convert Servo metrics into Spring Boot {@link org.springframework.boot.actuate.metrics.Metric}
|
||||
* instances.
|
||||
*/
|
||||
final class ServoMetricObserver extends BaseMetricObserver {
|
||||
|
||||
private final MetricWriter metrics;
|
||||
private final ServoMetricNaming naming;
|
||||
|
||||
public ServoMetricObserver(MetricWriter metrics, ServoMetricNaming naming) {
|
||||
super("spring-boot");
|
||||
this.metrics = metrics;
|
||||
this.naming = naming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateImpl(List<Metric> servoMetrics) {
|
||||
for (Metric servoMetric : servoMetrics) {
|
||||
String key = naming.getName(servoMetric);
|
||||
|
||||
if (servoMetric.hasNumberValue()) {
|
||||
this.metrics.set(new org.springframework.boot.actuate.metrics.Metric<>(key,
|
||||
servoMetric.getNumberValue(), new Date(servoMetric
|
||||
.getTimestamp())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,8 +45,15 @@ public class ServoMetricsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServoMetricCollector servoMetricCollector(MetricWriter metrics) {
|
||||
return new ServoMetricCollector(metrics);
|
||||
public ServoMetricNaming servoMetricNaming() {
|
||||
return new DefaultServoMetricNaming();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServoMetricCollector servoMetricCollector(MetricWriter metrics,
|
||||
ServoMetricNaming naming) {
|
||||
return new ServoMetricCollector(metrics, naming);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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.cloud.netflix.servo;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import com.netflix.servo.annotations.DataSourceType;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.netflix.servo.Metric;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DefaultServerMetricNamingTests {
|
||||
|
||||
private DefaultServoMetricNaming naming = new DefaultServoMetricNaming();
|
||||
|
||||
@Test
|
||||
public void vanillaServoMetricWorks() {
|
||||
MonitorConfig config = MonitorConfig.builder("testMetric") .build();
|
||||
String name = naming.getName(new Metric(config, System.currentTimeMillis(), 0));
|
||||
assertThat(name, is(equalTo("servo.testmetric")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeTagWorks() {
|
||||
MonitorConfig config = MonitorConfig.builder("testMetric")
|
||||
.withTag(DataSourceType.KEY, DataSourceType.COUNTER.getValue())
|
||||
.build();
|
||||
String name = naming.getName(new Metric(config, System.currentTimeMillis(), 0));
|
||||
assertThat(name, is(equalTo("counter.servo.testmetric")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instanceTagWorks() {
|
||||
MonitorConfig config = MonitorConfig.builder("testMetric")
|
||||
.withTag("instance", "instance0")
|
||||
.build();
|
||||
String name = naming.getName(new Metric(config, System.currentTimeMillis(), 0));
|
||||
assertThat(name, is(equalTo("servo.instance0.testmetric")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void statisticTagWorks() {
|
||||
MonitorConfig config = MonitorConfig.builder("testMetric")
|
||||
.withTag("statistic", "min")
|
||||
.build();
|
||||
String name = naming.getName(new Metric(config, System.currentTimeMillis(), 0));
|
||||
assertThat(name, is(equalTo("servo.testmetric.min")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allTagsWork() {
|
||||
MonitorConfig config = MonitorConfig.builder("testMetric")
|
||||
.withTag(DataSourceType.KEY, DataSourceType.COUNTER.getValue())
|
||||
.withTag("instance", "instance0")
|
||||
.withTag("statistic", "min")
|
||||
.build();
|
||||
String name = naming.getName(new Metric(config, System.currentTimeMillis(), 0));
|
||||
assertThat(name, is(equalTo("counter.servo.instance0.testmetric.min")));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user