java - 解析日志文件中的请求和响应时间

标签 java

我正在尝试解析日志文件。我需要帮助检查请求和响应之间的时间差。本质上是花费超过 10 秒的请求数量。以下是该文件的示例摘录:

16/08/29-03:20:39.538 << 1250 REQUEST COUNTER="1"
16/08/29-03:20:39.542 << 1250 REQUEST COUNTER="2"
16/08/29-03:20:39.656 >> 2250 RESPONSE COUNTER="1"
16/08/29-03:20:39.655 >> 2250 RESPONSE COUNTER="2"

此文件可以包含大约 300 万条记录。我正在考虑使用 BufferedReader 读取它,读取一行,然后检查该行中是否存在“COUNTER”,存储请求时间和计数器的值,然后在整个文件中搜索相同的计数器值以获得响应时间,然后检查差异。

我需要帮助来存储时间并检查差异。另外,有没有更好的方法?

    BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
        String line;
        while((line = reader.readLine()) != null) {
            if(line.contains("COUNTER")) {
                String[] tokens = line.split("\\s+");
                Date date = new SimpleDateFormat("yy/mm/dd-HH:mm:ss.SSS").parse("16/08/29-12:42:48.167");
                //this is not storing the correct value                 
            }

最佳答案

我会采取一次读取日志文件并使用 HashMap 跟踪请求/响应的方法。映射键将是计数器,映射值将是请求的日期。为了节省内存,请在收到响应后从 map 中删除项目。使用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();
}

关于java - 解析日志文件中的请求和响应时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39207428/

相关文章:

java - EJB,持久化期间出现异常 : "EntityManager must be access within a transaction"

java - 在 Java 中,当按下某个键(例如字母)时,如何防止该键输出分配给 jTextPane 的字母?

java - 如何实现来自 java servlet 的图像幻灯片放映,而不需要在 html 中对图像进行硬编码?

java - org.hibernate.exception.JDBCConnectionException : Error calling Driver#connect

java - 无法在 SD 卡中创建文件

java - 我可以被追踪吗

java - android studio 中的 build.gradle 依赖

java - InetAddress 无法解析为类型

java - 在 Spring Boot Controller 方法中传递 HttpServletResponse

java - 处理 apache 公共(public)池中的饥饿