2

I'm trying to enable Tomcat access logs in the STS console, but i get an error on startup:

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"

I understand that it does not have the permission to write to /dev/stdout, but i'm not sure how to whitelist it, how to give it permission for access.

isotronic
  • 47
  • 6

3 Answers3

1

I would say that you issue is not in your code but on your server.

Obviously, it's Linux or Unix. So, use a chmod command to change what your user can do on this folder.

BenjaminD
  • 488
  • 3
  • 13
0

Give ownership of the dev folder to the current user with:

sudo chown -R $USER dev/

Change the group owner of the folder to the current user using this command:

sudo chgrp -R $USER dev/

This should fix it.

Abdulah Pehlic
  • 171
  • 1
  • 10
  • 1
    I really wouldn't do that since the `/dev` folder contains special devices and one wouldn't want Tomcat to be able to create and delete files here. Besides the error statement says that Tomcat tried to create `/dev/stdout.2020-09-02`, which is not the standard output device. – Piotr P. Karwasz Feb 06 '21 at 07:05
  • This isn't `dev/`, it's `/dev`, and no one should mess with `/dev`. – Dalibor Filus Dec 03 '22 at 08:30
0

As you can see, Tomcat is trying to open the file /dev/stdout.2020-09-02 instead of /dev/stdout. The reason behind this is that an empty file-data-format means default format for your locale. If you want to disable the addition of a date in the filename you need to use:

rotatable: false

On the other hand this will redirect your logs to the standard output depending on whether the standard output is a file or not: Java does not duplicate the file descriptor 1, but calls open on /dev/stdout. Check this answer to understand why it won't work on pipes/sockets.

To achieve what you want you'll need to modify the method 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;
        }
        ...
    }

and set - as the name of your logfile.

Piotr P. Karwasz
  • 12,857
  • 3
  • 20
  • 43