| | |
| | | package com.vincent.rsf.httpaudit.service; |
| | | |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.vincent.rsf.httpaudit.entity.HttpAuditLog; |
| | | import com.vincent.rsf.httpaudit.mapper.HttpAuditLogMapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | |
| | | import java.util.LinkedHashMap; |
| | | import java.util.Map; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 异步落库;失败时打全量日志,不向业务抛错 |
| | | * 异步写入已配置的日志目标;单路失败不影响其他路与业务 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class HttpAuditAsyncRecorder { |
| | | |
| | | private final HttpAuditLogMapper httpAuditLogMapper; |
| | | private final ObjectMapper objectMapper = new ObjectMapper(); |
| | | private final List<HttpAuditLogSink> sinks; |
| | | |
| | | public HttpAuditAsyncRecorder(List<HttpAuditLogSink> sinks) { |
| | | this.sinks = sinks; |
| | | } |
| | | |
| | | @Async("httpAuditExecutor") |
| | | public void save(HttpAuditLog entity) { |
| | | try { |
| | | httpAuditLogMapper.insert(entity); |
| | | } catch (Throwable t) { |
| | | try { |
| | | Map<String, Object> dump = new LinkedHashMap<>(); |
| | | dump.put("serviceName", entity.getServiceName()); |
| | | dump.put("scopeType", entity.getScopeType()); |
| | | dump.put("uri", entity.getUri()); |
| | | dump.put("method", entity.getMethod()); |
| | | dump.put("functionDesc", entity.getFunctionDesc()); |
| | | dump.put("queryString", entity.getQueryString()); |
| | | dump.put("requestBody", entity.getRequestBody()); |
| | | dump.put("responseBody", entity.getResponseBody()); |
| | | dump.put("httpStatus", entity.getHttpStatus()); |
| | | dump.put("okFlag", entity.getOkFlag()); |
| | | dump.put("spendMs", entity.getSpendMs()); |
| | | dump.put("clientIp", entity.getClientIp()); |
| | | dump.put("errorMessage", entity.getErrorMessage()); |
| | | String json = objectMapper.writeValueAsString(dump); |
| | | log.error("http-audit 落库失败,全量JSON如下:{}", json, t); |
| | | } catch (JsonProcessingException je) { |
| | | log.error("http-audit 落库失败且序列化审计内容失败,requestBody.length={}, responseBody.length={}", |
| | | entity.getRequestBody() == null ? -1 : entity.getRequestBody().length(), |
| | | entity.getResponseBody() == null ? -1 : entity.getResponseBody().length(), |
| | | t); |
| | | log.error("序列化异常", je); |
| | | } |
| | | for (HttpAuditLogSink sink : sinks) { |
| | | sink.write(entity); |
| | | } |
| | | } |
| | | } |