Search code examples
dockerlagom

How to write logs to a file in a lagom application


As part of deploying my lagom application to the kubernetes production environment, I am trying to publish all my logs to a file besides writing to the standard output. For this I created a logback.xml under resources directory adding file appender as per suggestion here.

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${application.home:-.}/logs/application.log</file>
    <encoder>
        <pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
    </encoder>
</appender>

But it is failing to create a log file in the container working directory. I get following error instead:

09:23:33,209 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNCSTDOUT] - Setting discardingThreshold to 51
09:23:33,209 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.FileAppender]
09:23:33,213 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE]
09:23:33,217 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
09:23:33,220 |-INFO in ch.qos.logback.core.FileAppender[FILE] - File property is set to [./logs/application.log]
09:23:33,222 |-ERROR in ch.qos.logback.core.FileAppender[FILE] - Failed to create parent directories for [/opt/docker/./logs/application.log]
09:23:33,222 |-ERROR in ch.qos.logback.core.FileAppender[FILE] - openFile(./logs/application.log,true) call failed. java.io.FileNotFoundException: ./logs/application.log (No such file or directory)
    at java.io.FileNotFoundException: ./logs/application.log (No such file or directory)
    at  at java.io.FileOutputStream.open0(Native Method)

I am not really sure why is it failing to create the log directory and the log file under container working directory.

demiourgos728@ca5fc4a4c1db:/opt/docker$ ls
bin  lib  share

I tried providing the read, write, execute permission on the container working directory as shown below but that didn't work either:

DockerChmodType.UserGroupWriteExecute

Please suggest.

  • Docker base images conf: dockerBaseImage := "adoptopenjdk/openjdk8".
  • Whole log file here.
  • K8S definitions

Solution

  • Writing to a file in a container is bad for two reasons: 1. Logs are available only within the container i.e.,would require to get into the container to see the logs 2. They are not available via kubectl log command 3. They are ephemeral in nature i.e., if container crashes, logs will disappear

    Instead writing to STDOUT and STDERR is considered as best practise in a container environment. The logs written to STDOUT and STDERR are redirected by docker engine to a location in the node (/var/log/containers/). Moreover, these logs are also available via kubectl logs command.

    Practically logs are not even preserved at even a node but are instead moved to a central logging system. You can read more about it here.