Linux之tail命令实时收集[纠正误解]
tail [OPTION]... [FILE]...
-c, --bytes=K output the last K bytes; alternatively, use -c +K
to output bytes starting with the Kth of each file
-f, --follow[={name|descriptor}]
output appended data as the file grows;
-f, --follow, and --follow=descriptor are
equivalent
-F same as --follow=name --retry
-n, --lines=K output the last K lines, instead of the last 10;
or use -n +K to output lines starting with the Kth
--max-unchanged-stats=N
with --follow=name, reopen a FILE which has not
changed size after N (default 5) iterations
to see if it has been unlinked or renamed
(this is the usual case of rotated log files).
With inotify, this option is rarely useful.
--pid=PID with -f, terminate after process ID, PID dies
-q, --quiet, --silent never output headers giving file names
--retry keep trying to open a file even when it is or
becomes inaccessible; useful when following by
name, i.e., with --follow=name
-s, --sleep-interval=N with -f, sleep for approximately N seconds
(default 1.0) between iterations.
With inotify and --pid=P, check process P at
least once every N seconds.
-v, --verbose always output headers giving file names
--help display this help and exit
--version output version information and exit
其中, 使用tail -F -n +K logfile, 可以很好地收集日志数据. 是以前理解错误! 纠正, 纠正!
在日志切换时会打印错误信息:
im e
tail: `/home/hadoop/test.log' has become inaccessible: No such file or directory
tail: `/home/hadoop/test.log' has appeared; following end of new file
this is a new file
其中第1句可以使用--retry去掉, 第2句则暂不确定.最好就是阅读非"tail:"打头的行才记入日志.
测试代码:
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("bash");
pb.redirectErrorStream(true);
final Process p = pb.start();
PrintStream stdin = new PrintStream(p.getOutputStream());
// stdin.println("source /etc/profile");
stdin.println("tail -F -q --retry ~/test.log");
stdin.close();
Thread t = new Thread(new Runnable() {
public void run() {
StringWriter buf = new StringWriter();
PrintWriter pbuf = new PrintWriter(buf);
// Scanner stdout = new Scanner(p.getInputStream());
BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while (true) {
try {
line = stdout.readLine();
if (line == null) {
return;
}
System.out.println(line);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.setDaemon(true);
t.start();
p.waitFor();
System.out.println(p.exitValue());
System.out.println("done...");
}