/dev/stdout 权限被拒绝 Tomcat 访问日志
/dev/stdout permission denied Tomcat access logs
我正在尝试在 STS 控制台中启用 Tomcat 访问日志,但我在启动时遇到错误:
java.io.FileNotFoundException: /dev/stdout.2020-09-02 (Permission denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at org.apache.catalina.valves.AccessLogValve.open(AccessLogValve.java:585)
at org.apache.catalina.valves.AccessLogValve.startInternal(AccessLogValve.java:615)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:182)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:953)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:793)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:344)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:99)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:84)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:552)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:177)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1187)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1176)
at au.com.paycorp.rest.ws.Application.main(Application.java:29)
application.yml :
server:
port: 50110
contextPath: /rest
tomcat:
accesslog:
enabled: true
directory: "/dev"
prefix: stdout
buffered: false
suffix:
file-date-format:
pattern: "[ACCESS] %{org.apache.catalina.AccessLog.RemoteAddr}r %l %t %D %F %B %S vcap_request_id:%{X-Vcap-Request-Id}i"
我知道它没有写入权限 /dev/stdout,但我不确定如何将它列入白名单,如何授予它访问权限。
我会说你的问题不在你的代码中,而是在你的服务器上。
显然,它是 Linux 或 Unix。因此,使用 chmod 命令更改您的用户可以在此文件夹上执行的操作。
通过以下方式将 dev 文件夹的所有权授予当前用户:
sudo chown -R $USER dev/
使用此命令将文件夹的组所有者更改为当前用户:
sudo chgrp -R $USER dev/
这应该可以解决问题。
如您所见,Tomcat 正在尝试打开文件 /dev/stdout.2020-09-02
而不是 /dev/stdout
。这背后的原因是空 file-data-format
意味着 default format for your locale。如果您想禁用在文件名中添加日期,您需要使用:
rotatable: false
另一方面,这会将您的日志重定向到标准输出,具体取决于标准输出是否为文件:Java 不会复制文件描述符 1
,而是调用 open
在 /dev/stdout
上。检查 this answer 以了解为什么它在 pipes/sockets.
上不起作用
要实现您想要的效果,您需要修改方法 AccessLogValve#open
:
protected synchronized void open() {
// Open the current log file
// If no rotate - no need for dateStamp in fileName
File pathname = getLogFile(rotatable && !renameOnRotate);
// Modify HERE:
if ("-".equals(pathname)) {
writer = System.out;
return;
}
...
}
并将 -
设置为日志文件的名称。
我正在尝试在 STS 控制台中启用 Tomcat 访问日志,但我在启动时遇到错误:
java.io.FileNotFoundException: /dev/stdout.2020-09-02 (Permission denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at org.apache.catalina.valves.AccessLogValve.open(AccessLogValve.java:585)
at org.apache.catalina.valves.AccessLogValve.startInternal(AccessLogValve.java:615)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:182)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:953)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:793)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:344)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:99)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:84)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:552)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:177)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1187)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1176)
at au.com.paycorp.rest.ws.Application.main(Application.java:29)
application.yml :
server:
port: 50110
contextPath: /rest
tomcat:
accesslog:
enabled: true
directory: "/dev"
prefix: stdout
buffered: false
suffix:
file-date-format:
pattern: "[ACCESS] %{org.apache.catalina.AccessLog.RemoteAddr}r %l %t %D %F %B %S vcap_request_id:%{X-Vcap-Request-Id}i"
我知道它没有写入权限 /dev/stdout,但我不确定如何将它列入白名单,如何授予它访问权限。
我会说你的问题不在你的代码中,而是在你的服务器上。
显然,它是 Linux 或 Unix。因此,使用 chmod 命令更改您的用户可以在此文件夹上执行的操作。
通过以下方式将 dev 文件夹的所有权授予当前用户:
sudo chown -R $USER dev/
使用此命令将文件夹的组所有者更改为当前用户:
sudo chgrp -R $USER dev/
这应该可以解决问题。
如您所见,Tomcat 正在尝试打开文件 /dev/stdout.2020-09-02
而不是 /dev/stdout
。这背后的原因是空 file-data-format
意味着 default format for your locale。如果您想禁用在文件名中添加日期,您需要使用:
rotatable: false
另一方面,这会将您的日志重定向到标准输出,具体取决于标准输出是否为文件:Java 不会复制文件描述符 1
,而是调用 open
在 /dev/stdout
上。检查 this answer 以了解为什么它在 pipes/sockets.
要实现您想要的效果,您需要修改方法 AccessLogValve#open
:
protected synchronized void open() {
// Open the current log file
// If no rotate - no need for dateStamp in fileName
File pathname = getLogFile(rotatable && !renameOnRotate);
// Modify HERE:
if ("-".equals(pathname)) {
writer = System.out;
return;
}
...
}
并将 -
设置为日志文件的名称。