【发布时间】:2020-11-23 16:02:17
【问题描述】:
我在 elastic.co 上玩 ELK 堆栈,现在我已经敲了 5 个小时的头(尽管阅读了文档和文档)。
所以我有一个 Spring Boot API,它写入一个 JSON 日志文件。该日志文件由 filebeat 获取并发送到 Elastic.co ELK 堆栈,在那里我可以在 Kibana 中查看数据。
在我的 API 中,我有一个过滤器类,它向日志中添加了一些值,例如响应代码等(如下所示),但是我看到的是,在 Kibana 中,这些 MDC 值实际上是在消息中而不是独立字段中。
正确吗?还是我需要做一个 Grok 过滤器?如果 Grok 是要走的路,我一直在尝试并未能从消息中提取所有内容。
在我真正失去理智之前,任何人都可以帮助/阐明一些观点:D
@Order(1)
@Component
public class MDCFilter implements Filter {
private final Logger LOGGER = LoggerFactory.getLogger(MDCFilter.class);
private final String X_REQUEST_ID = "X-Request-ID";
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
try {
addXRequestId(req);
LOGGER.info("path: {}, method: {}, query {}",
req.getRequestURI(), req.getMethod(), req.getQueryString());
res.setHeader(X_REQUEST_ID, MDC.get(X_REQUEST_ID));
chain.doFilter(request, response);
} finally {
MDC.put("api.version", req.getContextPath());
MDC.put("Server.IP", req.getServerName());
MDC.put("API.Controller", req.getServletPath());
MDC.put("Response.code", String.valueOf(res.getStatus()));
MDC.put("Request.Method.Type", req.getMethod());
LOGGER.info("statusCode {}, path: {}, method: {}, query {}, context {}, serverName {}, RequestURI {}, RemoteHost {}, Cookies {}",
res.getStatus(), req.getRequestURI(), req.getMethod(), req.getQueryString(), req.getContextPath(),
req.getServerName(), req.getRequestURI(), request.getRemoteAddr(),
req.getCookies());
MDC.clear();
}
}
private void addXRequestId(HttpServletRequest request) {
String xRequestId = request.getHeader(X_REQUEST_ID);
if (xRequestId == null) {
MDC.put(X_REQUEST_ID, UUID.randomUUID().toString());
} else {
MDC.put(X_REQUEST_ID, xRequestId);
}
}
}
这是我的日志的输出:
{"@timestamp":"2020-11-23T10:31:09.010Z", "log.level": "INFO", "message":"statusCode 200, path: /test/service/feed/, method: GET, query null, context /api/v1, serverName localhost, RequestURI /test/service/feed/, RemoteHost 0:0:0:0:0:0:0:1, Cookies null", "service.name":"test-spring-project","event.dataset":"test-service.log","process.thread.name":"http-nio-8080-exec-8","log.logger":"com.example.filter.MDCFilter","api.version":"/api/v1","API.Controller":"/test/service/feed/","Request.Method.Type":"GET","Response.code":"200","Server.IP":"localhost"}
【问题讨论】:
-
这可能是关于设置 ELK 堆栈以将您的消息视为 JSON - 现在似乎没有意识到它们是 JSON 并将它们作为纯字符串行处理的事实。但是您的服务产生的输出似乎很好。不过,不确定这是如何在 ELK 上完成的。
-
我想你可能正在做点什么。现在可能是我需要应用注入管道。任何人都知道如何使用 Filebeat 来做到这一点(我没有使用 logstash)。谢谢你的回复顺便说一句!!
-
好的,感谢 Jan 的帮助。所以基本上你是对的!我必须设置一个摄取管道来解析 JSON。再次感谢您
标签: spring spring-boot kibana elastic-stack