Why is the shutdown endpoint not enabled in my application? - java

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.

Related

Spring Boot Actuators only exposing limited endpoints

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.

Actuator endpoints returns "circuitBreakers":{"status":"UNKNOWN"} despite management.health.circuitbreakers.enabled: true

I have a Spring Boot 2.6.0-M1 project with Jubilee (But issue can be reproduced since 2.4).
In my project, I am using Actuator, Spring cloud Kubernetes, and Resilience4J (not Spring Cloud Circuit breaker)
Very happy about this combination. Resilience4J is working fine, the circuit breaker goes into open states etc. Kubernetes detect the config maps, etc... Very happy.
However, on a actuator health endpoint, I am seeing this :
"circuitBreakers":{"status":"UNKNOWN"}
And checked my configuration, management.health.circuitbreakers.enabled: true
How do I get the correct status, and not this "UNKNOWN" please?
Thank you
In order to use actuator along with resilience 4j please use the configuration mentioned below.
Make sure to add your service name and it works perfectly.
resilience4j.retry.instances.customerService.max-attempts: 3
resilience4j.retry.instances.customerService.wait-duration: 5s
management.endpoint.health.show-details: "ALWAYS"
management.health.circuitbreakers.enabled: false
management.health.ratelimiters.enabled: true
resilience4j.circuitbreaker.configs.default.registerHealthIndicator: true
circuitreaker showing status unknown because you are missing one of the required properties in application.properties file.
you should add below property
resilience4j.circuitbreaker.instances.{App Name}.registerHealthIndicator = true
Also check below properties:
management.endpoint.health.show-details: "ALWAYS"
management.health.circuitbreakers.enabled: false
management.health.ratelimiters.enabled: true
resilience4j.circuitbreaker.configs.default.registerHealthIndicator: true

How to implement liveness/readines using springboot 2.3.0

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

Spring actuator endpoints does not work on the application port

