Springboot disable selected prometheus metrics - spring-boot

I am using springboot gateway 2.0.4.RELEASE.
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
After adding this dependency, it is exposing all metrics to prometheus endpoint.
I want to disable some of the metrics from exposing through /actuator/prometheus endpoint.
Let's say I want to disable
gateway_requests_seconds_count
gateway_requests_seconds_sum
gateway_requests_seconds_max
Does anyone know how can I achieve this ?
Thanks
Alpesh

Related

How to include timestamps in Spring Boot Actuator Prometheus metrics

I am using Spring Boot 2.5.4 and Actuator with Micrometer and Prometheus support.
When I open the /actuator/prometheus endpoint, I see metrics like these:
# HELP jvm_threads_live_threads The current number of live threads including both daemon and non-daemon threads
# TYPE jvm_threads_live_threads gauge
jvm_threads_live_threads 28.0
Note that there is no timestamp attached to that metric. However, according to OpenMetrics / Prometheus spec, it is possible to add a timestamp to the metrics output.
My question: How can you tell Spring Boot Actuator to generate and add a timestamp to the metrics it creates? I have not found any documentation on it. Thanks!
References
My pom.xml dependencies look like this:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
My application.yaml like this:
# Application name. Shows up in metrics etc.
spring:
application:
name: "some_app_name"
# Expose application on port 8080
server:
port: ${SERVER_PORT:8080}
# Expose all Actuator endpoints (don't do this in production!)
management:
endpoints:
web:
exposure:
include:
- "*"
Micrometer doesn't support this at the moment. The team's recommendation is to use the Prometheus Java Client directly for metrics where the timestamp is important to you.

How to enable actuator endpoints which are set in custom starter / library?

I have got custom starter application (library) which has actuator and prometheus dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.5.2</version>
</dependency>
in application.properties
management.endpoints.web.exposure.include=health, info, metrics, prometheus
I am using this starter in my other applications and I want to pass also this exposition of the endpoints from the starter.
Actuator and Prometheus dependecies works in applications but not show selected endpoints in starter. Ofc I can add also line with management.endpoints.web.exposure.include=health, info, metrics, prometheus to my apps but with several apps using this starter I want to pass this once for all and change endpoints only in starter if needed.
Do you have an idea how to expose those endpoints in my app which are set in starter?
Spring Boot v2.3.2 /
Maven 3.6.3
You can pass this as command line args or as ENV vars to your jar, when you start your application.
This way you can pass it to required application, as and when needed w/o updating application.properties.
It will also safeguard against exposing the actuator endpoints when not required, as actuator endpoints reveal sensitive info about the application.
eg. java -Dmanagement.endpoints.web.exposure.include=health, info, metrics, prometheus -jar myapp.jar

Prometheus java/Spring API for fetching metrics

I need to query for collected metrics in my application and the only way I found to do it is via Prometheus rest api as described here: https://prometheus.io/docs/prometheus/latest/querying/api/ Does any Spring or java api for fetching metrics from Prometheus exist, so that I wouldn't have to implement it from scratch?
If you want to collect metrics from your spring application using Prometheus, this is what you have to do:
In your application's pom.xml add this dependency:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.7.0</version>
</dependency>
In application.properties you need to add:
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
And this should be all, now when you start your Spring application you can check the collected metrics at /actuator/prometheus, you'll have all the metrics grouped here.
Good luck!

Spring Cloud Bus - Refresh a specific cluster of client

I have a spring cloud config server configured over spring cloud bus over kafka.
I am using Edgware.RELEASE with boot 1.5.9.
When I send a POST request to the endpoint /bus/refresh with destination=clientId:dev:** in the body via POSTMAN to config server, all the clients get their beans refreshed even though their clientId doesn't match the value in the destination field.
Here are additional configuration details:
spring cloud config server
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
application.properties
server.port=8888
management.security.enabled=false
spring.cloud.bus.enabled=true
spring.kafka.bootstrap-servers=localhost:9092
I have two config clients with id - config-client1 and config-client2
After changing an application property in the repository for config-client2, I submit a POST request to /bus/refresh endpoint on the config server, with destination=config-client2:dev:** in the body of the request. I was hoping this would refresh/re-initialize the beans only in config-client2 application. But I noticed beans in config-client application are also refreshed/re-initialized. I also noticed config-client application receiving refresh event along with config-client2.
I was hoping only config-client2 application receives the event and its beans are the only ones that are refreshed as a result of it.
Wondering if I am missing any configuration setting to enable granular refresh at specific client level.
I did go through the document posted at - http://cloud.spring.io/spring-cloud-static/Edgware.RELEASE/single/spring-cloud.html, but the results are not as explained.
Any help with a working example is appreciated.
You can use:
curl -X POST http://localhost:8001/actuator/bus-refresh/config-client2
You also need this in your application.properties or .yml.
spring.cloud.config.uri=http://localhost:8001
spring.cloud.config.uri should point to your Spring Config Server

Spring boot Kubernetes Service Discovery

I am running into issues with Kubernetes Service Discovery on Spring Boot applications.
I should be able to discover the services whether my spring boot application is running within or out of Kubernetes cluster. Our local development won't be on k8s cluster.
I am using Service Discovery via DNS. I tried using spring-cloud-starter-kubernetes
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<version>0.2.0.RELEASE</version>
</dependency>
As per documentation you should be able to autowire DiscoveryClient and good to go
#Autowire
private DiscoveryClient discoveryClient;
DiscoveryClient is part of spring-cloud-commons. spring-cloud-starter-kuberenetes doesn't have it.
Anyone solved similar problem using the same library or a different one? Please share the solution
Thanks!
I have solved this issue using the Spring Cloud Kubernetes Dependencies
<spring.cloud.kubernetes>0.2.0.RELEASE</spring.cloud.kubernetes>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-ribbon</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-config</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-core</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
What was very important for me was the ribbon dependency as it makes use of a load balanced rest template in order to substitute service names for the correct pod IP's that are found in your kubernetes cluster.
I have created a git repo as part of answering a larger set of questions but it should be more than sufficient if someone is looking a way to implement Kubernetes service discovery in place of Eureka or Consul.
https://github.com/foundery-rmb/kubernetes-service-discovery

Resources