- We need to change the actuator endpoints to be on a different port number (To serve the Kubernetes probes)
- We also need the logs from the Actuator to go to
stdout
- Changing the value of
management.server.port: 8404
causes an exception as the server configures the new port to stream logs to/dev/management_stdout
when it should be/dev/stdout
(already configured for the server, as shown in theQuestion
section below)
SpringBoot Setup
buildscript {
repositories {
mavenCentral()
// For src/gradle/tests.gradle
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.3.5.RELEASE")
}
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-actuator')
}
Changing SpringBoot Actuator
- Changed the port number as follows in
application.yaml
management:
endpoints:
web:
exposure:
include: "*"
server:
port: 8404
Error shown during bootstrap
- The default logger is trying to write to
/dev/management_stdout
2020-11-15T17:23:41 ERROR [app=parking-plus-service,prf=default][tid=,sid=,sxp=][cid=] 77926 ---
[ restartedMain] o.apache.catalina.valves.AccessLogValve :
Failed to open access log file [/dev/management_stdout]
java.io.FileNotFoundException: /dev/management_stdout (Operation not permitted)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
at org.apache.catalina.valves.AccessLogValve.open(AccessLogValve.java:651)
at org.apache.catalina.valves.AccessLogValve.startInternal(AccessLogValve.java:685)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:176)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:933)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:440)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:193)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:158)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration$DifferentManagementContextConfiguration.onApplicationEvent(ManagementContextAutoConfiguration.java:142)
at org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration$DifferentManagementContextConfiguration.onApplicationEvent(ManagementContextAutoConfiguration.java:114)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361)
at org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle.start(WebServerStartStopLifecycle.java:46)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at cash.super_.platform.service.ParkingPlusApplication.main(ParkingPlusApplication.java:12)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Question
- Which property sets the file name prefix
stdout
just like on the server settings shown below? - Maybe the management embedded tomcat is taking the value of
directory
and using the prefix asmanagement_stdout
as the value of the file?
server:
#port: 8080 default
tomcat:
accesslog:
enabled: true
directory: /dev
prefix: stdout
buffered: false
suffix:
file-date-format:
Comment From: wilkinsona
When you configure a separate management port, you end up with two embedded Tomcat instances. There's one instance for your application and one for the actuator. When accessing logging is enabled, to avoid the two Tomcat instances writing their access logs to the same location, the management server prefixes its location with management_
.
https://github.com/spring-projects/spring-boot/issues/14948 is tracking making this management-specific prefix customisable. It also suggests a workaround that you could use in the interim.
Comment From: marcellodesales
@wilkinsona Thanks a lot for clarifying it!!!