1

I am trying to make an object repositoryMetrics in SpringBoot and later I obtained information with this repository. But I create a repository and this always is null.

How I generate a repository and this save the metrics? I have this code:

public static void stateSist() throws Exception {

    InMemoryMetricRepository metricRepository = null;
    metricRepository.findAll();
    System.out.println(metricRepository.count());

}

EDIT 1:

I do this change in my version and I obtained this error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'actuatorMetricsPrinter' defined in file [ActuatorMetricsPrinter.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.Collection]: : No qualifying bean of type [org.springframework.boot.actuate.endpoint.PublicMetrics] found for dependency [collection of org.springframework.boot.actuate.endpoint.PublicMetrics]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.actuate.endpoint.PublicMetrics] found for dependency [collection of org.springframework.boot.actuate.endpoint.PublicMetrics]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:747)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1115)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at hello.Application.main(Application.java:14)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.actuate.endpoint.PublicMetrics] found for dependency [collection of org.springframework.boot.actuate.endpoint.PublicMetrics]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1118)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:919)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:811)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:739)
... 18 common frames omitted

Thank you!

herzo
  • 105
  • 4
  • 12
  • Herzo, the code you have pasted does absolutely nothing. You need to provide us with more information about your environment - are you using Spring Data - if so which module (JPA, Mongo, etc.). And please paste your configuration of the Spring Boot application. Without it we cannot help you. – Rafal G. May 01 '15 at 20:53
  • @R4J I use spring boot actuator, and I want know how fill this repository. I dont see example in the web for this. – herzo May 01 '15 at 21:03
  • If you are using Actuator, then this repository is already created. All you need to do is to inject it to your component and manipulate the contents. See the code on Github: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/repository/InMemoryMetricRepository.java – Rafal G. May 01 '15 at 21:06
  • @R4J but I don´t understand when the repository is fill?. It is automatically when execute application? – herzo May 01 '15 at 21:07
  • Actuator works from the moment you start your application and records lots of different statistics (http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html). – Rafal G. May 01 '15 at 21:11
  • oks, but I have a problem when I need obtained information of this repository. Because in my example, always give me null pointer... How do this repository? – herzo May 01 '15 at 21:13
  • Your example will not work. Ever. You directly assign null reference to your repository variable. Do you know how to autowire beans in spring or are you completely new to the subject? – Rafal G. May 02 '15 at 05:24
  • @R4J I do some things, but I don´t know how do this. I autowire and repository and this fill? – herzo May 02 '15 at 07:59

2 Answers2

2

In order to access all Public Metrics printed by the Spring Boot actuator framework you need to inject a 'Collection' into your component and then access it to read all the metrics. Here is an example:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.actuate.endpoint.PublicMetrics;
    import org.springframework.boot.actuate.metrics.Metric;
    import org.springframework.stereotype.Component;

    import java.util.Collection;

    @Component
    public class ActuatorMetricsPrinter {
        private static final String TEMPLATE = "Metric: %s [%s]";

        private final Collection<PublicMetrics> publicMetrics;

        @Autowired
        public ActuatorMetricsPrinter(Collection<PublicMetrics> publicMetrics) {
            this.publicMetrics = publicMetrics;
        }

        public String printAllMetrics() {

            StringBuilder sb = new StringBuilder();

            for (PublicMetrics pm : publicMetrics) {
                sb.append("Public Metric: " + pm.getClass().getName());
                sb.append("\n\n");

                for (Metric<?> m : pm.metrics()) {
                    sb.append(String.format(TEMPLATE, m.getName(), m.getValue().toString()));
                    sb.append("\n");
                }
            }

            return sb.toString();
        }
    }

If you want to reproduce this simple scenario, then:

  1. Go to http://start.spring.io/ and create new project with Actuator and Web checked,
  2. Create a demo project with Build tool of your choice (Gradle, Maven),
  3. Download it and open in your IDE,
  4. Create a new component just like one in my example,
  5. Create a new RestController, like this:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DummyController {

    private final ActuatorMetricsPrinter metricsPrinter;

    @Autowired
    public DummyController(ActuatorMetricsPrinter metricsPrinter) {
        this.metricsPrinter = metricsPrinter;
    }

    @RequestMapping(value = "/customMetrics", method = RequestMethod.GET)
    public String printMetrics() {
        return metricsPrinter.printAllMetrics();
    }
}
  1. Then start the application and type in your browser: http://localhost:8080/customMetrics
  2. You should see all the metrics printed by your class in the most messy way possible
aksappy
  • 3,400
  • 3
  • 23
  • 49
Rafal G.
  • 4,252
  • 1
  • 25
  • 41
0

If you are using Maven or Gradle for dependency management, then you must make sure these are present in either (from Spring Clouds's Home Page):

Maven:

<parent>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-parent</artifactId>
    <version>Angel.SR4</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
</dependencies>

Gradle:

buildscript {
  dependencies {
    classpath "io.spring.gradle:dependency-management-plugin:0.4.0.RELEASE"
  }
}

apply plugin: "io.spring.dependency-management"

dependencyManagement {
  imports {
    mavenBom 'org.springframework.cloud:spring-cloud-starter-parent:Angel.SR4'
  }
}

dependencies {
    compile 'org.springframework.cloud:spring-cloud-starter-config'
    compile 'org.springframework.cloud:spring-cloud-starter-eureka'
}

If you omit the parent in Maven or the dependencyManagement in gradle, and try to just import the latest version of each of the dependencies, you will get the runtime error that you are describing.

A similar problem addresses this here on GitHub.

Michael Plautz
  • 3,578
  • 4
  • 27
  • 40