29

Every once in a while our catalina.out file gets very very large (yes, I will be implementing slf4j and logback in my applications to prevent this in the future). But for now, when I go to cycle the logs, I copy catalina.out to catalina.{date} and execute cat /dev/null > catalina.out. The problem is, tomcat will capture no further logs after I do that, until tomcat is restarted the next morning, and this is not ideal. Why does this happen? And is there a way to avoid it?

Jibby
  • 850
  • 1
  • 9
  • 21
  • Are you sure you are doing a `cp` and not a `mv` when you backup the old catalina.out? – Jose Martinez May 09 '16 at 20:47
  • /dev/null is an eternal stream of null chars! type `cat /dev/null` and youll see what I mean. btw.. `ctrl + c ` should stop the process. The best way – Nate T Sep 26 '21 at 10:49
  • To anyone else who finds themselves in a similar situation, The best way to solve your issue is to do what I said above. This pulls the stream from your descriptor into stdout. from there the interrupt kills it. The old "trap n' kill" XD – Nate T Sep 26 '21 at 10:56

7 Answers7

50

Easy as cake: echo > catalina.out. The file descriptor won't change and java can continue to write to that file.

Michael-O
  • 18,123
  • 6
  • 55
  • 121
  • 1
    Could you elaborate on the file descriptor not changing, including why cat /dev/null would change it but echo would not? – Jibby May 09 '16 at 20:29
  • 3
    @Jibbyj, to be honest. I do not know. It does its job. – Michael-O May 10 '16 at 07:36
  • About file descriptors: [https://stackoverflow.com/questions/5256599/what-are-file-descriptors-explained-in-simple-terms](https://stackoverflow.com/questions/5256599/what-are-file-descriptors-explained-in-simple-terms) – karthi Aug 24 '18 at 05:00
  • @Michael-O echo with no string to echo will write nothing. The `>` redirect will take the "nothing" output and overwrite the file. This isn't different than cat-ing `/dev/null`, which also provides a "nothing" to trigger `>`'s overwriting of the file. – Edwin Buck Sep 26 '21 at 15:13
19

The traditional way is to

cat /dev/null > catalina.out

It will clear the log file, and will not disrupt the processes that currently hold open file handles.

The better way is to not lose your logging information, by rotating out the log file. To do this, create or edit the file /etc/logrotate.d/tomcat and have its contents read

/var/log/tomcat/catalina.out {   copytruncate   daily   rotate 7   compress   missingok   size 5M  }

Then restart logrotate with the command (as root)

/usr/sbin/logrotate /etc/logrotate.conf

And you should have the log file rotated out daily, or if the size exceeds 5M, with the last seven logs kept for debugging purposes.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • Note you may need to modify the log file location, if your tomcat catalina.out file is at a different path. Likewise, you can read about logrotate and modify the other values to suit your liking. – Edwin Buck May 09 '16 at 20:02
  • I've used the traditional way, but it definitely seems to disrupt the processes that currently hold open file handles... – Jibby May 09 '16 at 20:28
  • 1
    It would be very helpful for you to explain the contents of the logrotate file you're creating. Also, creating a file called `tomcat` is only appropriate if that's the process name correct? On Ubuntu 14 for tomcat 7 the process is actually `tomcat7`, for example. – Madbreaks Mar 23 '17 at 17:22
  • The traditional way is to just archive / zip /change the name, e.g. `full_file.log`, to any of (full_file.log.1, full_file.1, full_file.~, full_file.log.09262021, etc.)and start a new one under the old name. Many times Ive needed super old log files to save the curent state of a machine. – Nate T Sep 26 '21 at 10:39
  • How does changing the name prevent the open file handle from writing to the new name? And how do you start a new log file under the old name without a program that's explicitly designed to create a new file (like one that does so after receiving a signal)? Many offer facilities to do what you ask, but not all, and I think the shortness of comments has you leaving out a few steps. Why not write up a full answer instead? – Edwin Buck Sep 26 '21 at 15:11
14

You can truncate the file. This makes logical sense also since it is essentially what you are trying to do.

truncate -s 0M catalina.out

FYI: Doing a cat /dev/null > file does not alter the inode of the file.

logs]$ls -i test.log
19794063 test.log
logs]$
logs]$cat /dev/null > test.log
logs]$ls -i test.log
19794063 test.log

Also, I had a separate command tailing live data into test.log during these commands. After running these commands the tail to test.log still worked without a problem. This does not answer your question as to why it stopped working, but it helps rule out change in inode.

Jose Martinez
  • 11,452
  • 7
  • 53
  • 68
  • Could you please explain why truncating is better than cat /dev/null? – Jibby May 09 '16 at 20:30
  • 2
    @Jibbyj op asked how to truncate the file. I think the question is why anyone would `echo /dev/null > catalina.out` instead of using `truncate`. The latter is both semantically and technically the correct way to do so. – Madbreaks Mar 23 '17 at 17:12
  • damn! I was doing an `echo /dev/null` instead and was wondering why it didn't work – asgs Nov 22 '18 at 13:48
  • 1
    Didn't we need to remove the `M` from the command? I am asking because there is junk file named `M` created. The command supposed to look like: `truncate -s 0 catalina.out` – Kyo Aug 26 '23 at 08:55
  • @Kyo you are right. The `M` is suppose to be touching the `0`. I updated my answer with the fix. Thank you for pointing this out! – Jose Martinez Aug 26 '23 at 16:46
3

What you are looking for is log rotation. Since this requires a low-level signal support while the process is running, you should do this indirectly. You can use this procedure to achieve this. This is also documented on Tomcat Wiki.

Kedar Mhaswade
  • 4,535
  • 2
  • 25
  • 34
1

go to the folder /opt/tomcat/logs/ type in command line --

sudo echo > catalina.out

you can run this without shutting down tomcat server . . you can also schedule this command on daily or weekly basis . .

0

If the catalina.out is deleted after tomcat is stopped, it will create a new catalina.out once tomcat starts again and it is totally safe.

But if you remove the catalina.out while tomcat is running, it will keep on logging to catalina.out which is removed already (reference of the file is hold by the tomcat) hence the space will not be released. So you will need to restart the tomcat sever to release the space. It is not recommended.

Actually you can clear the log of catalina.out file without stopping tomcat with the command below.

sudo cat /dev/null > /opt/tomcat/apache-tomcat-9.0.37/logs/catalina.out  

To keep catalina.out smaller, either one of the following ways can be used:

  1. You could use the above Linux command and add it to a CronScheduler to run daily/ weekly/ monthly or yearly as preferred.

  2. Use logrotate tool in Linux. It is a log managing command-line tool in Linux. This can rotate the log files under different conditions. Particularly, we can rotate log files on a fixed duration or if the file has grown to a certain size. You can click here for more info on this.

Du-Lacoste
  • 11,530
  • 2
  • 71
  • 51
0

Simple and straight forward solution:

echo "" > catalina.out

Note: Add sudo if required