背景:
公司接口请求经过多层代理,有时总请求时间超长,但nginx中的request_time和应用监控的超时时间对不上,为了明确应用服务的http接口访问时间,需要开启springboot的accesslog。
第一步:首先因为springboot内置了很多web容器,如tomcat jetty undertow,如果选择使用undertow则需要添加undertow容器对应依赖,且排除tomcat相关依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
//....其他依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
<exclusion>
<artifactId>log4j-to-slf4j</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
</exclusions>
</dependency>
第二步:开启accesslog配置
在springboot 配置文件application.properties中添加如下配置项
# Undertow access log directory. accesslog的目录
#server.undertow.accesslog.dir=weblog
# Enable access log. 开启accesslog
server.undertow.accesslog.enabled=true
# Format pattern for access logs. 默认是common,如果不配置pattern
server.undertow.accesslog.pattern=%t [%I] %{i,x_forwarded_for} %a %r %s (%D ms)
# Log file name prefix. accesslog文件前缀
server.undertow.accesslog.prefix=access_log.
如果不配置日志的输出格式,也就是不指定server.undertow.accesslog.pattern时,默认使用的是common格式输出,但common格式输出的日志格式是怎样的呢?
查看undertow accesslog处理的源码:io.undertow.server.handlers.accesslog.AccessLogHandler
查看源码可发现日志格式common和 combined的格式定义:
private static String handleCommonNames(String formatString) {
if(formatString.equals("common")) {
return "%h %l %u %t \"%r\" %s %b";
} else if (formatString.equals("combined")) {
return "%h %l %u %t \"%r\" %s %b \"%{i,Referer}\" \"%{i,User-Agent}\"";
}
return formatString;
}
common日志格式: %h %l %u %t \"%r\" %s %b
%h: 远程主机名
%l: 远程主机逻辑名: 经常是 -
%u: 远程受信用户名: 经常是 -
%t: 日期和时间,用 Common Log Format格式
%r: Http请求的第一行
%s: 响应状态码
%b: 发送的字节数(不包括头域),如是 - 表明没有字节发送,
combined日志格式: %h %l %u %t \"%r\" %s %b \"%{i,Referer}\" \"%{i,User-Agent}\
"%{i,Referer}\": 从http请求头中获取 来源地址
%{i,User-Agent}: 从http请求头中获取 userAgent
注意,common格式的日志输出并没有响应时间的输出,如果想输出响应时间,需要用%D
但如果要记录http请求所费时间,需要开启一项server配置,有少量性能影响,所以配置的默认值是false。
开启undertow计时配置则需要在项目增加一项初始化配置类,开启undertow计时。(否则%D无法显示)
@Configuration
public class UndertowConfig {
@Bean
public UndertowServletWebServerFactory undertowServletWebServerFactory() {
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
@Override
public void customize(Undertow.Builder builder) {
builder.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, true);
}
});
return factory;
}
}
其他参数定义请参考官网文档:Predicates Attributes and Handlers