接入skywalking和elk指南

83 阅读4分钟

概述

思考如下几个问题:

微服务组件几十个,怎么去看某个请求的日志?难道要登录一台一台机器去手工tail?

甚至都不知道该请求经过了哪几个服务?

该请求经过的每个微服务的耗时多少?瓶颈在哪个服务?

elk是有了,但还是不能愉快的查看某个请求链路的所有日志?怎么定义某个请求?

elk展示的时间不对,并不是实际日志的时间?

elk中java异常栈显示异常,怎么是一行一行的?

本篇文章就是解决上述所有问题

一些约定

使用elk技术栈来收集和展示日志

这里定义了一些规范:

标签

在filebeat端,设置tag,示例如下:

tags: ["crm", "member"]

增加了2个tag

第一个是子部门的名称,CRM子部门为:crm,IOT子部门为:iot

第二个是应用的名称,比如member是会员服务,shop为商城名称,一般和git中该项目的名称一样即可

tags会在查询日志时用到,后续会说明

这个操作不需要开发人员自己操作

field

日志收集时统一加上ip地址,可以方便定位到某台具体的机器

这个操作不需要开发人员自己操作

其他

线上严禁乱打日志,所有日志需调整为warn或者warn级别以上

确有线上排查问题需求,去对应的springboot admin中临时调整日志级别即可,排查完后记得调整回来

改造

官方的log4j2和logback插件,打印的traceId竟然格式不一致,一个有空格一个没有空格

导致在elk收集时,由于分词的原因,对logback的日志不能很好的进行搜索

log4j2

image2022-6-8_16-28-12.png

logback

image2022-6-8_16-28-24.png

其实对于没有空格的,仍然可以用通配符*的方式进行搜索,只是略为麻烦一点

故进行改造,使得logback的日志也有空格

image2022-6-8_16-29-45.png

filter

上述只是在日志中打印了traceId,我怎么知道线上的某个请求的traceId是多少呢

使用拦截器即可,代码示例如下:

public class TraceFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        MDC.put("uri", req.getRequestURI());
        resp.addHeader("traceId", TraceContext.traceId());

        try {
            filterChain.doFilter(req, servletResponse);
        } finally {
            MDC.remove("uri");
        }
    }
}

这样就可以在响应头中愉快的找到traceId了

image2022-3-21_14-27-37.png

查询链路和日志最佳实践

skywalking

最经典的操作即是根据上述获取traceId,然后根据traceId来查询链路

image2022-3-21_14-49-16.png

kibana

根据traceId来搜索全链路日志

image2022-3-21_14-51-4.png 如果所有子部门都接入了skywaking和elk,那么跨子部门调用的日志也全部都会有

搜索某个子部门日志

可以根据上述配置的tag来搜索日志,比如只想搜索某个部门的日志,比如crm,那么tags设置为crm即可

image2022-3-21_14-53-47.png 也可以直接在左侧过滤字段

image2022-3-21_14-54-53.png 效果如下:

image2022-3-21_14-54-53.png

搜索某个应用日志

操作类似上面

image2022-3-21_14-54-53.png

时间筛选

image2022-3-21_14-57-58.png

机器筛选

image2022-3-21_14-57-58.png

图表

在图表中可以清晰的看到某个时间点的日志量

image2022-3-21_14-58-31.png

不喜欢图表可以关掉

image2022-3-21_14-59-11.png

查询说明和优化

目前,所有部门的所有组件都使用一个索引,只是按天来滚动,然后我们建立了一个log*的索引模式,这样搜索时默认使用这一个

这样所有组件都是通的,根据一个traceid,即可跨所有组件来搜索相关的日志

image2022-7-7_11-29-50.png

如果要根据部门,或者组件来搜索,上面其他章节也进行说明了

但是,如果不知道的话,会发现每次进来都要重新输入搜索条件,较为繁琐

其实,搜索条件是可以保存的

image2022-7-7_11-34-13.png

image2022-7-7_11-34-40.png

image2022-7-7_11-35-4.png 这样可以快速复用已保存的搜索条件,而不用每次都输入

索引模式优化

除了上述可以保存搜索条件,我们对索引模式也进行了优化

每个服务的名称以 部门-组件-日期 分别建立索引
然后建立索引模式:部门*,部门-组件*,和*
这样可以按照,部门,组件,或者全部的维度来搜索

以测试环境的dfs组件为例:

生成的索引名称为:crm-dfs-2023.07.07

然后分别建立索引模式:crm*,crm-dfs,如下图

image2022-7-7_11-40-5.png

这样,如果只想搜索dfs该组件的日志,选择crm-dfs即可,如果想搜索crm部门的日志,选择crm即可,想搜索全部部门的人日志选择