Spring 引导:在 AuditApplicationEvent 侦听器中获取查询字符串参数和请求正文
Spring Boot: getting query string parameters and request body in AuditApplicationEvent listener
Spring 在此处启动 REST 应用程序。我正在尝试配置 Spring 启动请求审核以记录任何 resources/controllers 收到的每个 HTTP 请求以及以下信息:
- 我需要在日志中查看客户端请求的确切 HTTP URL(路径),包括 HTTP 方法 和任何查询字符串参数 ;和
- 如果有请求正文(例如带有 POST 或 PUT),我还需要在日志中查看该正文的内容
迄今为止我最好的尝试:
@Component
public class MyAppAuditor {
private Logger logger;
@EventListener
public void handleAuditEvent(AuditApplicationEvent auditApplicationEvent) {
logger.info(auditApplicationEvent.auditEvent);
}
}
public class AuditingTraceRepository implements TraceRepository {
@Autowired
private ApplicationEventPublisher applicationEventPublisher
@Override
List<Trace> findAll() {
throw new UnsupportedOperationException("We don't expose trace information via /trace!");
}
@Override
void add(Map<String, Object> traceInfo) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
AuditEvent traceRequestEvent = new AuditEvent(new Date(), "SomeUser", 'http.request.trace', traceInfo);
AuditApplicationEvent traceRequestAppEvent = new AuditApplicationEvent(traceRequestEvent);
applicationEventPublisher.publishEvent(traceRequestAppEvent);
}
}
但是在运行时,如果我使用以下 curl 命令:
curl -i -H "Content-Type: application/json" -X GET 'http://localhost:9200/v1/data/profiles?continent=NA&country=US&isMale=0&height=1.5&dob=range('1980-01-01','1990-01-01')'
然后我只看到以下日志消息(其中 MyAppAuditor
发送审核事件):
{ "timestamp" : "14:09:50.516", "thread" : "qtp1293252487-17", "level" : "INFO", "logger" : "com.myapp.ws.shared.auditing.MyAppAuditor", "message" : {"timestamp":"2018-06-29T18:09:50+0000","principal":"SomeUser","type":"http.request.trace","data":{"method":"GET","path":"/v1/data/profiles","headers":{"request":{"User-Agent":"curl/7.54.0","Host":"localhost:9200","Accept":"*/*","Content-Type":"application/json"},"response":{"X-Frame-Options":"DENY","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","Pragma":"no-cache","Expires":"0","X-XSS-Protection":"1; mode=block","X-Application-Context":"application:9200","Date":"Fri, 29 Jun 2018 18:09:50 GMT","Content-Type":"application/json;charset=utf-8","status":"200"}},"timeTaken":"89"}} }
如您所见,审核员正在选择基本路径 (/v1/data/profiles
),但未记录任何查询字符串参数。当我点击 POST 或 PUT 确实需要请求正文的端点 (JSON) 时,我也看到类似的请求正文信息缺失。
我需要做什么来配置这些 类(或其他 Spring classes/configs),以便我获得我想要的请求审核级别我在找什么?
幸运的是,Actuator 使配置这些 Trace
事件变得非常容易。
添加参数到跟踪信息
您可以 take a look 所有选项。您会注意到默认值 (line 42
) 是:
Include.REQUEST_HEADERS,
Include.RESPONSE_HEADERS,
Include.COOKIES,
Include.ERRORS,
Include.TIME_TAKEN
因此您还需要添加 Include.PARAMETERS
以及您希望在跟踪中包含的任何其他内容。要配置它,management.trace.include
.
有一个配置 属性
因此,要获得您想要的(即 parameters
),加上默认值,您需要:
management.trace.include = parameters, request-headers, response-headers, cookies, errors, time-taken
添加请求正文到跟踪信息
为了获得 body
,您必须将此 Bean
添加到您的 Context
:
@Component
public class WebRequestTraceFilterWithPayload extends WebRequestTraceFilter {
public WebRequestTraceFilterWithPayload(TraceRepository repository, TraceProperties properties) {
super(repository, properties);
}
@Override
protected Map<String, Object> getTrace(HttpServletRequest request) {
Map<String, Object> trace = super.getTrace(request);
String body = null;
try {
body = request.getReader().lines().collect(Collectors.joining("\n"));
} catch (IOException e) {
throw new RuntimeException(e);
}
if(body != null) {
trace.put("body", body);
}
return trace;
}
}
上面的代码将覆盖 AutoConfigure'd
WebRequestTraceFilter
bean(因为它是 @ConditionalOnMissingBean
将尊重您的自定义 bean),并提取额外的有效负载 属性 关闭 request
,然后将其添加到发布到 TraceRepository
!
的 Map
属性
总结
- 请求参数 可以通过
management.trace.include
属性 添加到 TraceRepository trace events
- 请求主体可以通过创建扩展
Bean
添加到TraceRepository trace events
以读取HTTP请求的body
并补充跟踪事件
Spring 在此处启动 REST 应用程序。我正在尝试配置 Spring 启动请求审核以记录任何 resources/controllers 收到的每个 HTTP 请求以及以下信息:
- 我需要在日志中查看客户端请求的确切 HTTP URL(路径),包括 HTTP 方法 和任何查询字符串参数 ;和
- 如果有请求正文(例如带有 POST 或 PUT),我还需要在日志中查看该正文的内容
迄今为止我最好的尝试:
@Component
public class MyAppAuditor {
private Logger logger;
@EventListener
public void handleAuditEvent(AuditApplicationEvent auditApplicationEvent) {
logger.info(auditApplicationEvent.auditEvent);
}
}
public class AuditingTraceRepository implements TraceRepository {
@Autowired
private ApplicationEventPublisher applicationEventPublisher
@Override
List<Trace> findAll() {
throw new UnsupportedOperationException("We don't expose trace information via /trace!");
}
@Override
void add(Map<String, Object> traceInfo) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
AuditEvent traceRequestEvent = new AuditEvent(new Date(), "SomeUser", 'http.request.trace', traceInfo);
AuditApplicationEvent traceRequestAppEvent = new AuditApplicationEvent(traceRequestEvent);
applicationEventPublisher.publishEvent(traceRequestAppEvent);
}
}
但是在运行时,如果我使用以下 curl 命令:
curl -i -H "Content-Type: application/json" -X GET 'http://localhost:9200/v1/data/profiles?continent=NA&country=US&isMale=0&height=1.5&dob=range('1980-01-01','1990-01-01')'
然后我只看到以下日志消息(其中 MyAppAuditor
发送审核事件):
{ "timestamp" : "14:09:50.516", "thread" : "qtp1293252487-17", "level" : "INFO", "logger" : "com.myapp.ws.shared.auditing.MyAppAuditor", "message" : {"timestamp":"2018-06-29T18:09:50+0000","principal":"SomeUser","type":"http.request.trace","data":{"method":"GET","path":"/v1/data/profiles","headers":{"request":{"User-Agent":"curl/7.54.0","Host":"localhost:9200","Accept":"*/*","Content-Type":"application/json"},"response":{"X-Frame-Options":"DENY","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","Pragma":"no-cache","Expires":"0","X-XSS-Protection":"1; mode=block","X-Application-Context":"application:9200","Date":"Fri, 29 Jun 2018 18:09:50 GMT","Content-Type":"application/json;charset=utf-8","status":"200"}},"timeTaken":"89"}} }
如您所见,审核员正在选择基本路径 (/v1/data/profiles
),但未记录任何查询字符串参数。当我点击 POST 或 PUT 确实需要请求正文的端点 (JSON) 时,我也看到类似的请求正文信息缺失。
我需要做什么来配置这些 类(或其他 Spring classes/configs),以便我获得我想要的请求审核级别我在找什么?
幸运的是,Actuator 使配置这些 Trace
事件变得非常容易。
添加参数到跟踪信息
您可以 take a look 所有选项。您会注意到默认值 (line 42
) 是:
Include.REQUEST_HEADERS,
Include.RESPONSE_HEADERS,
Include.COOKIES,
Include.ERRORS,
Include.TIME_TAKEN
因此您还需要添加 Include.PARAMETERS
以及您希望在跟踪中包含的任何其他内容。要配置它,management.trace.include
.
因此,要获得您想要的(即 parameters
),加上默认值,您需要:
management.trace.include = parameters, request-headers, response-headers, cookies, errors, time-taken
添加请求正文到跟踪信息
为了获得 body
,您必须将此 Bean
添加到您的 Context
:
@Component
public class WebRequestTraceFilterWithPayload extends WebRequestTraceFilter {
public WebRequestTraceFilterWithPayload(TraceRepository repository, TraceProperties properties) {
super(repository, properties);
}
@Override
protected Map<String, Object> getTrace(HttpServletRequest request) {
Map<String, Object> trace = super.getTrace(request);
String body = null;
try {
body = request.getReader().lines().collect(Collectors.joining("\n"));
} catch (IOException e) {
throw new RuntimeException(e);
}
if(body != null) {
trace.put("body", body);
}
return trace;
}
}
上面的代码将覆盖 AutoConfigure'd
WebRequestTraceFilter
bean(因为它是 @ConditionalOnMissingBean
将尊重您的自定义 bean),并提取额外的有效负载 属性 关闭 request
,然后将其添加到发布到 TraceRepository
!
Map
属性
总结
- 请求参数 可以通过
management.trace.include
属性 添加到 - 请求主体可以通过创建扩展
Bean
添加到TraceRepository trace events
以读取HTTP请求的body
并补充跟踪事件
TraceRepository trace events