Giter Site home page Giter Site logo

metrics-spring's Introduction

Metrics for Spring

Build Status Maven Central GitHub license

About

The metrics-spring module integrates Dropwizard Metrics library with Spring, and provides XML and Java configuration.

This module does the following:

  • Creates metrics and proxies beans which contain methods annotated with @Timed, @Metered, @ExceptionMetered, and @Counted
  • Registers a Gauge for beans which have members annotated with @Gauge and @CachedGauge
  • Autowires Timers, Meters, Counters and Histograms into fields annotated with @Metric
  • Registers with the HealthCheckRegistry any beans which extend the class HealthCheck
  • Creates reporters from XML config and binds them to the Spring lifecycle
  • Registers metrics and metric sets in XML

Maven

Current version is 3.1.3, which is compatible with Metrics 3.1.2

<dependency>
    <groupId>com.ryantenney.metrics</groupId>
    <artifactId>metrics-spring</artifactId>
    <version>3.1.3</version>
</dependency>

Basic Usage

As of version 3, metrics-spring may be configured using XML or Java, depending on your personal preference.

Spring Context XML:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:metrics="http://www.ryantenney.com/schema/metrics"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.ryantenney.com/schema/metrics
           http://www.ryantenney.com/schema/metrics/metrics.xsd">

    <!-- Creates a MetricRegistry bean -->
    <metrics:metric-registry id="metricRegistry" />

    <!-- Creates a HealthCheckRegistry bean (Optional) -->
    <metrics:health-check-registry id="health" />

    <!-- Registers BeanPostProcessors with Spring which proxy beans and capture metrics -->
    <!-- Include this once per context (once in the parent context and in any subcontexts) -->
    <metrics:annotation-driven metric-registry="metricRegistry" />

    <!-- Example reporter definiton. Supported reporters include jmx, slf4j, graphite, and others. -->
    <!-- Reporters should be defined only once, preferably in the parent context -->
    <metrics:reporter type="console" metric-registry="metricRegistry" period="1m" />

    <!-- Register metric beans (Optional) -->
    <!-- The metrics in this example require metrics-jvm -->
    <metrics:register metric-registry="metricRegistry">
        <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 and other Spring config -->

</beans>

Java Annotation Config:

import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Configuration;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries;
import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;

@Configuration
@EnableMetrics
public class SpringConfiguringClass extends MetricsConfigurerAdapter {

    @Override
    public void configureReporters(MetricRegistry metricRegistry) {
        // registerReporter allows the MetricsConfigurerAdapter to
        // shut down the reporter when the Spring context is closed
        registerReporter(ConsoleReporter
            .forRegistry(metricRegistry)
            .build())
            .start(1, TimeUnit.MINUTES);
    }

}

XML Config Documentation

The <metrics:annotation-driven /> element is required, and has 4 optional arguments:

  • Attributes
  • metric-registry - the id of the MetricRegistry bean with which the generated metrics should be registered. If omitted a new MetricRegistry bean is created.
  • health-check-registry - the id of the HealthCheckRegistry bean with which to register any beans which extend the class HealthCheck. If omitted a new HealthCheckRegistry bean is created.
  • proxy-target-class - if set to true, always creates CGLIB proxies instead of defaulting to JDK proxies. This may be necessary if you use class-based autowiring.
  • expose-proxy - if set to true, the target can access the proxy which wraps it by calling AopContext.currentProxy().

The <metrics:metric-registry /> element constructs a new MetricRegistry or retrieves a shared registry:

  • Attributes
  • id - the bean name with which to register the MetricRegistry bean
  • name - the name of the MetricRegistry, if present, this calls SharedMetricRegistries.getOrCreate(name)

The <metrics:health-check-registry /> element constructs a new HealthCheckRegistry:

  • Attributes
  • id - the bean name with which to register the HealthCheckRegistry bean

The <metrics:reporter /> element creates and starts a reporter:

  • Attributes
  • id - the bean name
  • metric-registry - the id of the MetricRegistry bean for which the reporter should retrieve metrics
  • type - the type of the reporter. Additional types may be registered through SPI (more on this later).
  • console: ConsoleReporter
  • jmx: JmxReporter
  • slf4j: Slf4jReporter
  • ganglia: GangliaReporter (requires metrics-ganglia)
  • graphite: GraphiteReporter (requires metrics-graphite)

