Add configuration to set href base-path in WebMvcEndpointHandlerMapping Actuator links
See original GitHub issueIf you run a spring-boot
application inside a docker container on context root, the actuator endpoint is exposed at: localhost:8080/actuator
. (assuming the docker container runs on 8080).
Spring generated the base url for the actuator links by request.getRequestURL()
. And as inside a docker container, this is also always the context root:
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"auditevents": {
"href": "http://localhost:8080/actuator/auditevents",
"templated": false
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
},
....
Problem: when you’re behind a loadbalancer or a simple apache2 reverse proxy, you may face situations where the actuator endpoint must be “rewritten”. If you run multiple applications on a host, you often have a subpath mapping as follows (in this case apache2, but it does not matter):
ProxyPass https://yourhost/api1 http://localhost:8080
ProxyPassReverse https://yourhost/api1 http://localhost:8080
ProxyPass https://yourhost/api2 http://localhost:8081
ProxyPassReverse https://yourhost/api2 http://localhost:8081
This way, clients can connect via SSL without opening extra ports, and forward them to the desired docker app.
Problem: request.getRequestURL()
only sees the forwarded request, not the original request.
As a result, health endpoints always result in https://yourhost/actuator
or https://yourhost/actuator/health
, which thus never reach the desired actuator endpoint (as the subpath mapping for apache2 is missing).
It should thus be possible to set the base-path for the actuator endpoint href links explicit via configuration, but without changing the actual path on which the actuator endpoint is accessed (it should still be exposed under the /actuator root context).
org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.class
:
class WebMvcLinksHandler implements LinksHandler {
@Override
@ResponseBody
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(request.getRequestURL().toString()));
}
}
I know there is management.endpoints.web.base-path
, but this actually changes also the path where the actuator is exposed.
I’m looking for a way that only changes the base path that is used to generate the links, but keeps the actuator at default path.
Issue Analytics
- State:
- Created a year ago
- Comments:9 (5 by maintainers)
This is really a proxy issue. You could address this limitation with a Servlet filter, but I strongly suggest to try and solve this problem at the proxy level as it should.
There’s not way to use
ForwardedHeaderFilter
and not remove the headers. The source code for the filter is here.