1

I'm use redirect to logging println operation output to a xxx.log file. But I want move the log info to a separate file with name of current days date, such as 2017-08-18.log by crontab.

I have attempt use > xxx.log shell command to clear the xxx.log file, but all content recovery when a new log generate.

How to clear the redirect log file?

UPDATE

  1. After I'm execute > xxx.log, the xxx.log file's size is 0.But if my application print some new log, the xxx.log not only contains the new log info but also contains the former cleared log info.
  2. After use mv xxx.log xxx2.log, new log info will write to xxx2.log.But if I use rm xxx.log instead of rename, the log action will stop. Besides, the process invoked by nohup java -jar xxx.jar > xxx.log 2>&1 & if you familiar with playframework, the execute file build by a dist command to generate the jar file.
  3. ps wx|grep "xxx.*.log output:
    1) 3912 pts/10 S+ 0:00 grep --color=auto xxx.log
    2) 26234 pts/10 Sl 0:16 /usr/lib/jvm/jdk1.8.0_111/bin/java -Duser.dir=...something ignored... play.core.server.ProdServerStart (it's the process execute command)

Hope it will be helpful, thanks again!

  • I'm not quite sure what you mean by "but all content recovery when a new log generate". – Kusalananda Aug 18 '17 at 6:21
  • @Kusalananda, It really confusing. After I'm execute > xxx.log, the xxx.log file's size is 0.But if my application print some new log, the xxx.log not only contains the new log info but also contains the former cleared log info. – LoranceChen Aug 18 '17 at 6:52
  • it's sounds a thing that your application is keeping the logs is somewhere or buffer and it write back the logs, you can rename xxx.log once to check if it's recreating with same name or has rotation mechanism – αғsнιη Aug 18 '17 at 7:08
  • @AFSHIN, After use rm xxx.log xxx2.log, new log info will write to xxx2.log.But if I use rm xxx.log instead of rename, the log action will stop. Besides, the process invoked by nohup java -jar xxx.jar > xxx.log 2>&1 &. – LoranceChen Aug 18 '17 at 7:40
  • please edit in your question with these details + post the output of `ps wx|grep "xxx.*.log" – αғsнιη Aug 18 '17 at 7:52
1

The problem is that your log file stays opened by the application that is writing to it. If you truncate the file (> file.log), your app will still write to it from the point of its last write (due to the truncation, I suppose your file will be filled with 0 bytes till that point). If you move the file, your app will continue to write to it since, once opened, its name doesn't matter. If you remove the file, the blocks won't be freed from the disk and the app will still be writing to them, even if the file is not visible any longer in your directory.

This is a classic scenario. Your application must:

  • either reopen the log file periodically
  • or detect that it has been truncated and reopen it
  • or wait for a special signal that tells it "close your current log file and reopen it"

Else, there is nothing you can do externally except restarting your application. You would then do it the same way as logrotate:

  • first move the log file under a new name
  • optionally touch the log file with its old name so that the file exists
  • restart the application to force it to stop writing to the old log file and to start writing to the new one.
  • Maybe I need some log tools in my application, such as log4j or write myself, restart the application for logging is not allowed.Thanks a lot – LoranceChen Aug 18 '17 at 23:51
  • @LoranceChen Restart is an extreme case when you have no control over the application, which was my assumption. If the Java application is yours, then yes, of course, use a dedicated tool for your logs. log4j apparently offers a mechanism for log rotation through RollingFileAppender – xhienne Aug 19 '17 at 8:49
0

If you are ok with Perl you could run this little script:

use POSIX qw(strftime);

$fbase = "tmp-%Y-%m-%d-%H-%M.log";

while(<>)
{
  $fnamenew = strftime $fbase, localtime;

  if ($fnamenew ne $fname)
  {
    print "logging to: $fnamenew\n";
    $fname = $fnamenew;
    close OUT;
    open OUT, ">$fname";
  }
  print OUT $_;
}

Use it like: $mycomputation | perl script.pl. It will append all input to a filename built from the given time pattern, here tmp-YYYY-MM-DD-HH-MI.log. On each new line of input, the pattern is rebuilt and checked against the old one. Should it differ then the input is piped to the new file and the old one is closed.

  • Hi, I'm not familiar with perl.The script has a error: ./perl.pl: line 1: syntax error near unexpected token (' ` and another line ./perl.pl: line 1: use POSIX qw(strftime);'. – LoranceChen Aug 18 '17 at 23:45
  • For the record: This was related to using the wrong interpreter. The script needs to be run with perl script.pl or with #!/usr/bin/perl in line 1. – yacc Aug 19 '17 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.