The <metrics:register /> element registers with the MetricRegistry a bean which extends implements Metric or MetricSet

  • Attributes
  • metric-registry - the id of the MetricRegistry bean with which the metrics are to be registered
  • Child elements
  • <bean /> - The beans to register with the specified registry.
  • metrics:name attribute on the bean element - specifies the name with which the metric will be registered. Optional if the bean is a MetricSet.

Java Config Documentation

A @Configuration class annotated with @EnableMetrics is functionally equivalent to using the <metrics:annotation-driven /> element.

  • proxyTargetClass - if set to true, always creates CGLIB proxies instead of defaulting to JDK proxies. This may be necessary if you use class-based autowiring.
  • exposeProxy - if set to true, the target can access the proxy which wraps it by calling AopContext.currentProxy().

The class may also implement the interface MetricsConfigurer, or extend the abstract class MetricsConfigurerAdapter

  • getMetricRegistry() - return the MetricRegistry instance with which metrics should be registered. If omitted a new MetricRegistry instance is created.
  • getHealthCheckRegistry() - return the HealthCheckRegistry instance with which to register any beans which extend the class HealthCheck. If omitted a new HealthCheckRegistry instance is created.
  • configureReporters(MetricRegistry) - configure reporters

A Note on the Limitations of Spring AOP

Due to limitations of Spring AOP only public methods can be proxied, so @Timed, @Metered, @ExceptionMetered, and @Counted have no effect on non-public methods. Additionally, calling an annotated method from within the same class will not go through the proxy.

public class Foo {
	
    @Timed
    public void bar() { /* … */ }
	
    public void baz() {
        this.bar(); // doesn't pass through the proxy
		
        // fix: reengineer
        // workaround: enable `expose-proxy` and change to:
        ((Foo) AopContext.currentProxy()).bar(); // hideous, but it works
    }
}

As @Gauge doesn’t involve a proxy, it may be used on non-public fields and methods. Additionally, @InjectMetric may be used on non-public, non-final fields.

Users of the Maven Shade plugin

Please see the Shade Readme

Documentation

Javadocs are hosted at http://ryantenney.github.io/metrics-spring/docs/

Acknowledgements

YourKit

YourKit is kindly supporting this open source project with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler.

License

Copyright (c) 2012-2017 Ryan Tenney

Portions Copyright (c) 2012-2013 Martello Technologies

Published under Apache Software License 2.0, see LICENSE

Rochester Made

metrics-spring's People

Contributors

adammelliott avatar bryant1410 avatar codahale avatar davidkarlsen avatar fgaule avatar fkjellberg avatar mattbertolini avatar ninthnails avatar oconnor0 avatar organicveggie avatar prb avatar rburgst avatar ryantenney avatar sandor-nemeth avatar scullxbones avatar thyzzv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metrics-spring's Issues

Issue with covariant return types

interface ReturnANumber {
  @Metered
  public Number getNumber();
}
class ReturnAnInteger implements ReturnANumber {
  @Override
  public Integer getNumber() { return 1; }
}

99.9995% certain this will fail. Create a test case and see if this can be fixed.

Generic <metrics:reporter> tag

A tag to create ANY type of reporter (provided that the target reporter follows certain conventions). Core reporters could have aliases, so type="jmx" would be equivalent to class="com.yammer.metrics.reporting.JmxReporter".

<metrics:reporter type="jmx" />
<metrics:reporter class="com.yammer.metrics.reporting.JmxReporter" />
<metrics:reporter class="com.yammer.metrics.reporting.CsvReporter" p:outputDir="./foodir/" />
<metrics:reporter class="com.yammer.metrics.graphite.GraphiteReporter" p:host="hostname" p:port="1111" />
<metrics:reporter class="com.librato.metrics.LibratoReporter" p:username="foo" p:token="bar" p:source="hostname" />
<!-- et cetera -->

Adding <metrics:annotation-driven/> to spring context results in failed container startup

I've been looking at incorporating yammer metrics into our software and since we're a spring shop your spring-metrics project looks pretty interesting to me. We're heavy users of auto-wiring & annotations so using @timed and the like is pretty natural.

