Spring-Boot-Actuator Endpoint Prometheus not shown correctly - spring

I want to show some metrics using micrometer prometheus in combination with the spring-boot-actuator. My project is totally based on spring-boot and has the actuator feature enabled and mapped on the following url: http://localhost:9000/actuator
Other endpoints are shown correctly but the http://localhost:9000/actuator/prometheus isnĀ“t. Below you find a screenshot that I get when accessing this http-endpoint.
Can anybody help me? Why is this happening and how do i fix it?
Cause normally prometheus is configured automatically for spring-boot-actuator when you provide the suitable dependency.

you need to check many things to be sure to enable Prometheus by Actuator
First thing you should put the following dependency on your pom.xml to enable Prometheus on your project.
<!-- enable prometheus-->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.10.2</version>
</dependency>
The second point you must check if the actuator exists on your
project or not if doesn't exist, you need to add the following
dependency.
<!--to enable actuator help to trace project-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
You need to add the following scripts to your application.yml to
enable the actuator and Prometheus by actuator.
.
management:
security:
enabled: false
server:
port: 9000
endpoint:
metrics:
enabled: true
prometheus:
enabled: true
health:
show-details: always
show-components: always
probes:
enabled: true
shutdown:
enabled: true
info:
env:
enabled: true
enabled: true
endpoints:
web:
exposure:
include: prometheus, metrics, info, health, shutdown, beans
using the above script the actuator will run on port 9000 and you can send a request to the following URL to access the actuator.
http://localhost:9000/actuator/prometheus
and the following URL to access Prometheus
http://localhost:9000/actuator/prometheus
Note: you must check where you are writing your script because I was confused between endpoint and endpoints
The endpoint to set the actuator config.
The endpoints to set the actuator URLs endpoint
Note: you can delete the port from application.yml and the actuator will run by current application port
best luck

This is auto-cofigured by default, here are some pointers for troubleshooting:
Check if you added micrometer-registry-prometheus (without defining the version, the version should come from the BOM)
Check if the actuator endpoint is enabled: management.endpoints.web.exposure.include=*
Check if there is a controller that maps the path of the prometheus endpoint or any of its sub-paths (/, /actuator, /actuator/prometheus)
Check if you browser tricks you curl localhost:9090/actuator/prometheus

ok i solved it with the solution:
i created a bean of type prometheusMeterRegistry manually and so spring boot didn't configure it automatically leading to no metrics provided at the prometheus endpoint
see below code snippet for further details:
// #Bean
// public PrometheusMeterRegistry prometheusMeterRegistry() {
// return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
// }

In my case I was trying to set up prometheus on old project where was MetricsAutoConfiguration excluded. So removing exclude solved the problem.
#EnableAutoConfiguration(exclude = { MetricsAutoConfiguration.class})

Related

How to enable health in Spring Boot Actuator

I have to check whether my service / app works or not.
I've added dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.6.2</version>
</dependency>
and also tried to add management.endpoint.health.show-details: always to application.yml but it didn't help.
I tried to go to http://localhost:8080/actuator/health, http://localhost:8080/health but it returned 404 error.
You can try this code on your application.yaml. This is worked for Spring boot 2.6.7.
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: health
As you see, you have 404 both on
http://localhost:8080/actuator/health
and
http://localhost:8080/health
Reason for this is not because security is enabled, if security was enabled you will get 401 or 403.
You probably need to expose actuator endpoints in application.yaml file.
Something like this:
management:
endpoints:
web:
exposure:
include: "health,info"
And if you have security enabled, you need to write you own SecurityFilterChain implementation in which you will disable security on all Actuator endpoints, or in your case only on those that you exposed in your application.yaml file.
Example:
#Configuration
class ActuatorSecurityAutoConfiguration {
#Bean
SecurityFilterChain
surpassingActuatorSecurityFilterChain(HttpSecurity
httpSecurity) throws Exception {
return httpSecurity
.requestMatcher(EndpointRequest.toAnyEndpoint())
.authorizeRequests()
.anyRequest()
.permitAll()
.and().build();
}
}
By default Spring boot enables security for all actuator endpoints
You can disable that feature using below property
management.security.enabled=false
Henceforth, try to run the application and hit the endpoint
http://localhost:8080/actuator

Expose metrics from spring application to prometheus without using spring-boot actuator

I have been trying to collect micrometer metrics in a non springboot application and expose them to prometheus.I have added the following dependency and the test method for the same.I would like to know how to proceed and expose the collected metrics to prometheus from my non spring boot application(traditional spring application).
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.2.0</version>
</dependency>
public string testmetrics(){
private PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
registry.counter("ws metric collection","tktdoc metrics");
String metricsInfo = registry.scrape();
return metricsInfo;
}
You practically have to expose an HTTP endpoint and configure Prometheus with it; the HTTP endpoint will supply the data for the scrapes.
An example showing how to add the HTTP endpoint by starting up an HTTP Server (your application may already be using one) is here.

Unable to access /actuator endpoints

I've got a small project running Spring Boot and Spring Cloud Streams with version Greenwich.SR4.
So far I've tried to include the following dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
Wanting to have a /check/health endpoint which basically returns a code 200.
I've modified the config accordingly so that I don't have useless health configs within.
management.endpoints.web.base-path=/check
management.endpoint.health.enabled=true
management.health.solr.enabled=false
management.health.elasticsearch.enabled=false
However, whenever I try to run localhost:8080/check/health a 404 is prompted. What could be happening?
Also mentioning that I've tried including my own #RestController but same behavior happens.
The URL for the health check should be http://localhost:8080/check/health, not /check/status.
It is depends on the Spring-Boot version. After version 2.0 the path name is manage, so your right url is: http://localhost:8080/check/health
You can also change that with (.yml version):
management:
context-path: /manage
security:
enabled: false

