https://bz.apache.org/bugzilla/show_bug.cgi?id=60632

            Bug ID: 60632
           Summary: Last logs lost when running Tomcat with systemd and
                    journald
           Product: Tomcat 8
           Version: 8.5.x-trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: j...@redradishtech.com
  Target Milestone: ----

Many people run Tomcat from systemd, and will be using 'journalctl' to manage
Tomcat's stdout. journalctl has a not-easily-fixed bug that causes the last few
stdout/stderr lines to be 'lost'. This is a problem, as the last few lines are
usually the most important. Here I suggest a small workaround in
bin/catalina.sh that I feel would be safe and worthwhile.

A simple example: let's deploy a Tomcat instance running as a dedicated user:

# useradd -s /bin/bash -d /tmp testtomcat
# su - testtomcat
curl -sLO
http://www-us.apache.org/dist/tomcat/tomcat-8/v8.5.11/bin/apache-tomcat-8.5.11.tar.gz
tar xf apache-tomcat-8.5.11.tar.gz
cd apache-tomcat-8.5.11

If we run 'bin/catalina.sh run' it starts normally.

testtomcat@jturner-desktop:~/apache-tomcat-8.5.11$ ./bin/catalina.sh run
Using CATALINA_BASE:   /tmp/apache-tomcat-8.5.11
Using CATALINA_HOME:   /tmp/apache-tomcat-8.5.11
Using CATALINA_TMPDIR: /tmp/apache-tomcat-8.5.11/temp
Using JRE_HOME:        /usr/lib/jvm/java-8-oracle
Using CLASSPATH:      
/tmp/apache-tomcat-8.5.11/bin/bootstrap.jar:/tmp/apache-tomcat-8.5.11/bin/tomcat-juli.jar
...

Let's introduce an error. Say we got JAVA_HOME wrong. We get an error message
as expected:

testtomcat@jturner-desktop:~/apache-tomcat-8.5.11$ JAVA_HOME=/incorrect/path
./bin/catalina.sh run
Using CATALINA_BASE:   /tmp/apache-tomcat-8.5.11
Using CATALINA_HOME:   /tmp/apache-tomcat-8.5.11
Using CATALINA_TMPDIR: /tmp/apache-tomcat-8.5.11/temp
Using JRE_HOME:        /incorrect/path
Using CLASSPATH:      
/tmp/apache-tomcat-8.5.11/bin/bootstrap.jar:/tmp/apache-tomcat-8.5.11/bin/tomcat-juli.jar
./bin/catalina.sh: 1: exec: /incorrect/path/bin/java: not found
testtomcat@jturner-desktop:~/apache-tomcat-8.5.11$ 

All find and dandy.

Now let's run Tomcat via systemd. Create a minimal service file as root and
load it:

# cat > /etc/systemd/system/testtomcat.service <<EOF
[Service]
Type=simple
User=testtomcat
ExecStart=/tmp/apache-tomcat-8.5.11/bin/catalina.sh run
EOF
# systemctl daemon-reload

(an aside: see https://jdebp.eu/FGA/systemd-house-of-horror/tomcat.html for why
we call catalina.sh run from systemd instead of startup.sh) 

Start it, and see the status:

# systemctl start testtomcat
# systemctl status testtomcat -n5
● testtomcat.service
   Loaded: loaded (/etc/systemd/system/testtomcat.service; static; vendor
preset: enabled)
   Active: active (running) since Tue 2017-01-24 12:43:18 AEDT; 47s ago
 Main PID: 30648 (java)
    Tasks: 33
   Memory: 109.2M
      CPU: 3.979s
   CGroup: /system.slice/testtomcat.service
           └─30648 /usr/bin/java
-Djava.util.logging.config.file=/tmp/apache-tomcat-8.5.11/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2

Jan 24 12:43:20 jturner-desktop catalina.sh[30648]: 24-Jan-2017 12:43:20.173
INFO [localhost-startStop-1]
org.apache.catalina.startup.HostConfig.deployDirectory Deploying web
application directory /tmp/apache-to
Jan 24 12:43:20 jturner-desktop catalina.sh[30648]: 24-Jan-2017 12:43:20.182
INFO [localhost-startStop-1]
org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web
application directory /tmp/apach
Jan 24 12:43:20 jturner-desktop catalina.sh[30648]: 24-Jan-2017 12:43:20.184
INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler
[http-nio-8180]
Jan 24 12:43:20 jturner-desktop catalina.sh[30648]: 24-Jan-2017 12:43:20.187
INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler
[ajp-nio-8109]
Jan 24 12:43:20 jturner-desktop catalina.sh[30648]: 24-Jan-2017 12:43:20.188
INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 649 ms


