Skip to content

Commit

Permalink
Emit Tomcat HTTP logs to stdout from Docker
Browse files Browse the repository at this point in the history
Tomcat emits its own startup and shutdown logs by default, but also
emits HTTP access logs to logs/localhost_access_log.YYYY-MM-DD.txt. This
dynamically rewrites the conf/server.xml file to emit the HTTP logs to
standard output instead.

As mentioned in the update-tomcat-logging-config.sh comment, this
configuration was inspired by:

- https://stackoverflow.com/a/62598943

Got the Perl implementation hint from:

- https://unix.stackexchange.com/a/26289
- https://unix.stackexchange.com/a/181215

Also updates the Dockerfile FROM from tomcat:10.1.16-jdk21-temurin-jammy
to tomcat:10.1.16-jre21-temurin-jammy. The former was 211.56 MB
compressed/454MB uncompressed, the latter 111.28 MB compressed/310MB
uncompressed.

- https://hub.docker.com/layers/library/tomcat/10.1.16-jdk21-temurin-jammy/images/sha256-857b168692495ee6ff0d6ee89b5b479555c74401bc3c219c88644b9181f03dd5?context=explore
- https://hub.docker.com/layers/library/tomcat/10.1.16-jre21-temurin-jammy/images/sha256-7aaaf9a602c7160a644f1aa5cb1a42c584879769d9b78ef9e31f1055f392561a?context=explore
  • Loading branch information
mbland committed Nov 23, 2023
1 parent 5973ae4 commit f920e91
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 2 deletions.
56 changes: 55 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ Public License 2.0][]. For the text of the license, see the
I installed the latest JDK 21.0.1 from [Eclipse Temurin™ Latest
Releases][] via [SDKMAN!][].

### Install the [Tomcat servlet container][]
### Optional: Install the [Tomcat servlet container][]

_This step is optional, as the [bin/tomcat-docker.sh][] script will run Tomcat
locally in a Docker container defined by
[dockerfiles/Dockerfile.tomcat-test][]._

I followed the [Tomcat 10.1 Setup instructions][] to install Tomcat locally
at `/opt/tomcat/apache-tomcat-10.1.16`. I created `bin/tomcat.sh` as a thin
Expand All @@ -68,6 +72,51 @@ and sets `CATALINA_HOME`. Verified that it was installed correctly via

- [Introduction to Apache Tomcat](https://www.baeldung.com/tomcat)

### Optional: Configure Tomcat to emit HTTP access logs to standard output

_This step is optional, as the Docker container launched by
[bin/tomcat-docker.sh][] is already configured to do this by running
[bin/update-tomcat-config-logging.sh][]._

By default, Tomcat emits its HTTP access logs to
`$CATALINA_HOME/logs/localhost_access_log.YYYY-MM-DD.txt`. This is configured by
the following block in `$CATALINA_HOME/conf/server.xml`:

```xml
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
```

When running and experimenting locally, it can be helpful and convenient to emit
these logs directly to the terminal instead. To emit the HTTP access logs to
standard output instead, edit or replace this `<Valve>` element with the
following:

```xml
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="/dev" prefix="stdout"
suffix="" rotatable="false" buffered="false"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
```

(The above is based on [the answer to &quot;Stack Overflow: Docker, Tomee,
Logging, STDOUT, AWS&quot;][so-tomcat-stdout].)

Alternatively, if you're into the YOLO thing, apply this update by running:

```sh
bin/update-tomcat-config-logging.sh $CATALINA_HOME/conf/server.xml
```

For more information on Tomcat access logging, see:

- [The Apache Software Foundation Apache Tomcat 10 Configuration Reference > The
Valve Component > Access Logging][tomcat-access-logging]

### Install [Gradle][]

I installed Gradle 8.4 via [SDKMAN!][], which also required installing the
Expand Down Expand Up @@ -669,7 +718,12 @@ Coming soon...
[Eclipse Temurin&trade; Latest Releases]: https://adoptium.net/temurin/releases/
[SDKMAN!]: https://sdkman.io
[Tomcat servlet container]: https://tomcat.apache.org/
[bin/tomcat-docker.sh]: bin/tomcat-docker.sh
[dockerfiles/Dockerfile.tomcat-test]: dockerfiles/Dockerfile.tomcat-test
[Tomcat 10.1 Setup instructions]: https://tomcat.apache.org/tomcat-10.1-doc/setup.html
[bin/update-tomcat-config-logging.sh]: bin/update-tomcat-config-logging.sh
[so-tomcat-stdout]: https://stackoverflow.com/a/62598943
[tomcat-access-logging]: https://tomcat.apache.org/tomcat-10.1-doc/config/valve.html#Access_Logging
[Create a Java project with Gradle]: https://docs.gradle.org/current/samples/sample_building_java_libraries.html
[strcalc/build.gradle.kts]: strcalc/build.gradle.kts
[Gradle Tutorial]: https://docs.gradle.org/current/userguide/part1_gradle_init.html
Expand Down
22 changes: 22 additions & 0 deletions bin/update-tomcat-logging-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# Updates Tomcat config to log HTTP requests to standard output, per:
# - https://stackoverflow.com/a/62598943
#
# Takes the path to the Tomcat config as an argument, which it updates in place.
#
# See also:
# - https://tomcat.apache.org/tomcat-10.1-doc/config/valve.html#Access_Logging

ORIG_PAT=(
'<Valve className="org.apache.catalina.valves.AccessLogValve"'
'directory="logs"\n.*\n.* \/>'
)
NEW_VAL="<Valve className=\"org.apache.catalina.valves.AccessLogValve\"
directory=\"\/dev\" prefix=\"stdout\"
suffix=\"\" rotatable=\"false\" buffered=\"false\"
pattern=\"%h %l %u %t &quot;%r&quot; %s %b\" \/>"

# - https://unix.stackexchange.com/a/26289
# - https://unix.stackexchange.com/a/181215
exec perl -p0e "s/${ORIG_PAT[*]}/${NEW_VAL}/g" -i "$1"
11 changes: 10 additions & 1 deletion dockerfiles/Dockerfile.tomcat-test
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# syntax=docker/dockerfile:1.6.0
ARG TOMCAT_TAG=10.1.16-jdk21-temurin-jammy
ARG TOMCAT_TAG=10.1.16-jre21-temurin-jammy

FROM tomcat:${TOMCAT_TAG}

COPY bin/update-tomcat-logging-config.sh /tmp/

RUN <<END_OF_LOGGING_CONFIG_UPDATE
set -e
/tmp/update-tomcat-logging-config.sh /usr/local/tomcat/conf/server.xml
rm /tmp/update-tomcat-logging-config.sh
END_OF_LOGGING_CONFIG_UPDATE

COPY strcalc/build/libs/strcalc.war /usr/local/tomcat/webapps/

0 comments on commit f920e91

Please sign in to comment.