首页 > 试题广场 >

一份请求日志文件,请写程序统计出每5分钟(第一行时间算起),

[问答题]
一份请求日志文件,请写程序统计出每5分钟(第一行时间算起),请求次数最多的接口
输入样例:log.txt
2019-09-10T10:00:01 /api/a
2019-09-10T10:00:01 /api/a
2019-09-10T10:00:01 /api/b
2019-09-10T10:06:00 /api/a
解释:每行表示一次http请求,空格前表示时间,空格后表示接口

输出样例:
2 /api/a
1 /api/a
解释:输入的日志文件跨度包含两个5分钟,第一个5分钟/api/a出现次数最多为2,第二个5分钟/api/a出现次数最多为1
package test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

public class TestSU {
  static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

  private static final String[] TEST_ARRAY = new String[] {
      //
      "2019-09-10T10:00:01 /api/a", //
      "2019-09-10T10:00:01 /api/a", //
      "2019-09-10T10:00:01 /api/b", //
      "2019-09-10T10:00:02 /api/b", //
      "2019-09-10T10:00:03 /api/b", //
      "2019-09-10T10:00:04 /api/b", //
      "2019-09-10T10:00:01 /api/b", //
      "2019-09-10T10:01:01 /api/b", //
      "2019-09-10T10:05:01 /api/b", //
      "2019-09-10T10:05:03 /api/c", //
      "2019-09-10T10:05:04 /api/c", //
      "2019-09-10T10:06:01 /api/a", //
      "2019-09-10T10:06:01 /api/a", //
      "2019-09-10T10:06:01 /api/a", //
      "2019-09-10T10:06:01 /api/a", //
      "2019-09-10T10:06:01 /api/a", //
      "2020-04-20T10:05:01 /api/ddd", //
  };

  public static void main(String[] args) throws ParseException {
    final Date first111 = format.parse("2019-09-10 10:00");
    Map<String, LogDetail> map = Arrays.asList(TEST_ARRAY).stream().map(str -> {
      String[] aaStrings = str.split(" ");
      String[] bbStrings = aaStrings[0].split("T");
      String orgDate = bbStrings[0] + " " + bbStrings[1];
      return new LogDetail(orgDate, aaStrings[1]);
    }).filter(Objects::nonNull).filter(test -> {
      try {
        long diff = format.parse(test.getDate()).getTime() - first111.getTime();
        System.out.println(diff % (5 * 60 * 1000));
        return (diff % (5 * 60 * 1000) == 0);
      } catch (ParseException e) {
        e.printStackTrace();
      }
      return false;
    }).collect(Collectors.groupingBy(LogDetail::getKey, LinkedHashMap::new, Collectors.counting()))
        .entrySet().stream().map(e -> {
          String[] array = e.getKey().split("\\|");
          return new LogDetail(array[0], array[1], e.getValue());
        })
        .collect(Collectors.groupingBy(LogDetail::getDate, LinkedHashMap::new,
            Collectors.reducing(null, BinaryOperator
                .maxBy(Comparator.nullsFirst(Comparator.comparingLong(LogDetail::getCount))))));

    map.entrySet().stream().forEach(e -> System.out.println(e.getValue()));
  }

  static class LogDetail {

    private String date;
    private String detail;

    private long count;

    public LogDetail(String date, String detail) {
      this.setDate(date);
      this.setDetail(detail);
    }

    public LogDetail(String date, String detail, long count) {
      this.setDate(date);
      this.setDetail(detail);
      this.setCount(count);
    }

    public String getDateWithoutSec() {
      return date.substring(0, date.lastIndexOf(":"));
    }

    public String getDate() {
      return date;
    }

    public void setDate(String date) {
      this.date = date;
    }


    public String getDetail() {
      return detail;
    }


    public void setDetail(String detail) {
      this.detail = detail;
    }

    public String getKey() {
      return getDateWithoutSec() + "|" + detail;
    }

    public long getCount() {
      return count;
    }

    public void setCount(long count) {
      this.count = count;
    }

    @Override
    public String toString() {
      return String.format("date:%s, detail:%s, count:%s", date, detail, count);
    }
  }


}

发表于 2020-04-21 11:48:02 回复(0)