Unable to generate different spring-cloud-gateway routes based on active Spring profile

I'm trying to define different routes in Spring Cloud Gateway using Spring profiles. Everything I've read about how Spring manages profiles using yaml sems to indicate it should work, but for the life of me it just ... doesn't seem to. (My other Spring apps use properties, so I'm unused to the yaml config -- it's possible I'm missing something.)
Effectively what I'm trying to do is to have a "prod" profile which contains the URIs for my production servers, and a "dev" profile which contains the localhost equivalents.
I have two profiles, dev and prod. My application.yml file looks like this
spring:
profiles:
default: prod
management:
endpoint:
health:
enabled: true
endpoints:
web:
exposure:
include: hystrix.stream, gateway
---
spring
profiles: prod
cloud:
gateway:
routes:
- id: test_route
uri: http://foo.mycompany.com
predicates:
- Path=/status
- Method=GET
---
spring
profiles: dev
cloud:
gateway:
routes:
- id: test_route
uri: http://localhost:8080
predicates:
- Path=/status
- Method=GET
My understanding is as follows:
the spring.profiles.default property tells Spring that, if no profile is specified, to use the prod profile
Spring will treat the --- as a "file separator" and re-evaluate each set of properties and overwrite previous values if the spring.profiles parameter evaluates true
Given this understanding, I would expect Spring to parse the "default" properties first, learning that the default activated profile should be prod. Then it will parse the prod properties. Since "prod" is an active profile (the only active profile, being the default), it should parse and apply the prod routes. Then it would parse the dev routes, but recognize that dev is not an active profile, and not overwrite those values. This is my understanding from reading the documentation on how to change config based on the environment.
However, when I load this, and I hit the actuator endpoint -- /actuator/gateway/routes -- I get back [] where I would expect to see the prod routes. I do see in my logs that the prod profile is activated, but it seems like not having the properties in the "default" section at top causes them to not be applied when the parser reads them out of the profile section.
The other thing I tried was putting the "dev" properties as the defaults, and then attempting to use the "prod" profile properties to overwrite the URIs. A similar issue happened there -- I hit the actuator endpoint and got back routes, but they were just the dev ones from the default.
How can I leverage Spring profiles to configure different Spring Cloud Config routes in my application.yml ?
Versions:
spring-cloud-gateway 2.0.1.BUILD-SNAPSHOT (to get a workaround for this bug, probably not relevant)
spring-cloud-starter-gateway
spring-boot 2.0.3.RELEASE
spring-boot-starter-webflux
spring-boot-starter-actuator
(I can't use Spring Cloud Config for political reasons. My company's chief architect has a severe case of Not Invented Here Syndrome.)
You cannot use spring.profiles.default in the property file. It will be too late for setting such value.
So you can set it using program argument (or System property). E.g.
java -jar --spring.profiles.default=dev your-app.jar
Or you can do it in the code by hardcoding the default profile:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(DemoApplication.class);
ConfigurableEnvironment environment = new StandardEnvironment();
environment.setDefaultProfiles("dev");
application.setEnvironment(environment);
application.run(args);
}
}
Some related information you can find here by reading all comments:
https://github.com/spring-projects/spring-boot/issues/1219

How to create more than one health check endpoints with Spring Boot Actuator

What I want to do
Create two (different) endpoints using Spring Boot Actuator
My environment
Spring Boot 1.4.2
spring-boot-starter-actuator embedded in Spring Boot 1.4.2
Detail
I'm creating a Web app using Spring Boot and will need to create two separated endpoints: one for just checking application health including the app's DB connection and so on (This will be realized by the default behavior of "/health") and the other for just checking if the app is ready for accepting HTTP requests (say "/httpcheck").
To implement health check feature, I guess it's the fastest way to use Spring Boot Actuator (by default, /health is mapped to health check endpoint).
I also understand we can configure this endpoint by extending AbstractHealthIndicator (so that it will include DB health check).
But as far as I could see, I could not find a way to create more than one endpoints to do different health checks.
Do you have any ideas?
Thanks in advance.
Thanks for your answer.
Actually, I dealt with this problem by implementing a new endpoint (/httpcheck) to simply check if its HTTP stack works well or not.
HttpCheckEndpoint.java
#Component
#ConfigurationProperties(prefix = "endpoints.httpcheck") // Specifies the prefix on application.yml
public class HttpCheckEndpoint extends AbstractMvcEndpoint {
public HttpCheckEndpoint() {
super("/httpcheck", false);
}
/**
* Check if simply the app can connect to their own HTTP stack and return 200 OK.
* <ul>
* <li>Method: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS</li>
* <li>Endpoint: "/httpcheck"</li>
* </ul>
*/
#RequestMapping
#ResponseBody
public ResponseEntity<String> checkHttpConnecton() {
if (!isEnabled()) {
return new ResponseEntity<String>("", HttpStatus.NOT_FOUND);
} else {
return new ResponseEntity<String>("{\"status\": \"UP\"}", HttpStatus.OK);
}
}
}
application.yml
endpoints:
enabled: false # Default enabled/disabled on endpoints on Spring Boot Actuator
health: # Health check (already prepared in Spring Boot Actuator)
enabled: true
httpcheck: # Simple HTTP connection check (newly created by myself)
enabled: true
I've confirmed it worked well, although not sure if it's the best solution...
Solution
You can use Jolokia end points in your Spring-boot application and get it registered with o.s.b.a.e.jmx.EndpointMBeanExporter along with your Actuator Plugins.
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
<version>1.2.2</version>
</dependency>
Jolokia Configurations in application.properties
jolokia.config.debug=true
endpoints.jolokia.enabled=true

Resources