However, when I add the metrics:annotation-driven/ custom bean into my spring context I get the following at runtime:

Error creating bean with name 'xyz': Bean with name 'xyz' has been injected into other beans [pdq,abc] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

(names of classes changed to protect the innocent...)

The spring container fails to start after this.

no declaration can be found for element 'metrics:annotation-driven'

Hello,
I am getting this execution error, even if I provide the <metrics:annotation-driven/> in my bean repo.

And the final jar contains an appropriate file com/ryantenney/metrics/spring/config/metrics-3.0.xsd (contains effectively an <xsd:element name="annotation-driven">)

here is the content of my bean repository:

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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">

        <context:component-scan base-package="xxxxx" />
        <context:component-scan base-package="xxxxx" />

        <metrics:annotation-driven/>

        <!-- other beans -->

    </beans>

Thanks for any help.

Tie reporters created with Java config to Spring's lifecycle

In 3.0.0-RC2-SNAPSHOT it's possible to call registerReporter(Closeable) in a Java-config class which extends MetricsConfigurerAdapter, which in turn destroys the reporter when the Spring context closes. However, it would be much better if it tied into the Spring lifecycle (start/stop). Not entirely sure how to do this though.

getting weird sax parser exception while using metrics

Hi

I am also getting
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'metrics:metrics-registry'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)

I am facing this issue from last 3 days. when i directly click
http://www.ryantenney.com/schema/metrics/metrics-3.0.xsd
it gives me page not found. I downloaded it manually and tried to parse it but did not get succesful.

Please help.

My spring configuration is.

xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
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.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.ryantenney.com/schema/metrics http://www.ryantenney.com/schema/metrics/metrics-3.0.xsd">

Change Default Naming for Meters or Timers

currently it is not possible to annotate a method with both Timed and Metered annotations and their default values as the Interceptors will try to create a Meter and a Timer with the same name (resulting in a class cast exception).

The only solutions for this are:

  1. changes to the registry to handle this case
  2. configuration of the name property for at least one annotation in every case
  3. a change to the default naming mechanism in at least one of the interceptors

Personally i would like to add a prefix to the default metrics name as it is already done in the ExceptionMetered Interceptor.

InjectMetric javadocs aren't clear for function of "absolute" parameter

Hi, I think this may be just a javadoc issue, but it's not exactly clear what the "absolute" parameter on @InjectMetric does. It's listed as a boolean but the description says "The name of the type of events the meter is measuring."

It seems to me that the "name" attribute defines the name of the metric, no? If so, it's not clear what the boolean attribute does.

Please clarify. Thanks.

Annotation config (@EnableMetrics)

Support for the new XML-less config option added in Spring 3.1

@Configuration
@EnableMetrics
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration {

}

Instrumenting caches in spring

I can't seem to get metrics correctly set up on my caches. I've tried programmatically instrumenting the caches and I've tried adding the instrumented cache decorator in the ehcache.xml. Can you post an example of a cache being properly instrumented?

Unable to used @Timed with non default constructor

I am new to Spring, and trying to get Metrics setup within the project. I first set it up with 2.x and everything was working well. I am migrating to 3.x and using this project for the spring integration. I am trying to use the @timed annotation with the following class:

@Component
@Path("/v1/logs")
@Produces(MediaType.APPLICATION_JSON)
public class LogsModuleResource {
...
@Autowired
  public LogsModuleResource(final LogContentService contentService, final LogSearchService searchService) {
    this.contentService = contentService;
    this.searchService = searchService;
  }
...
       @GET
    @Path("content")
        @Timed
    public List<LogEntry> getLogFileContent(

The issue I am facing is that Spring can not create the object and throws the following exception:

Caused by: 
org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.pivotal.hd.nodeagent.module.logs.LogsModuleResource]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
        at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:217)
        at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
        at com.ryantenney.metrics.spring.AdvisingBeanPostProcessor.postProcessAfterInitialization(AdvisingBeanPostProcessor.java:82)
...
Caused by: 
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
        at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
        at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
        at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
        at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
        at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
        at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
        at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
        at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205)
        at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
        at com.ryantenney.metrics.spring.AdvisingBeanPostProcessor.postProcessAfterInitialization(AdvisingBeanPostProcessor.java:82)

