Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added spring-boot client #114

Merged
merged 1 commit into from May 25, 2016
Merged

Conversation

tokuhirom
Copy link
Contributor

I want to use spring-boot's metrics/health checking feature as a prometheus exporter.

ref.

@brian-brazil
Copy link
Contributor

I'm not too familiar with Spring, however this appears to be a mix of a wrapper, bridge, collector and exporter. Each of those should probably be separate.

@tokuhirom
Copy link
Contributor Author

Okay, I'll split into modules.

@tokuhirom
Copy link
Contributor Author

tokuhirom commented May 20, 2016

I split the module into following modules.
https://gyazo.com/28a123d0edb966ee6d33bfa371900ad2

@tokuhirom
Copy link
Contributor Author

I removed some over eringeering modules.
I want to add metrics_reader and metrics_writer.

/**
* Returns the number of collectors in this registry.
*/
public int size() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Old implementation required this. But it was removed.

@tokuhirom
Copy link
Contributor Author

I rewrote all of the code. Could you re-review this?


<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>1.3.3.RELEASE</spring.boot.version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should put this in literally. Some build tools have problems with variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inlined a variable.

@brian-brazil
Copy link
Contributor

That looks generally good, just some nits left.

@brian-brazil
Copy link
Contributor

That's looking good.

Could you add a docstring demonstrating how to use it, and squash your commits?

@tokuhirom
Copy link
Contributor Author

Thanks. I added docstring. And squashed commits.

@brian-brazil brian-brazil merged commit 7ebe34a into prometheus:master May 25, 2016
@brian-brazil
Copy link
Contributor

Thanks!

@haocheng
Copy link

haocheng commented Jun 22, 2016

Hi @tokuhirom ,

Would you please provide an example about how to use SpringBootMetricsCollector?
Is adding a @configuration class like the code below enough?

@Configuration
public class MetricsConfiguration {

    @Bean
    public SpringBootMetricsCollector springBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
      SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(publicMetrics);
      springBootMetricsCollector.register();
      return springBootMetricsCollector;
    }

}

Thank you!

@tokuhirom
Copy link
Contributor Author

@ haocheng
Yes. it looks good.

Here is a complete example:

package com.example;

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.MetricsServlet;
import io.prometheus.client.hotspot.DefaultExports;
import io.prometheus.client.spring.boot.SpringBootMetricWriter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringBootPrometheusSampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootPrometheusSampleApplication.class, args);
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        DefaultExports.initialize();
        return new ServletRegistrationBean(new MetricsServlet(), "/prometheus");
    }

    @Bean
    public SpringBootMetricWriter springBootMetricWriter() {
        return new SpringBootMetricWriter(CollectorRegistry.defaultRegistry);
    }
}

@haocheng
Copy link

Hi @tokuhirom ,

Thank you for the great work! It works like a charm ;)

BTW, I cannot find SpringBootMetricWriter, but using SpringBootMetricsCollector instead works fine.

import io.prometheus.client.exporter.MetricsServlet;
import io.prometheus.client.hotspot.DefaultExports;
import io.prometheus.client.spring.boot.SpringBootMetricsCollector;
import java.util.Collection;
import org.springframework.boot.actuate.endpoint.PublicMetrics;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MetricsConfiguration {

  @Bean
  public ServletRegistrationBean servletRegistrationBean() {
    DefaultExports.initialize();
    return new ServletRegistrationBean(new MetricsServlet(), "/prometheus");
  }

  @Bean
  public SpringBootMetricsCollector springBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
    SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(
        publicMetrics);
    springBootMetricsCollector.register();
    return springBootMetricsCollector;
  }

}

@robachmann
Copy link

@haocheng, where do you get the Collection<PublicMetrics> from? I'm getting a Could not autowire. No beans of 'PublicMetrics' or 'Collection<PublicMetrics>' types found error using your example with Spring Boot 1.4.1.
Thanks!

@haocheng
Copy link

haocheng commented Nov 4, 2016

@240ch um... I am still using Spring boot 1.3.3. Do you have spring-boot-actuator in your dependency lib? It seems that PublicMetrics is included in that library.

@johnmgibbons
Copy link

Is there a guide for how to use this? Trying to use spring boot's metrics as an exporter for prometheus.

Thanks!

@hakamairi
Copy link

@johnmgibbons try @haocheng 's code above and be sure to add following dependencies:

    compile "org.springframework.boot:spring-boot-starter-actuator"
    compile "io.prometheus:simpleclient:0.0.19"
    compile "io.prometheus:simpleclient_common:0.0.19"
    compile "io.prometheus:simpleclient_hotspot:0.0.19"
    compile "io.prometheus:simpleclient_servlet:0.0.19"
    compile "io.prometheus:simpleclient_spring_boot:0.0.19"

@hakamairi
Copy link

hakamairi commented Dec 8, 2016

Hi @tokuhirom ,
I've tried your solution with Spring Boot 1.4.2 and Spring Cloud 1.1.6. When I have @EnabledDiscoveryClient on my main class and possibly "org.springframework.cloud:spring-cloud-starter-eureka" dependency I get in my /prometheus repeated lines like:

HELP counter_servo_eurekaclient_transport_request

Which makes Prometheus unhappy:

text format parsing error in line 88: second HELP line for metric name "counter_servo_eurekaclient_transport_request"

Is this my misconfiguration, or is this a bug?

EDIT:
I've done some debugging

this.publicMetrics = {LinkedHashMap$LinkedValues@7351} size = 4
0 = {MetricReaderPublicMetrics@7356}
metricReader = {ServoMetricReader@7360}
monitorRegistry = {DefaultMonitorRegistry@7361}
registry = {BasicMonitorRegistry@7363}
monitors = {Collections$SynchronizedSet@7364} size = 119
publicMetrics.txt

There you can see that for requests they actually use the same name but different id and/or status.
This gets lost in translation, and results in duplicated counter/gauges for prometheus
prometheus.txt

I think just changing the logic in SpringBootMetricsCollector to generate a name of the Metric to account for that should be enough. Shall I open a bug report?

EDIT:
I've tried to fix that myself, found that org.springframework.boot.actuate.metrics.Metric is actually pretty simple with no Ids or Statuses.
The metric to blame comes from com.netflix.servo.monitor package. I've ended up filtering those out. Not nice, but at least some workaround is possible.

@JasonBeiJing
Copy link

hey, you just need add @EnableSpringBootMetricsCollector, DONE.
if u check the source code, u will find that EnableSpringBootMetricsCollector imports the configuration: PrometheusMetricsConfiguration which defines the actual implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants