【问题标题】:How to implement statistics using dropwizard metrics and spring-mvc如何使用 dropwizard 指标和 spring-mvc 实现统计
【发布时间】:2015-12-22 06:28:29
【问题描述】:

我有大约 20 个 API,我想为每个 API 实现执行时间、响应计数等统计信息。在做了一些研究之后,我知道dropwizard 指标是实现此类功能的最佳方法。我正在使用 Spring MVC 框架(不可启动)。谁能建议我如何将 Metrics 集成到 Spring MVC 框架中?

如果可能,请提供任何代码作为参考。

【问题讨论】:

  • 您提供的链接包含您希望将其集成到 Spring 应用程序中的所有代码。你试过了吗?
  • 是的,我试过了。但我不知道要调用什么来获取 API 的统计信息。

标签: spring-mvc statistics dropwizard metrics


【解决方案1】:

您可以使用Metrics for Spring。这是一个github link,它解释了如何将它与 Spring MVC 集成。 metrics-spring模块将Dropwizard Metrics library与Spring集成,提供XML和Java配置。

Maven

当前版本为 3.1.2,与 Metrics 3.1.2 兼容

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

基本用法

从版本 3 开始,metrics-spring 可以使用 XML 或 Java 进行配置, 看个人喜好吧。

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 配置:

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);
    }

}

阅读更多Metrics Spring

【讨论】:

  • 谢谢。我已经实现了同样的事情,但我不知道要调用什么来获取 API 的统计信息。
  • @kumar 您可以在哪里知道要调用什么来获取指标?
  • @kumar 这取决于您希望如何实现此指标。在此处查看入门指南,metrics.dropwizard.io/4.1.2/getting-started.html
【解决方案2】:

正如已经建议的那样,Metrics Spring 提供了一些与 Spring 的有趣集成。如果您想从 JSON API 访问这些指标,您仍然需要添加 http://metrics.dropwizard.io/3.1.0/manual/servlets/ 中记录的 servlet。

为了使用这些 servlet,您需要添加依赖项:

<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-servlets</artifactId>
    <version>${metrics.version}</version>
</dependency>

然后在 web.xml 中添加 servlet:

<servlet>
 <servlet-name>metrics-admin</servlet-name>
 <servlet-class>com.codahale.metrics.servlets.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name>metrics-admin</servlet-name>
 <url-pattern>/metrics/admin/*</url-pattern>
</servlet-mapping>

你也可以使用JavaConfig来配置它。

注册小服务程序:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import com.codahale.metrics.servlets.AdminServlet;

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        ServletRegistration.Dynamic metricsServlet = servletContext.addServlet("metrics", new AdminServlet());
        metricsServlet.addMapping("/metrics/admin/*");
    }
}

并提供servlet所需的属性:

import java.util.concurrent.TimeUnit;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.codahale.metrics.servlets.HealthCheckServlet;
import com.codahale.metrics.servlets.MetricsServlet;
import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;

@Configuration
@EnableMetrics
public class MetricsConfiguration extends MetricsConfigurerAdapter {

    @Autowired ServletContext servletContext;
    @Autowired
    private HealthCheckRegistry healthCheckRegistry;
    @Override
    public void configureReporters(MetricRegistry metricRegistry) {
        registerReporter(ConsoleReporter
            .forRegistry(metricRegistry)
            .build())
            .start(1, TimeUnit.MINUTES);
        servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY, metricRegistry);
        servletContext.setAttribute(HealthCheckServlet.HEALTH_CHECK_REGISTRY, healthCheckRegistry);
    }
}

【讨论】:

    【解决方案3】:

    我对上述答案有一些补充。

    你需要在WebInitializer里面注册MetricsConfiguration为RootConfigClasses,否则不会加载。

    我发现我的 Spring 版本 (4.2.5) 的 AOP 版本与来自 metrics-spring 的版本不匹配,这会导致 ClassNotFoundException。只需将 spring-aop 排除为 pom 中 metrics-spring 的依赖项即可。

    最后,您可以像这样轻松实现自己的 Metrics Controller:

    @Controller
    public class MetricsContoller {
    
    @Autowired 
    private ServletContext servletContext;
    
    @RequestMapping(value="/metrics", method=RequestMethod.GET)
    public @ResponseBody MetricRegistry saveTestStep() throws ServletException {
        final Object registryAttr = servletContext.getAttribute(MetricsServlet.METRICS_REGISTRY);
        if (registryAttr instanceof MetricRegistry) {
            return (MetricRegistry) registryAttr;
        } else {
            throw new ServletException("Couldn't find a MetricRegistry instance.");
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-09-03
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多