Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #45 from ryantenney/register
Browse files Browse the repository at this point in the history
Register metrics and metrics sets in xml
  • Loading branch information
ryantenney committed Nov 13, 2013
2 parents 38dd0fb + c53a82b commit 8a2f1e5
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 1 deletion.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@
<artifactId>metrics-annotation</artifactId>
<version>${metrics.version}</version>
</dependency>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-jvm</artifactId>
<version>${metrics.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@

class MetricsNamespaceHandler extends NamespaceHandlerSupport {

public static final String METRICS_NAMESPACE = "http://www.ryantenney.com/schema/metrics";

@Override
public void init() {
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser("metric-registry", new MetricRegistryBeanDefinitionParser());
registerBeanDefinitionParser("health-check-registry", new HealthCheckRegistryBeanDefinitionParser());
registerBeanDefinitionParser("reporter", new ReporterBeanDefinitionParser());
registerBeanDefinitionParser("register", new RegisterMetricBeanDefinitionParser());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* Copyright (C) 2012 Ryan W Tenney ([email protected])
*
* 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 com.ryantenney.metrics.spring.config;

import java.util.List;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;

import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.MetricSet;

import static com.ryantenney.metrics.spring.config.MetricsNamespaceHandler.METRICS_NAMESPACE;

class RegisterMetricBeanDefinitionParser implements BeanDefinitionParser {

@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
final CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compDefinition);

final String metricRegistryBeanName = element.getAttribute("metric-registry");
if (!StringUtils.hasText(metricRegistryBeanName)) {
throw new RuntimeException(); // TODO
}
final RuntimeBeanReference metricRegistryBeanRef = new RuntimeBeanReference(metricRegistryBeanName);

final List<Element> metricElements = DomUtils.getChildElementsByTagName(element, new String[] { "bean", "ref" });
for (Element metricElement : metricElements) {
// Get the name attribute and remove it (to prevent Spring from looking for a BeanDefinitionDecorator)
final String name = metricElement.getAttributeNS(METRICS_NAMESPACE, "name");
if (name != null) {
metricElement.removeAttributeNS(METRICS_NAMESPACE, "name");
}

final Object metric = parserContext.getDelegate().parsePropertySubElement(metricElement, null);

final RootBeanDefinition metricRegistererDef = new RootBeanDefinition(MetricRegisterer.class);
metricRegistererDef.setSource(parserContext.extractSource(metricElement));
metricRegistererDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

final ConstructorArgumentValues args = metricRegistererDef.getConstructorArgumentValues();
args.addIndexedArgumentValue(0, metricRegistryBeanRef);
args.addIndexedArgumentValue(1, name);
args.addIndexedArgumentValue(2, metric);

final String beanName = parserContext.getReaderContext().registerWithGeneratedName(metricRegistererDef);
parserContext.registerComponent(new BeanComponentDefinition(metricRegistererDef, beanName));
}

parserContext.popAndRegisterContainingComponent();

return null;
}

public static class MetricRegisterer implements InitializingBean {

private final MetricRegistry metricRegistry;
private final String name;
private final Metric metric;

public MetricRegisterer(MetricRegistry metricRegistry, String name, Metric metric) {
this.metricRegistry = metricRegistry;
this.name = name;
this.metric = metric;

if (!StringUtils.hasText(name) && !(metric instanceof MetricSet)) {
throw new RuntimeException(); // TODO
}
}

@Override
public void afterPropertiesSet() throws Exception {
metricRegistry.register(name, metric);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
targetNamespace="http://www.ryantenney.com/schema/metrics"
elementFormDefault="qualified" attributeFormDefault="unqualified">

<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"/>

<xsd:element name="annotation-driven">
<xsd:complexType>
Expand Down Expand Up @@ -55,4 +55,15 @@
</xsd:complexType>
</xsd:element>

<xsd:element name="register">
<xsd:complexType>
<xsd:sequence maxOccurs="unbounded">
<xsd:element ref="beans:bean"/>
</xsd:sequence>
<xsd:attribute name="metric-registry" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>

<xsd:attribute name="name" type="xsd:string"/>

</xsd:schema>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright (C) 2012 Ryan W Tenney ([email protected])
*
* 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 com.ryantenney.metrics.spring;

import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.codahale.metrics.MetricRegistry;

public class RegisterElementTest {

@Test
public void testRegisterMetrics() {
ClassPathXmlApplicationContext ctx = null;
try {
ctx = new ClassPathXmlApplicationContext("classpath:register-element-test.xml");
MetricRegistry registry = ctx.getBean(MetricRegistry.class);
Assert.assertTrue(registry.getMetrics().size() > 0);
for (String metricName : registry.getMetrics().keySet()) {
Assert.assertTrue(metricName.startsWith("jvm."));
}
}
finally {
if (ctx != null) {
ctx.close();
}
}
}

}
39 changes: 39 additions & 0 deletions src/test/resources/register-element-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2012 Ryan W Tenney ([email protected])
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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:metrics="http://www.ryantenney.com/schema/metrics"

xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.ryantenney.com/schema/metrics http://www.ryantenney.com/schema/metrics/metrics-3.0.xsd">

<metrics:metric-registry id="metrics" />

<metrics:register metric-registry="metrics">
<bean metrics:name="jvm.gc" class="com.codahale.metrics.jvm.GarbageCollectorMetricSet" />
<bean metrics:name="jvm.memory" class="com.codahale.metrics.jvm.MemoryUsageGaugeSet" />
<bean metrics:name="jvm.thread-states" class="com.codahale.metrics.jvm.ThreadStatesGaugeSet" />
<bean metrics:name="jvm.fd.usage" class="com.codahale.metrics.jvm.FileDescriptorRatioGauge" />
</metrics:register>

</beans>

0 comments on commit 8a2f1e5

Please sign in to comment.