Here is my pom

<dependency>
      <groupId>com.codahale.metrics</groupId>
      <artifactId>metrics-core</artifactId>
      <version>3.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.codahale.metrics</groupId>
      <artifactId>metrics-servlet</artifactId>
      <version>3.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.codahale.metrics</groupId>
      <artifactId>metrics-servlets</artifactId>
      <version>3.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.codahale.metrics</groupId>
      <artifactId>metrics-healthchecks</artifactId>
      <version>3.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.ryantenney.metrics</groupId>
      <artifactId>metrics-spring</artifactId>
      <version>3.0.0-RC2</version>
    </dependency>
    <dependency>
      <groupId>com.codahale.metrics</groupId>
      <artifactId>metrics-jersey</artifactId>
      <version>3.0.1</version>
    </dependency>

I am super new to spring (just had to learn it this weak), and its late, so sorry if I have something setup wrong.

@Timed and friends on class level

Since metrics 3.1 (not released yet and again with new package names) it's possible to place the annotations on the class level which greatly reduces boilerplate code. Do you plan to support this?

Currently the code is coupled to the method level and it's not possible to extend metrics-spring to support other annotations because everything is package protected.

Unfortunately this makes metrics-spring for me hard to use because the original metrics annotations can only be placed on the method level. With class level support I could add the annotations to a stereotype/meta annotation.

Regards
Lars

@Gauge annotation on Gauge field shouldn't wrap it in another Gauge

public class SomethingWithGauge {

    @Gauge
    private Gauge<Integer> oneGauge = new Gauge<Integer>() {
        public Integer getValue() {
            return 1;
        }
    }

}

Results in the creation and registration of a Gauge<Gauge<Integer>>, instead it should directly register the Gauge<Integer>.

Unable to autowire custom metric registry

I think this may just be a configuration issue, but we've created a subclass of MetricRegistry and are trying to wire it in our XML file but are getting NPEs due to the autowiring failing. Here is what we have, is it correct?

   <bean id="myMetricRegistry" class="com.foo.bar.metric.MyMetricRegistry"/>
   <metrics:annotation-driven metric-registry="myMetricRegistry"/>

I don't think we need the metrics:metric-registry element anymore, right?

Thanks.

Health Registry

Hi I am not able to see any stats for Health Register. I was just trying to create a POC for myself. Could you please help me in this.

///////////////////////////

<metrics:annotation-driven metrics-registry="metrics" health-check-registry="health"/>

<metrics:jmx-reporter  metrics-registry="metrics" />

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

<metrics:health-check-registry id="health" />

<bean id="databaseHealthCheck" class="com.rbsfm.emcs.metrics.DatabaseHealthCheck" >
</bean>

//////////////////
public class DatabaseHealthCheck extends HealthCheck {

private final String database="Database";


public DatabaseHealthCheck(){
    super("health");
}

@Override
public HealthCheck.Result check() throws Exception {
    if (database.equals("Database")) {
        return HealthCheck.Result.healthy();
    } else {
        return HealthCheck.Result.unhealthy("Cannot connect to " );
    }
}

}

This is code that I have written. Now how can I see my health check? and is this the way I can register my health register by passing the id name in constructor or I can do anything in the application context.xml itself.

I have also added the metrics servlet because i think i can not get it in JMXReporter
web.xml contains

    <servlet>
<servlet-name>Metrics</servlet-name>
<servlet-class>com.yammer.metrics.reporting.MetricsServlet</servlet-class>
<init-param>
 <param-name>metrics-uri</param-name>
<param-value>/metrics</param-value>
 </init-param>
<init-param>
 <param-name>ping-uri</param-name>
 <param-value>/ping</param-value>
 </init-param>
<init-param>
 <param-name>healthcheck-uri</param-name>
 <param-value>/health</param-value>
 </init-param>
<init-param>
 <param-name>threads-uri</param-name>
 <param-value>/threads</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>Metrics</servlet-name>