I am trying to enable the actuator endpoints on the same port as the application port (specified in the application.properties file by the server.port=8080) but for some reason, it does not work. When I run the application, I can get back the response from the application but not from the actuator endpoints. I can see the logs mention the endpoints being exposed beneath base path '/actuator' as shown in the screenshot below. But when I try to hit the actuator URL, it gives a 404.
URL, not working:
http://localhost:8080/actuator
http://localhost:8080/actuator/health
http://localhost:8080/actuator/info
However, if I specify a separate port in application.properties for the actuator endpoints with the property (management.server.port=9000) then it works fine.
URL, that's working:
http://localhost:9000/actuator
http://localhost:9000/actuator/health
http://localhost:9000/actuator/info
The only difference is about the port number but from what I read in the spring documentation, the actuator endpoints should by default be enabled on the application port if we don't specify the management.server.port.
Can someone please explain what am I missing here?
PS: The application run logs are exactly the same with or without specifying the management.server.port, hence, this one screenshot is without specifying the management port.
Also, I tried giving the same port number for both the property (server.port and management.server.port) but the same problem occurs. The application works on that port but the actuator endpoints do not.
I am using the spring-boot version 2.0.6
These are the contents of my application.properties file:
camel.springboot.main-run-controller=true
camel.springboot.name=AppName
camel.rest.data-format-property.prettyPrint=false
camel.component.servlet.mapping.context-path=/*
server.port=8080
management.server.port=9000
management.endpoint.health.show-details=always
management.endpoint.beans.enabled=true
logging.level.org.springframework = INFO
logging.level.org.apache.camel.spring.boot = INFO
logging.level.org.apache.camel.impl = DEBUG
Here are the dependencies in pom.xml:
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-servlet-starter</artifactId>
</dependency>
</dependencies>
Regarding the Spring Boot Actuator documentation
Exposing management endpoints by using the default HTTP port is a
sensible choice for cloud-based deployments. If, however, your
application runs inside your own data center, you may prefer to expose
endpoints by using a different HTTP port.
it serves the Actuator using the default HTTP port (which is 8080). I did a quick check and could confirm this with Spring Boot 2.1.X and 2.2.X.
Try to remove the management.port from your config and if this does not work then the problem might come from an additional (custom) configuration in your application.
Remove management.server.port=9000, this property overrides server.port=8080.
Please set the below in application.properties file
management.endpoints.enabled-by-default=true
management.endpoints.web.exposure.include=*
I had the same problem, what was causing this for me was a conflict between the context I declared for camel and the one being used for spring actuator.
So, at application.yml I had these 3 contexts:
server: servlet: context-path: myservercontext/v1
camel: component: servlet: mapping: contextPath: /*
management: endpoints: web: base-path: "/"
I think after the request hits the server it gets lost on this ambiguity so i solved it by changing these contexts to:
server: servlet: context-path: myservercontext/v1
camel: component: servlet: mapping: contextPath: /camel/*
management: endpoints: web: base-path: "/"
This worked out nicely for me since all my resources where grouped under "/camel" anyway but as I tested I found out this also works:
server: servlet: context-path: myservercontext
camel: component: servlet: mapping: contextPath: /v1/*
management: endpoints: web: base-path: "/"
Just note that in this last scenario the health route won't be under "v1".
I would never have figured out the cause of this problem if it wasn't for this question, even if it wasn't solved yet, so I thank you a lot for posting this and hope my solution will manage to help others ^^

Spring Boot Actuator /health endpoint does not show database or file system information

I cannot get database information or filesystem information to show up on the /health endpoint. I only can get:
{
"status": "UP"
}
Details about my setup and configuration:
- Spring Boot 1.3.3
- Running the WAR on JBoss EAP 6.4
- Datasource is a JNDI resource.
- Oracle is the database
spring:
datasource:
# Must match the datasource name in JBoss standalone.xml
jndi-name: java:jboss/beautiful-ds
driver-class-name: oracle.jdbc.driver.OracleDriver
jpa:
properties:
# escapes reserved words used as column names (if any)
globally_quoted_identifiers: true
show-sql: true
hibernate:
naming_strategy: org.hibernate.cfg.EJB3NamingStrategy
server:
servlet-path: /*
management:
health:
diskspace:
enabled: true
db:
enabled: true
endpoints.health.sensitive: false
One thing i found on /configprops is this, which I'm not sure whether it is related:
"spring.datasource.CONFIGURATION_PROPERTIES": {
"prefix": "spring.datasource",
"properties": {
"error": "Cannot serialize 'spring.datasource'"
}
I had tried adding "driver-class-name: oracle.jdbc.driver.OracleDriver" thinking it maybe needed more details, but that didn't change the situation.
so yeah, what gives? I made a vanilla example project which at least shows the filesystem stuff out the gate, so not sure why either don't want to show in my "real" app. Tell me your great and wise answers! :)
By default Spring sets the below property to never.
To be able to see full health details add the below property to your application.properties.
management.endpoint.health.show-details=always
From the spring-boot documentation:
45.6 Security with HealthIndicators
Information returned by HealthIndicators is often somewhat sensitive in nature. For example,
you probably don’t want to publish details of your database server to
the world. For this reason, by default, only the health status is
exposed over an unauthenticated HTTP connection. If you are happy for
complete health information to always be exposed you can set
endpoints.health.sensitive to false. Health responses are also cached
to prevent “denial of service” attacks. Use the
endpoints.health.time-to-live property if you want to change the
default cache period of 1000 milliseconds.
Make sure to have following properties set.
endpoints.health.sensitive=true # Mark if the endpoint exposes sensitive information.
management.health.db.enabled=true # Enable database health check.
management.health.defaults.enabled=true # Enable default health indicators.
management.health.diskspace.enabled=true # Enable disk space health check.
In cases if you are using spring security, then by default security is enabled for actuator endpoints, disable it in your yml file -
management:
security:
enabled: false
IIUC, the aggregate health is shown under /health, at least (IIUC) for springboot2. Meaning, that even if you have everything configured just right, only one line will be shown.
UPDATE: and if this is not what you need, you have to specifically ask to see details. Check these settings:
management.endpoint.health.show-details=when-authorized
management.endpoint.health.roles=ADMIN
You mixed YAML and Properties syntax in your configuration file. Replace the last line by the following, and it should work:
endpoints:
health:
sensitive: false

Categories

Resources