【发布时间】:2010-12-20 03:19:14
【问题描述】:
我必须监听一个文件,当它的内容被添加时,我将读取新行,并处理新行的内容。 文件的长度永远不会减少。(其实就是tomcat的日志文件)。
我使用以下代码:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.apache.log4j.Logger;
import com.zjswkj.analyser.ddao.LogEntryDao;
import com.zjswkj.analyser.model.LogEntry;
import com.zjswkj.analyser.parser.LogParser;
public class ListenTest {
private RandomAccessFile raf;
private long lastPosition;
private String logEntryPattern = "^([\\d.]+) (\\S+) (\\S+) \\[([\\w:/]+\\s[+\\-]\\d{4})\\] \"(.+?)\" (\\d{3}) (\\S+) \"([^\"]+)\" \"([^\"]+)\"";
private static Logger log = Logger.getLogger(ListenTest.class);
public void startListenLogOfCurrentDay() {
try {
if (raf == null)
raf = new RandomAccessFile(
"/tmp/logs/localhost_access_log.2010-12-20.txt",
"r");
String line;
while (true) {
raf.seek(lastPosition);
while ((line = raf.readLine()) != null) {
if (!line.matches(logEntryPattern)) {
// not a complete line,roll back
lastPosition = raf.getFilePointer() - line.getBytes().length;
log.debug("roll back:" + line.getBytes().length + " bytes");
if (line.equals(""))
continue;
log.warn("broken line:[" + line + "]");
Thread.sleep(2000);
} else {
// save it
LogEntry le = LogParser.parseLog(line);
LogEntryDao.saveLogEntry(le);
lastPosition = raf.getFilePointer();
}
}
}
} catch (FileNotFoundException e) {
log.error("can not find log file of today");
} catch (IOException e) {
log.error("IO Exception:" + e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ListenTest().startListenLogOfCurrentDay();
}
}
现在,我的问题是,如果正在写入文件的新行的行没有完成,则会出现死循环。
例如,如果tomcat尝试向文件写入一个新行:
10.33.2.45 - - [08/Dec/2010:08:44:43 +0800] "GET /poi.txt HTTP/1.1" 200 672 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
并且当只写了一行的一部分时(例如:10.33.2.45 - - [08/Dec/2010:08:44:43 +0800] "GET /poi.txt HTTP/1.1 " 200 672>),现在由于无法匹配我定义的模式,也就是说tomcat没有完成它的写入工作,所以我会尝试回滚文件指针,然后休眠2秒然后读取再次。
在睡眠期间,该行的最后一部分可能还没有写(实际上我写它们而不是tomcat进行测试),在我看来,randomaccessfile会读取一个可以匹配模式的新行,但似乎没有.
任何人都可以检查代码?
注意:日志文件的格式是这样“组合”的:
10.33.2.45 - - [08/Dec/2010:08:44:43 +0800] "GET /poi.txt HTTP/1.1" 200 672 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
【问题讨论】:
-
您可以尝试提供赏金。另外,请不要那样做。
-
在日志中发布超过 1 行的示例日志文件,我也不清楚究竟是什么问题
标签: java loops io random-access