<url-pattern>/Metrics/*</url-pattern>
</servlet-mapping>

my pom.xml contains

com.ryantenney.metrics
metrics-spring
2.1.4


com.yammer.metrics
metrics-servlet
2.2.0

But when i click on http://localhost:8080/enabLiteService/Metrics/health. it does not show me anything. M I missing something . or you can share any metricsservlet example with me.

Thanks
Vivek

NPE with a Spring Integration managed field

Hi, I'm trying to add metrics (2.2.0) to a project that uses Spring Integration. I have little experience with metrics or SI, but as I understand the error, it seems metrics-spring is trying to do some AOP stuff on this field (an interface which gets resolved by SpringIntegration) and I'm getting this error:

java.lang.NullPointerException
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:563)
    at com.yammer.metrics.spring.GaugeAnnotationBeanPostProcessor.postProcessAfterInitialization(GaugeAnnotationBeanPostProcessor.java:43)

Is there a way I can go around this? Like excluding that field from metrics-spring scan?

Thanks,

Detect annotations on interfaces

If the @Timed annotation is placed on the interface, the aspect isn't awoken (annotation must be placed on the implementation class).

This is problematic if you want to monitor Spring Data's repositories where there is no implementation.

In AnnotationFilter#matches, you should use Spring's AnnotationUtils#findAnnotation (or something like that) instead of method.isAnnotationPresent(clazz)

Tested on 3.0.1

Spring Metrics doesn't support Spring Expression Lanuage

Just added port="#{appProperties['graphite.port']}" in applicationContext-metrics.xml. However, the metrics-spring will first validate port field and then throw an exception about failure validation. I checked the code in line 220 of AbstractReporterElementParser, it turns out the SpEL is not supported, since "^\\$\\{.*\\}$" is just a placeholder regex. It could be nice if SpEl is supported.

OSGi bundle does not work

Hi Ryan,

I've had problems getting the OSGi bundle to run (exceptions on Virgo startup). The cause was that in your manifest's Import-Package section 3 entries were missing: org.springframework.cglib.core,org.springframework.cglib.proxy,org.springframework.cglib.reflect

After I added those, the problems were gone. Please fix the manifest.

Thanks

Slf4j support

Please add slf4j support by adding the follow method:

ConsoleReporter.Builder.outputTo(Logger logger)

Health check registration support

It would be nice if we can register health checks via spring configuration:

<metrics:register metric-registry="metrics">
    <bean metrics:name="database" class="DatabaseHealthCheck"/>..</bean>
</metrics>

which is equal to:

registry.register("database", new DatabaseHealthCheck(database));

Metrics JMX Bean not raised

Hi, I'm evaluating if I can use metrics-spring in my application and I think I have found an issue in v3.0.0. I'm using Spring 3.2.8.RELEASE and this is the situation:

two context files are loaded at application startup
- metricsContext.xml -> contains the metrics stuff

<beans ...>
<metrics:metric-registry id="metrics" />
<metrics:annotation-driven metric-registry="metrics" />
<metrics:reporter id="consoleReporter" type="console" metric-registry="metrics" period="1m" />
<metrics:reporter id="jmxReporter" type="jmx" metric-registry="metrics" />
</beans>

- applicationContext.xml -> contains the normal stuff, but in particular
<beans ...>
<bean id="listener" init-method="startListening" destroy-method="stopListening" class="<myclass>" />
</beans>

I have spreaded some annotations inside the app itself, just for testing

In this case the "metrics" jmx bean is not created.

ADDITIONAL information:

If I add to metricsContext.xml

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="mmg:service=Metrics JMX Reporter" value-ref="jmxReporter"/>
</map>
</property>
</bean>

and restart the application the metrics is NOT added but if I access to mmg:service and select Metrics JMX Reporter and select the "start" operation then the
"metrics" bean appears in JMX console WITHOUT CachedGauge metrics. The other metrics seem to work fine

ADDITIONAL information:

If in application context I remove the init-method="startListening"

- applicationContext.xml
<beans ...>
<bean id="listener" destroy-method="stopListening" class="....Listener" />
</beans>

Then the "metrics" is available in JMX and contains the CachedGauge metrics

Unable to share registry objects from a root application context to a servlet context

We have a Tomcat webapplication that consists of 2 Spring contexts (root and servlet context) which are configured programmatically with the Spring AbstractAnnotationConfigDispatcherServletInitializer. Our root context contains all Spring components and services and our servlet context contains all controllers. We need to configure metrics-spring in the root context, so the registries are found by the AdminServlet (through the ContextLoaderListener). Unfortunately, with this setup we cannot acces the registries from the servlet context in which I have configured some @timed annotations. Instead the @EnableMetrics annotation creates a new set of registries. I have an @configuration with @EnableMetrics in the root context and a separate @configuration with @EnableMetrics in the servlet context which is needed for enabling component scanning in the controllers.
There is 1 solution: create a single application context as the root application context, but this does not seems like a correct one.

Using multiple metrics annotations on a single target method

Tried to put more than one metrics annotation which fails with an exception:
"name is already used for a different type of metric"

    // Only one annotation allowed at a time???
    //@Counted
    @Timed
    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<TaskResource> showAll() {
        //TODO use repository for fetching data
        TaskResource taskResource = taskResourceAssembler.toResource(new Task(1l, "task"));
        return new ResponseEntity<>(taskResource, HttpStatus.OK);
    }

Any specific technical limitation why this is not possible? Does it mean that in such a case the name has to be set explicitely?

Property placeholders not replaced in XML bean definitions

Hi

I've found that property placeholders are not being replaced when used in XML bean definitions and was wondering if this is a known issue or is planned for future development?

In my situation, I'm trying to define a GangliaReporter that uses different configuration depending on the environment where it's deployed:

<metrics:reporter metric-registry="registry" type="ganglia" period="1m"
    group="${ganglia.group}"
    port="${ganglia.port}"
    udp-mode="${ganglia.udp-mode}"
    ttl="${ganglia.ttl}"/>

I get the following error when the Spring context initialises:

Attribute 'udp-mode': No enum constant info.ganglia.gmetric4j.gmetric.GMetric.UDPAddressingMode.${ganglia.udp-mode}

Release v2.1.3

Please release a version that builds against metrics-2.1.3.

Custom reporter in metrics-spring

I have configured metrics-spring in my application using xml config. I wanted to add custom reporter through xml config. But I was not able to find any documentation around it. Can you please help me, giving some guideline regarding the same ?
Thank you.

Enable flag for reporters

Hi Ryan,

Been using your framework and it's really nice!

Was wondering if it'd be cool if there's an "enabled" property for the reporters. Here's the use case that I'm having:

I have a properties file which I pull, uh, properties from. I'd like to have my reporter beans created conditionally, like so:

### metrics.properties ###
metrics.graphite.enabled=true

### metrics.xml ###
<metrics:reporter type="graphite" enabled="${metrics.graphite.enabled}" host="localhost" port="2003" period="1m" />

Is this possible? Right now, my workaround is by making a shim class that gets initialized by Spring, and uses that enabled boolean in the @PostConstruct method, but I could get away by just XML configuration, that would be best.

Thanks!

Support for automatically instrumenting controllers

It would be nice if there was an annotation such as @Instrumented for classes that automatically scanned for all methods annotated with @RequestMapping ( support for Jersey would be a bonus too ) and automatically generated meters, timings, and exception meters for all methods.

It's tedious and ugly with large APIs to go call by call especially with naming semantics causing conflicts if you have more than one annotation on a call.

This ends up with every controller method looking like this:

@Timed(name="processLogon.timings")
@Counted(name="processLogon.counts")
@ExceptionMetered(name="processLogon.exceptions.meter")
@Metered(name="processLogon.meter")
    @RequestMapping(...)
    public LogonResult processLogon( ... ) { ... }

I'd be very happy with convention just automatically letting me apply this to entire controllers.

Classes implementing an interface are not metered

When using metrics-spring in a situation where you have a class implementing an interface meterics are not recorded. When I add the metrics on the class it does find the metrics but when invoking the method the metrics are never called.

The method as saved in the hashmap of for example the TimerMethodInterceptor is the actual method. But the method is used to fetch the Timer from the hashmap is the interface method so the Timer is not fetched from the hasmap.

I'll create a test for this and looking for a solution. But I wanted to verify that this should actually work:

interface ClassInterface {
  public void timedMethod();
}

class ClassImpl implements ClassInterface {
  @Timed
  @Override
  public void timedMethod() {
     // My timer is found by the annotation and added to a reporter
     // but when called the timer is not updated...
  }
}

Cannot differentiate metrics on overloaded methods.

I've been using the metrics-spring project to send metrics to graphite. I have a class with overloaded methods that I wanted to time using the Timed annotation. I specified a name for each of the annotations to differentiate between them. But I noticed that all of the metrics go into just one of the Timed metrics. I was hoping to collect different metrics for each of the overloaded methods rather than have them rolled into one. Can we change the MethodInterceptor classes (i.e. TimedMethodInterceptor) to use the metric name to look up metrics instead of the method name to handle the case of overloaded methods and differentiating between them?

Create README

It would be nice to have a readme here, explaining that this is now the canonical repo for metrics-spring (if that's the case).

MetricsRegistry Listener not being added in web application

<metrics:metric-registry id="registry" name="springMetrics" />
<metrics:reporter type="console" metric-registry="registry" period="1m" />    

I believe that your AbstractReporterFactoryBean implementations should be implementing SmartLIfeCycle and not Lifecycle. In a web application, the start() methods are not being called on lifecycle and thus, the listeners are not being registered with the Metric Registry. If you implement SmartLifecycle and return true for autostartup then your start method will be called.

I'm using Spring MVC 3.2.2 on a Tomcat 6 server. I've set multiple breakpoints, but it's just not registering the listener so the reporters never display anything.

Improve automatic naming

Related to #68

It would be nice to be able to use all the annotations simultaneously, without having manually specify their names.

Metrics XSD doesn't exist at given schemaLocation

http://www.ryantenney.com/schema/metrics/metrics-3.0.xsd doesn't exist, which only causes problems if the file metrics-3.0.xsd isn't on the classpath, which shouldn't ever happen, but seems to happen quite regularly.

Injection of metrics

Instantiate and register a metric of the selected type. Create @InjectedMetric annotation and bean processor.

Proposed annotation:

public @interface InjectedMetric {
    String domain(); // formerly group
    String type();
    String name();
    String eventType(); // Timer, Meter
    TimeUnit rateUnit(); // Timer, Meter
    TimeUnit durationUnit(); // Timer
    boolean biased(); // Histogram
}

Example use:

@Component
public class SomethingWithLotsOfMetrics {

    @InjectedMetric
    Timer timer;

    @InjectedMetric(domain = "foo", type = "bar", name = "baz",
        eventType = "poops", rateUnit = TimeUnit.SECONDS)
    Meter meter;

    @InjectedMetric(biased = true)
    Histogram ctr;

}

Validate bean's properties after properties placeholder post processor when using XML Configuration

Hi Ryan!

When using a XML bean configuration, the AbstractReporterElementParser classes are validating some properties values using regex. At this state, properties placeholders don't get processed yet, causing validations errors. Or am I missing something?

Is it possible to validate then at AbstractScheduledReporterFactoryBean instead (or when the reporters instances are being created)? So, we may use the properties placeholder feature. Example:

<metrics:metric-registry id="registry" name="springMetrics" />
<metrics:annotation-driven metric-registry="registry" />
<metrics:reporter id="metricReporter" type="graphite" 
    metric-registry="registry" 
    port="${metrics.port}"  
    period="${metrics.period}"
    host="${metrics.host}" />

I removed the regex validation for tests purposes at GraphiteReporterElementParser and worked fine.

I only test it using metrics:reporter, but I think this behavior could be the same at the others elements as well.

Thanks!

AspectJ support

Are there any plans for implementing AspectJ support, which would allow for compile-time performance improvements? AspectJ should also circumvent some of the limitations of Spring AOP.

... also, go Amerks.

com.yammer.metrics.core.Meter cannot be cast to com.yammer.metrics.core.Timer

Hi. I'm try use spring with metrics, but I get this exception:

com.yammer.metrics.core.Meter cannot be cast to com.yammer.metrics.core.Timer (line 318 in MetricsRegistry class)

But I does not use Meter ... Where does he get it ?

I'am use this annotations:

@Timed(group = "processorCore", name = "execute", durationUnit = TimeUnit.MILLISECONDS, rateUnit = TimeUnit.MILLISECONDS) @ExceptionMetered(group = "processorCore", name = "execute", rateUnit = TimeUnit.MILLISECONDS)

I'm sorry, need write different name for one group...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.