3

I am trying to programatically purge log files from a running(!) system consisting of several Java and non-Java servers. I used Java's File.delete() operation and it usually works fine. I am also perfectly fine with log files that are currently in use not being deleted, so I just log it as a warning whenever File.delete() returns false.

However, in log files which are currently still being written to by NON-Java applications (Postgres, Apache HTTPD etc., Java applications might also be affected, but I didn't notice yet, and all are using the same logging framework anyway, which seems to be OK) are not actually deleted (which is what I expected), however, File.delete() returns "true" for them. But not only do these files still exist on the file system (Windows explorer and "dir" still show them), but afterwards they are inaccessible... when I try to open them with a text editor etc. I get "access denied" or similar error messages, when I try to copy them with explorer, it also claims that I do not have permissions, when I check its "properties" with explorer, it gives me "You do not have permission to view or edit this object's permissions".

Just to be clear: before I ran the File.delete() operation, I could access or delete these files without any problems, the delete operation "breaks" them. Once I stop the application, the file then disappears, and on restart, the application creates it from scratch and everything is back to normal. The problem is that when NOT restarting the application after the log file purge operation, the application logs to nirvana.

This behavior reminds me a bit of the file deletion behavior of Linux: if you delete a file that is still held open by an application, it disappears from the file system, but the application - still holding a file handle - will happily continue writing to that file, but you will never be able to access it afterwards. The only difference being that here the files are still visible in the FS, but also not accessible otherwise.

I should mention that both my Java program and the applications themselves are running with "system" user.

I also tried Files.delete(), which allegedly throws an IOException indicating the error... but it seems there is no error.

What I tried to work around the problem is to check if the files are currently locked, using the method described here https://stackoverflow.com/a/1390669/5837050, but this only works for some of the files, not for all of them.

I basically need a reliable way (at least for Windows, if it worked also for Linux, that would be great) to determine if a file is still being used by some program, so I could just not delete it.

Any hints appreciated.

Community
  • 1
  • 1
MellowCoder
  • 149
  • 1
  • 4
  • 1
    @Divyesh: The link you posted introduces general Java concurrency features - not sure how they should help here, since the files I want to delete are actually not even written by my own Java application, but by various third-party Java and NON-Java applications. – MellowCoder Jul 11 '16 at 04:52

1 Answers1

0

I haven't reproduced it but it seems like an OS expected behaviour, normally different applications run with different users which have ownership on this type of files but I understand that you want like a master purge Java which checks the log files not in use to delete them (running with enough grants of course).

So, considering that the OS behaviour is not going to change I would suggest to configure your logs with "roll file appender" policies and then check the files that match these policies.

Check the rollback policies for logback to make you an idea: http://logback.qos.ch/manual/appenders.html#onRollingPolicies

For example, if your appender file policy is "more than one day or more than 1Gb" then just delete files which last edition date are older than one day or size are 1Gb. With this rule you will be sure to delete log files that are not in use.

Note that.. with a proper rolling policy maybe you even don't need your purge method, look at this configuration example:

  <!-- keep 30 days' worth of history capped at 3GB total size -->
  <maxHistory>30</maxHistory>
  <totalSizeCap>3GB</totalSizeCap>

I hope this could help you a bit!!

Carlos Verdes
  • 3,037
  • 22
  • 20