catalina.out should be mostly empty, meaning the application intercepts all errors and handles them itself, possibly logging them elsewhere as configured. But more often than not, nothing such is done and
catalina.out is considered as the application logs. This causes problems because by default Tomcat doesn't rotate this file.
The better approach to truncating the file (and beside fixing the application) is to have rotation in place for
catalina.out. This might already be provided by the specific packaged installation (eg: CentOS7's tomcat 7 is/was shipped with proper
catalina.out log rotation in place), or with a recent enough version of tomcat as described in Bug 64430 whose fix has been integrated in newer Tomcat and backported to Tomcat >= 7.0.105, >= 8.5.56 and >= 9.0.36:
Example (all one line)
CATALINA_OUT_CMD="/usr/bin/rotatelogs -f $CATALINA_BASE/logs/catalina.out.%Y-%m-%d.log 86400"
Rotated files should be further handled with
logrotate or an equivalent specialized tool.
Now to strictly answer the question, or at least the part about handling the single
OP writes both:
How to remove everything except last n bytes from the file in Linux?
=> keep the end
deletes [...] the last 5GB from that file
=> keep the start
Keep the start
Thus removing the end. Even if removing the end of a log rather than the start of a log is a bad idea:
truncate - truncate a file to a specified length
The truncate() function shall cause the regular file named by path to
have a size which shall be equal to length bytes.
Which has its
truncate(1) command implementation. For GNU truncate (along GNU
stat(1)) that would be used like this in shell (one has to check the file is greater than 5GiB first or its size would be increased instead). Keeping 5GiB:
if [ $(stat -c %s catalina.out) -gt $((5*1024*1024*1024)) ]; then
truncate -s $((5*1024*1024*1024)) catalina.out
Keep the end
Thus deleting the start of the file. It's possible on Linux and adequate filesystem (eg: Ext4, XFS ...) to do this without involving any copy of data, using
fallocate(1) (with additional Linux-only features):
Deallocates space (i.e., creates a hole) in the byte range starting at
offset and continuing for length bytes.
This doesn't involve any copy of data, but requires this to be block-aligned (so usually 4096 bytes-aligned). One can always keep the end of the file, a bit like a ring buffer, without any copy cost. This could be used like this (extra computation is needed to align to a 4096 multiple):
oldsize=$(stat -c %s catalina.out) || exit 1
if [ $oldsize -gt $((5*1024*1024*1024)) ]; then
holesize=$(( (oldsize-5*1024*1024*1024)/4096*4096 ))
fallocate --punch-hole --length "$holesize" catalina.out
--punch-hole (freeing the disk space by making the file sparse and keeping its apparent size) is used rather than
--collapse-range ("moving" remaining data to the start reducing the size) to avoid disruption of the ongoing output appended to
catalina.out by Tomcat, else Tomcat should be stopped before and restarted after.