私は、ログファイルを一度読んで、HashMapを使って要求/応答を追跡するというアプローチを取っています。マップキーはカウンタになり、マップ値はリクエストの日付になります。メモリを節約するには、レスポンスを受信したときにマップからアイテムを削除します。 Javaのpattern matchingを使用して、要求または応答かどうかを判断し、カウンタIDと日付を取得します。
final static long EXPIRED_MILLIS = 1000 * 10; // ten seconds
final static Pattern REQUEST_PATTERN = Pattern.compile("(.*)(<< \\d{4})(REQUEST COUNTER=\")(\\d)(\")");
final static Pattern RESPONSE_PATTERN = Pattern.compile("(.*)(<< \\d{4})(RESPONSE COUNTER=\")(\\d)(\")");
final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yy/MM/dd-HH:mm:ss.SSS");
List<String> getExpiredCounterList(File file) throws Exception {
Map<String,Long> requestMap = new HashMap<>();
List<String> expiredCounterList = new ArrayList<>();
try(FileReader fileReader = new FileReader(file);
BufferedReader buffReader = new BufferedReader(fileReader))
{
String line;
while((line = buffReader.readLine()) != null) {
Matcher requestMatcher = REQUEST_PATTERN.matcher(line);
if(requestMatcher.matches()) {
addRequestToMap(line, requestMatcher, requestMap);
continue;
}
Matcher responseMatcher = RESPONSE_PATTERN.matcher(line);
if(requestMatcher.matches()) {
String expiredCounter = checkIfExpiredAndRemoveFromMap(line, responseMatcher, requestMap);
if(expiredCounter != null)
expiredCounterList.add(expiredCounter);
}
}
}
return expiredCounterList;
}
void addRequestToMap(String request, Matcher requestMatcher, Map<String,Long> requestMap) {
String counter = getCounter(request, requestMatcher, 4);
long date = getDate(request, requestMatcher, 1);
requestMap.put(counter, date);
}
String checkIfExpiredAndRemoveFromMap(String response, Matcher responseMatcher, Map<String,Long> requestMap) {
String counter = getCounter(response, responseMatcher, 4);
if(requestMap.containKey(counter)) {
long date = getDate(response, responseMatcher, 1);
long elapsedMillis = date - requestMap.remove(counter);
if(elapsedMillis > EXPIRED_MILLIS)
return counter;
}
return null;
}
String getCounter(String line, Matcher matcher, int group) {
return line.substring(matcher.start(group), matcher.end(group));
}
long getDate(String line, Matcher matcher, int group) throws ParseException {
return DATE_FORMAT.parse(line.substring(matcher.start(group), matcher.end(group))).getTime();
}
毎回新しい行を作成するのではなく、一致する行ごとに同じ 'SimpleDateFormat'オブジェクトを使用できることに注意してください。 – Berger
あなたのファイルに複数のスレッドが並行して動作することはありません。その後、各スレッドは独自のフォーマッタを必要とします。 – GhostCat
ログファイルを読んでいるうちに、私は遭遇した「要求」をリストに記録します。 "RESPONSE"行が表示されたら、リストから適切なREQUESTを削除し、遅延が10秒を超えていないかどうかを確認します。 – Aaron