You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何从访问日志字符串中提取datetime、requestType等指定字段

日志字段正则提取需求实现

需求说明

需要从标准Apache/Nginx格式的访问日志中,提取datetime、requestType、resourceUrl、status四个字段,适配的日志样例如下:

127.0.0.1 - - [03/Dec/2020:05:48:05 +0000] "GET /web/test/explorer HTTP/1.1" 200 175842

对应字段提取要求:

  • datetime:取值为方括号内的时间部分,无需时区后缀,样例取值03/Dec/2020:05:48:05
  • requestType:取值为双引号开头的HTTP请求方法,样例取值GET
  • resourceUrl:取值为请求方法后的完整请求路径+协议,样例取值/web/test/explorer HTTP/1.1
  • status:取值为双引号结束后的第一个3位数字状态码,样例取值200

前置修正提示

你现有代码存在bug:getRequestObject方法中第二次调用setUrl是错误的,应该改为setResourceUrl,否则会覆盖之前设置的IP字段值。


各字段提取方法实现

1. extractDateTime 方法

匹配逻辑:匹配行中[和+之间的内容,正则规则为\[(.*?) \+

private String extractDateTime(String line) {
    String dateTime = "";
    Pattern pattern = Pattern.compile("\\[(.*?) \\+");
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        dateTime = matcher.group(1);
    }
    return dateTime;
}

2. extractRequestType 方法

匹配逻辑:匹配双引号后到第一个空格之间的请求方法,正则规则为"([A-Z]+)

private String extractRequestType(String line) {
    String requestType = "";
    Pattern pattern = Pattern.compile("\"([A-Z]+) ");
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        requestType = matcher.group(1);
    }
    return requestType;
}

3. extractResourceUrl 方法

匹配逻辑:匹配请求方法后到双引号之前的内容,正则规则为"[A-Z]+ (.*?)"

private String extractResourceUrl(String line) {
    String resourceUrl = "";
    Pattern pattern = Pattern.compile("\"[A-Z]+ (.*?)\"");
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        resourceUrl = matcher.group(1);
    }
    return resourceUrl;
}

4. extractStatus 方法

匹配逻辑:匹配双引号结束后第一个3位数字,正则规则为" (\d{3})

private int extractStatus(String line) {
    int status = 0;
    Pattern pattern = Pattern.compile("\" (\\d{3}) ");
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        status = Integer.parseInt(matcher.group(1));
    }
    return status;
}

性能优化建议

  • 所有正则的Pattern实例可以提前声明为类静态常量,避免每次调用方法重复编译,大幅提升大体积日志文件的解析性能
  • 可以使用全量匹配正则一次性提取所有5个字段,减少多次匹配的开销,全量正则参考:^(\\S+) - - \\[(.*?) \\+\\d+\\] "(\\S+) (.*?)" (\\d{3}) \\d+$,仅需一次匹配即可拿到所有字段值

内容的提问来源于stack exchange,提问作者Abdul Basit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 10:18:03