Happiness. All working normally.

Now let's introduce an error. Any error that prevents Tomcat startup will do
(e.g. incorrect permissions), but let's go with our invalid JAVA_HOME example:

cat > /etc/systemd/system/testtomcat.service <<EOF
[Service]
Type=simple
User=testtomcat
Environment=JAVA_HOME=/incorrect/path
ExecStart=/tmp/apache-tomcat-8.5.11/bin/catalina.sh run
EOF
# systemctl daemon-reload
# systemctl restart testtomcat
# systemctl status testtomcat -n5
● testtomcat.service
   Loaded: loaded (/etc/systemd/system/testtomcat.service; static; vendor
preset: enabled)
   Active: failed (Result: exit-code) since Tue 2017-01-24 12:44:40 AEDT; 6s
ago
  Process: 30846 ExecStart=/tmp/apache-tomcat-8.5.11/bin/catalina.sh run
(code=exited, status=127)
 Main PID: 30846 (code=exited, status=127)

Jan 24 12:44:40 jturner-desktop systemd[1]: Started testtomcat.service.
Jan 24 12:44:40 jturner-desktop systemd[1]: testtomcat.service: Main process
exited, code=exited, status=127/n/a
Jan 24 12:44:40 jturner-desktop systemd[1]: testtomcat.service: Unit entered
failed state.
Jan 24 12:44:40 jturner-desktop systemd[1]: testtomcat.service: Failed with
result 'exit-code'.


Unhappiness, as expected, but note one important detail: the actual error
"./bin/catalina.sh: 1: exec: /incorrect/path/bin/java: not found" is missing in
the logs.

Again, the above is just an example. The last log message from ANY failure,
generated by scripts or Tomcat itself, will be lost.

Here's what's going on. The logs are not actually 'lost', but just not "tagged"
as belonging to the testtomcat unit (i.e. you can see them if you 'journalctl
-f' before start). This is due to a systemd bug marked cant-fix:

https://github.com/systemd/systemd/issues/1347

which I was referred to when questioning this behaviour on stackoverflow:

https://superuser.com/questions/1169906/systemd-bug-stdout-not-tagged-as-belonging-to-unit-when-non-root-user-specifie

The systemd bug isn't going to be fixed soon, as it relies on kernel additions.

Here's what Tomcat can do. A simple workaround is to 'sleep' for a short period
after emitting our last output, to give systemd a chance to tag it. Put this
near the top of bin/catalina.sh:

# If running in systemd, give it a chance to tag the last output.
https://github.com/systemd/systemd/issues/1347
trap 'sleep 0.1' INT TERM EXIT

and now when we 'systemctl status testtomcat' (or 'journalctl -u testtomcat')
we see the final error message:

# systemctl restart testtomcat
# systemctl status testtomcat
● testtomcat.service
   Loaded: loaded (/etc/systemd/system/testtomcat.service; static; vendor
preset: enabled)
   Active: failed (Result: exit-code) since Tue 2017-01-24 12:58:39 AEDT; 6s
ago
  Process: 32326 ExecStart=/tmp/apache-tomcat-8.5.11/bin/catalina.sh run
(code=exited, status=127)
 Main PID: 32326 (code=exited, status=127)

Jan 24 12:58:39 jturner-desktop systemd[1]: Started testtomcat.service.
Jan 24 12:58:39 jturner-desktop catalina.sh[32326]:
/tmp/apache-tomcat-8.5.11/bin/catalina.sh: 1: exec: /incorrect/path/bin/java:
not found
Jan 24 12:58:39 jturner-desktop systemd[1]: testtomcat.service: Main process
exited, code=exited, status=127/n/a
Jan 24 12:58:39 jturner-desktop systemd[1]: testtomcat.service: Unit entered
failed state.
Jan 24 12:58:39 jturner-desktop systemd[1]: testtomcat.service: Failed with
result 'exit-code'.

I'm not a POSIX guru but AFAIK 'trap' and '/bin/sleep' are pretty vanilla. The
choice of a 0.1s delay is not very scientific. It fixes the problem on my
system.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to