I recently learned that springboot 2.3.0 offers liveness/readiness. In order to implement them, I updated springboot version to 2.3.0 and added dependency spring-boot-starter-validation in pom. I updated helm chart's env section as well to contain:
name: management.health.probes.enabled
value: 'true'
name: management.endpoint.health.group.readiness.include
value: 'readinessState,db'
Is this all I need to in order to implement liveness and readiness probes for the component? If so, is there way to test this locally? My co-worker told me if I can write environment locally in application.properties, I should be able to test it locally (running postman and expose api such as /actuator/health/livness or something).
Add actuator dependency in pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
HTTP Probes are only configured for applications running on Kubernetes. You can give it a try locally by manually enabling the probes with the management.health.probes.enabled=true configuration property
You can check the liveness and readiness by curl or using postman to hit below endpoints
// http://localhost:8080/actuator/health/liveness
// HTTP/1.1 200 OK
{
"status": "UP",
"components": {
"livenessProbe": {
"status": "UP"
}
}
}
// http://localhost:8080/actuator/health/readiness
// HTTP/1.1 503 SERVICE UNAVAILABLE
{
"status": "OUT_OF_SERVICE",
"components": {
"readinessProbe": {
"status": "OUT_OF_SERVICE"
}
}
}
You can of course configure additional Health Indicators to be part of the Probes, checking for the state of external systems: a database, a Web API, a shared cache.
management.endpoint.health.group.liveness.include=livenessProbe,customCheck
Related
I am trying to expose additional actuator endpoints in my Spring Boot 2.3 service. Attempting to add endpoints such as the prometheus and metrics for monitoring. But for some reason, the exposed endpoints are locked to the default loggers,health,info.
For some background, within the org, there is a parent Spring dependency which automatically brings all of the Spring essentials, as well as some generic code useful within the org. I use this dependency in many of my other projects and was able to expose these additional actuator endpoints successfully. However, in this project with multiple artifacts, I am unable to edit the default exposed actuator endpoints.
Printing the configurableEnvironment post init always shows the exposure property as follows
management.endpoints.web.exposure.include = loggers,health,info
This is after trying to override this property to an expanded list (loggers,health,info,Prometheus,metrics) using below methods:
Enabling specific endpoint via management.endpoint.metrics.enabled: true
Specifying these values in application.yaml
Passing this as a Command line arguement Dmanagement.endpoints.web.exposure.include=loggers,health,info,prometheus,metrics
Using mvn dependency:tree To exclude any transitive actuator dependencies
I don’t believe its due to the org’s parent pom, likely due to another dependency we are using. But due to the size of this project, it is quite hard to remove dependencies to test. Is there any way to track down where these properties are set. Or perhaps additional ways to force exposure of the additional endpoints I want?
——
Actuator config
management:
endpoints:
web:
exposure:
include: metrics,prometheus,info,health,logging
endpoint:
env:
enabled: true
metrics:
enabled: true
info:
enabled: true
health:
enabled: true
show-details: always
beans:
enabled: true
caches:
enabled: true
threaddump:
enabled: true
prometheus:
enabled: true
Actuator info
{"_links":{"self":{"href":"http://localhost:9050/actuator","templated":false},"health":{"href":"http://localhost:9050/actuator/health","templated":false},"health-path":{"href":"http://localhost:9050/actuator/health/{*path}","templated":true},"info":{"href":"http://localhost:9050/actuator/info","templated":false},"loggers":{"href":"http://localhost:9050/actuator/loggers","templated":false},"loggers-name":{"href":"http://localhost:9050/actuator/loggers/{name}","templated":true}}}
Your question lacks some background, like your pom.xml or build.gradle files and full application.yml config.
I will go through the basic steps, which you may have missed.
Firstly, please make sure that you've included the Prometheus dependency:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
Also, don't forget that some metrics require the AOP dependency (like custome timers, for example):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
To enable the Prometheus metrics exposure, you should specify such configuration in your application.yml file (it seems like you did it correctly, but let's list it here for the full picture):
management:
endpoints:
web.exposure.include: health, info, prometheus
To verify that the Prometheus endpoints were exposed, please use the GET request to this URL: http://localhost:8080/actuator/prometheus
If those steps don't help you resolve your issue, please add more details to your question.
I have a microservice based on spring boot. I have a spring cloud configserver as well in-place. So depending upon the changes in the configserver microservice restart automatically.
So now i need to grab the timestamp when the application got restarted.
Is it possible to do so in the same microservice?
You can listen to spring events such as the ContextStartedEvent. There's a tutorial here that lays it out:
#EventListener
public void handleContextStartedEvent(ContextStartedEvent ctxStartEvt) {
System.out.println("Context Start Event received.");
}
yes, possible by adding the actuator and enabling the startup endpoint.
step1: Add the below dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.5.4</version>
</dependency>
step2: Add the below property into the application.properties files.
management.endpoints.web.exposure.include=startup
step3: Setup a little amount of buffer memory to store the startup info and it won't affect the performance at anywhere in your application.
#SpringBootApplication
public class StartupTrackingApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(StartupTrackingApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(2048));
app.run(args);
}
}
step: Hit the below URL using CURL like below or a POST call from POSTMAN. Then you will be seeing all startup-related info like when the startup started and ended. e.t.c.
curl 'http://localhost:8080/actuator/startup' -X POST | jq
For more explanation, view reference
In the response json, node "timeline"."startTime" is the exact startup timestamp when the applicant has started its startup job.
I am trying to add a shutdown endpoint actuator/shutdown in my Spring application as explained in this tutorial so that I can gracefully shutdown the application using a call like curl -X POST localhost:8080/actuator/shutdown.
I added
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
to my pom.xml and
management:
endpoints.web.exposure.include: *
endpoint.shutdown.enabled: true
endpoints.shutdown.enabled: true
management.endpoint.shutdown.enabled: true
to src/main/resources/application.yaml.
But when I run curl -X POST localhost:8080/actuator/shutdown, I get the following response:
{"timestamp":"2020-04-10T10:49:36.758+0000","status":404,"error":"Not Found",
"message":"No message available","path":"/actuator/shutdown"}
I don't see the shutdown endpoint at http://localhost:8080/actuator:
What am I doing wrong? What do I need to change in order for the actuator/shutdown endpoint to appear?
It appears you are using yaml, * has a special meaning in yaml and must be quoted.
The following should work
management:
endpoint:
shutdown:
enabled: true
endpoints:
web:
exposure:
include: "*"
That may be, because of Spring/Actuator version, that you are using, Endpoints have changed quite a bit in Spring Boot 2.0 and, as a result, your configuration is out of date.
Try next:
management.endpoints.web.expose=*
management.endpoint.shutdown.enabled=true
OR
management.endpoints.web.exposure.include=shutdown
management.endpoint.shutdown.enabled=true
You can check more about changes in Spring Boot 2.0 in release notes.
I'm in the midst of migrating a project from Spring Boot 1.X to Spring Boot 2.X. The only thing that's left and that's giving me trouble is the Spring Boot Actuator.
In Spring Boot 1.X when you hit the /health endpoint with credentials, you would normally receive a more detailed list of indicators, like for example the result of the default org.springframework.boot.actuate.health.DiskSpaceHealthIndicator.
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 1000240963584,
"free": 909162590208,
"threshold": 10485760
}
}
I would also see custom defined Health indicators here as well.
Now that I use the newer version of the Actuator library, I no longer receive that additional information (when providing credentials). All I see is:
{
"status": "UP"
}
At first I thought that maybe I haven't set up the credentials properly, but by intentionally providing invalid credentials I get 401 Unauthorized. So it can't be the authentication.
I digged in a little deeper with the debugger and saw that the DiskSpaceHealthIndicator bean actually gets created, along with all my other custom defined indicators. But it seems like they do not get registered by Spring Boot for me to not see them when hitting the /health endpoint.
Any suggestions?
The issue was fixed by adding:
management.endpoint.health.show-details=when_authorized
as #ValentinCarnu suggested.
And this is what I found afterwards in the documentation: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-health
The default value is never. A user is considered to be authorized when they are in one or more of the endpoint’s roles. If the endpoint has no configured roles (the default) all authenticated users are considered to be authorized. The roles can be configured using the management.endpoint.health.roles property.
Thanks!
Don't use this URL http://localhost:8080/env
Instead use http://localhost:8080/actuator/env
And set the Application.properties with the following
management.security.enabled=false
management.endpoints.web.exposure.include=*
Worked for Me
I'm having difficulty with authentication when accessing Google Cloud Storage from within an appengine web app. I want to use the Application Default Credentials. Maybe someone can advise me.
I have a project, with service account: "x#appspot.gserviceaccount.com".
In section IAM the project has only member, y#gmail.com (which is my email address), with role Owner.
In the project I have two Cloud Storage buckets, staging.x.appspot.com and x.appspot.com. I haven't edited their permissions.
In the project I have an appengine web app written in Java. From its code, I want to access Cloud Storage like this:
import com.google.cloud.AuthCredentials;
import com.google.cloud.storage.Storage;
AuthCredentials credentials=AuthCredentials.createApplicationDefaults();
Storage storage=StorageOptions.builder().authCredentials(credentials).build().service();
with maven dependencies
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.9.38</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-appengine</artifactId>
<version>0.4.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>gcloud-java</artifactId>
<version>0.2.3</version>
</dependency>
I start the development server with
mvn clean appengine:devserver
and deploy with
mvn clean appengine:update
I would have thought that is enough.
But in devserver on one computer it works, on another computer I get exception "401 Invalid authentication" or something like that. I don't know what the difference between the computers is.
In the deployed app I get exception 403 Forbidden.
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Forbidden",
"reason" : "forbidden"
} ],
"message" : "Forbidden"
}
What am I doing wrong?
As Brandon and Nick said, gcloud auth login with the google user that is the owner (so not the service account) did the trick. Thanks for your help.