ELK 收集服务器日志

2021-10-26/2021-12-15
0 评论 88 浏览

参考文档你居然还去服务器上捞日志,搭个日志收集系统难道不香么!

1. ELK 环境搭建

此处使用 docker-compose 搭建

首先新建两个配置文件

1# ~/dockerData/kibana/config/kibana.yml
2server.name: kibana
3server.host: "0"
4elasticsearch.hosts: [ "http://elasticsearch:9200" ]
5i18n.locale: "zh-CN"
6
7# ~/dockerData/logstash/logstash.conf
8# 查看下文 logstash 配置

docker-compose 脚本

 1version: '3'
 2services:
 3  elasticsearch:
 4    image: elasticsearch:7.6.2
 5    container_name: elasticsearch
 6    environment:
 7      - "cluster.name=elasticsearch" #设置集群名称为elasticsearch
 8      - "discovery.type=single-node" #以单一节点模式启动
 9      - "ES_JAVA_OPTS=-Xms512m -Xmx512m" #设置使用jvm内存大小
10      - TZ=Asia/Shanghai
11    volumes:
12      - ~/dockerData/elasticsearch/plugins:/usr/share/elasticsearch/plugins #插件文件挂载
13      - ~/dockerData/elasticsearch/data:/usr/share/elasticsearch/data #数据文件挂载
14    ports:
15      - 9200:9200
16      - 9300:9300
17  kibana:
18    image: kibana:7.6.2
19    container_name: kibana
20    links:
21      - elasticsearch:es #可以用es这个域名访问elasticsearch服务
22    depends_on:
23      - elasticsearch #kibana在elasticsearch启动之后再启动
24    environment:
25      - "elasticsearch.hosts=http://es:9200" #设置访问elasticsearch的地址
26      - TZ=Asia/Shanghai
27    volumes:
28      - ~/dockerData/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml
29    ports:
30      - 5601:5601
31  logstash:
32    image: logstash:7.6.2
33    container_name: logstash
34    environment:
35      - TZ=Asia/Shanghai
36    volumes:
37      - ~/dockerData/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf #挂载logstash的配置文件
38    depends_on:
39      - elasticsearch #kibana在elasticsearch启动之后再启动
40    links:
41      - elasticsearch:es #可以用es这个域名访问elasticsearch服务
42    ports:
43      - 4560:4560
44      - 4561:4561
45      - 4562:4562
46      - 4563:4563

启动

1docker-compose up -d

logstash 安装 json_lines 插件

1docker exec -it logstash /bin/sh
2logstash-plugin install logstash-codec-json_lines

环境部署完毕

第一次启动可能会发现 Elasticsearch 无法启动,那是因为~/dockerData/elasticsearch/data目录没有访问权限,只需要修改权限,再重新启动。

2. 分场景收集日志

这里为了方便我们查看日志,提出一个分场景收集日志的概念,把日志分为以下四种。

  • 调试日志:最全日志,包含了应用中所有DEBUG级别以上的日志,仅在开发、测试环境中开启收集;
  • 错误日志:只包含应用中所有ERROR级别的日志,所有环境只都开启收集;
  • 业务日志:在我们应用对应包下打印的日志,可用于查看我们自己在应用中打印的业务日志;
  • 记录日志:每个接口的访问记录,可以用来查看接口执行效率,获取接口访问参数。

3. Logback 配置详解

在 SpringBoot 中,如果我们想要自定义 Logback 的配置,需要自行编写logback-spring.xml文件,下面是我们这次要使用的完全配置。

  1<?xml version="1.0" encoding="UTF-8"?>
  2<!DOCTYPE configuration>
  3<configuration>
  4    <!--引用默认日志配置-->
  5    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
  6    <!--使用默认的控制台日志输出实现-->
  7    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
  8    <!--应用名称-->
  9    <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
 10    <!--日志文件保存路径-->
 11    <property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/>
 12    <!--LogStash访问host-->
 13    <springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="localhost"/>
 14
 15    <!--DEBUG日志输出到文件-->
 16    <appender name="FILE_DEBUG"
 17              class="ch.qos.logback.core.rolling.RollingFileAppender">
 18        <!--输出DEBUG以上级别日志-->
 19        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
 20            <level>DEBUG</level>
 21        </filter>
 22        <encoder>
 23            <!--设置为默认的文件日志格式-->
 24            <pattern>${FILE_LOG_PATTERN}</pattern>
 25            <charset>UTF-8</charset>
 26        </encoder>
 27        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
 28            <!--设置文件命名格式-->
 29            <fileNamePattern>${LOG_FILE_PATH}/debug/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
 30            <!--设置日志文件大小,超过就重新生成文件,默认10M-->
 31            <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
 32            <!--日志文件保留天数,默认30天-->
 33            <maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
 34        </rollingPolicy>
 35    </appender>
 36
 37    <!--ERROR日志输出到文件-->
 38    <appender name="FILE_ERROR"
 39              class="ch.qos.logback.core.rolling.RollingFileAppender">
 40        <!--只输出ERROR级别的日志-->
 41        <filter class="ch.qos.logback.classic.filter.LevelFilter">
 42            <level>ERROR</level>
 43            <onMatch>ACCEPT</onMatch>
 44            <onMismatch>DENY</onMismatch>
 45        </filter>
 46        <encoder>
 47            <!--设置为默认的文件日志格式-->
 48            <pattern>${FILE_LOG_PATTERN}</pattern>
 49            <charset>UTF-8</charset>
 50        </encoder>
 51        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
 52            <!--设置文件命名格式-->
 53            <fileNamePattern>${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
 54            <!--设置日志文件大小,超过就重新生成文件,默认10M-->
 55            <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
 56            <!--日志文件保留天数,默认30天-->
 57            <maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
 58        </rollingPolicy>
 59    </appender>
 60
 61    <!--DEBUG日志输出到LogStash-->
 62    <appender name="LOG_STASH_DEBUG" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
 63        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
 64            <level>DEBUG</level>
 65        </filter>
 66        <destination>${LOG_STASH_HOST}:4560</destination>
 67        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
 68            <providers>
 69                <timestamp>
 70                    <timeZone>Asia/Shanghai</timeZone>
 71                </timestamp>
 72                <!--自定义日志输出格式-->
 73                <pattern>
 74                    <pattern>
 75                        {
 76                        "project": "mall-tiny",
 77                        "level": "%level",
 78                        "service": "${APP_NAME:-}",
 79                        "pid": "${PID:-}",
 80                        "thread": "%thread",
 81                        "class": "%logger",
 82                        "message": "%message",
 83                        "stack_trace": "%exception{20}"
 84                        }
 85                    </pattern>
 86                </pattern>
 87            </providers>
 88        </encoder>
 89        <!--当有多个LogStash服务时,设置访问策略为轮询-->
 90        <connectionStrategy>
 91            <roundRobin>
 92                <connectionTTL>5 minutes</connectionTTL>
 93            </roundRobin>
 94        </connectionStrategy>
 95    </appender>
 96
 97    <!--ERROR日志输出到LogStash-->
 98    <appender name="LOG_STASH_ERROR" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
 99        <filter class="ch.qos.logback.classic.filter.LevelFilter">
100            <level>ERROR</level>
101            <onMatch>ACCEPT</onMatch>
102            <onMismatch>DENY</onMismatch>
103        </filter>
104        <destination>${LOG_STASH_HOST}:4561</destination>
105        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
106            <providers>
107                <timestamp>
108                    <timeZone>Asia/Shanghai</timeZone>
109                </timestamp>
110                <!--自定义日志输出格式-->
111                <pattern>
112                    <pattern>
113                        {
114                        "project": "mall-tiny",
115                        "level": "%level",
116                        "service": "${APP_NAME:-}",
117                        "pid": "${PID:-}",
118                        "thread": "%thread",
119                        "class": "%logger",
120                        "message": "%message",
121                        "stack_trace": "%exception{20}"
122                        }
123                    </pattern>
124                </pattern>
125            </providers>
126        </encoder>
127        <!--当有多个LogStash服务时,设置访问策略为轮询-->
128        <connectionStrategy>
129            <roundRobin>
130                <connectionTTL>5 minutes</connectionTTL>
131            </roundRobin>
132        </connectionStrategy>
133    </appender>
134
135    <!--业务日志输出到LogStash-->
136    <appender name="LOG_STASH_BUSINESS" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
137        <destination>${LOG_STASH_HOST}:4562</destination>
138        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
139            <providers>
140                <timestamp>
141                    <timeZone>Asia/Shanghai</timeZone>
142                </timestamp>
143                <!--自定义日志输出格式-->
144                <pattern>
145                    <pattern>
146                        {
147                        "project": "mall-tiny",
148                        "level": "%level",
149                        "service": "${APP_NAME:-}",
150                        "pid": "${PID:-}",
151                        "thread": "%thread",
152                        "class": "%logger",
153                        "message": "%message",
154                        "stack_trace": "%exception{20}"
155                        }
156                    </pattern>
157                </pattern>
158            </providers>
159        </encoder>
160        <!--当有多个LogStash服务时,设置访问策略为轮询-->
161        <connectionStrategy>
162            <roundRobin>
163                <connectionTTL>5 minutes</connectionTTL>
164            </roundRobin>
165        </connectionStrategy>
166    </appender>
167
168    <!--接口访问记录日志输出到LogStash-->
169    <appender name="LOG_STASH_RECORD" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
170        <destination>${LOG_STASH_HOST}:4563</destination>
171        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
172            <providers>
173                <timestamp>
174                    <timeZone>Asia/Shanghai</timeZone>
175                </timestamp>
176                <!--自定义日志输出格式-->
177                <pattern>
178                    <pattern>
179                        {
180                        "project": "mall-tiny",
181                        "level": "%level",
182                        "service": "${APP_NAME:-}",
183                        "class": "%logger",
184                        "message": "%message"
185                        }
186                    </pattern>
187                </pattern>
188            </providers>
189        </encoder>
190        <!--当有多个LogStash服务时,设置访问策略为轮询-->
191        <connectionStrategy>
192            <roundRobin>
193                <connectionTTL>5 minutes</connectionTTL>
194            </roundRobin>
195        </connectionStrategy>
196    </appender>
197
198    <!--控制框架输出日志-->
199    <logger name="org.slf4j" level="INFO"/>
200    <logger name="springfox" level="INFO"/>
201    <logger name="io.swagger" level="INFO"/>
202    <logger name="org.springframework" level="INFO"/>
203    <logger name="org.hibernate.validator" level="INFO"/>
204
205    <root level="DEBUG">
206        <appender-ref ref="CONSOLE"/>
207        <!--<appender-ref ref="FILE_DEBUG"/>-->
208        <!--<appender-ref ref="FILE_ERROR"/>-->
209        <appender-ref ref="LOG_STASH_DEBUG"/>
210        <appender-ref ref="LOG_STASH_ERROR"/>
211    </root>
212
213    <logger name="com.macro.mall.tiny.component" level="DEBUG">
214        <appender-ref ref="LOG_STASH_RECORD"/>
215    </logger>
216
217    <logger name="com.macro.mall" level="DEBUG">
218        <appender-ref ref="LOG_STASH_BUSINESS"/>
219    </logger>
220</configuration>

使用默认的日志配置

一般我们不需要自定义控制台输出,可以采用默认配置,具体配置参考console-appender.xml,该文件在spring-boot-${version}.jar下面。

1<!--引用默认日志配置-->
2<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
3<!--使用默认的控制台日志输出实现-->
4<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>

springProperty

该标签可以从 SpringBoot 的配置文件中获取配置属性,比如说在不同环境下我们的 Logstash 服务地址是不一样的,我们就可以把该地址定义在 application.yml 来使用。

例如在application-dev.yml中定义了这些属性:

1logstash:
2  host: localhost

logback-spring.xml中就可以直接这样使用:

1<!--应用名称-->
2<springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
3<!--LogStash访问host-->
4<springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="localhost"/>

filter

在Logback中有两种不同的过滤器,用来过滤日志输出。

ThresholdFilter:临界值过滤器,过滤掉低于指定临界值的日志,比如下面的配置将过滤掉所有低于INFO级别的日志。

1<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
2    <level>INFO</level>
3</filter>

LevelFilter:级别过滤器,根据日志级别进行过滤,比如下面的配置将过滤掉所有非ERROR级别的日志。

1<filter class="ch.qos.logback.classic.filter.LevelFilter">
2    <level>ERROR</level>
3    <onMatch>ACCEPT</onMatch>
4    <onMismatch>DENY</onMismatch>
5</filter>

appender

Appender可以用来控制日志的输出形式,主要有下面三种。

  • ConsoleAppender:控制日志输出到控制台的形式,比如在console-appender.xml中定义的默认控制台输出。
1<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
2    <encoder>
3        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
4    </encoder>
5</appender>
  • RollingFileAppender:控制日志输出到文件的形式,可以控制日志文件生成策略,比如文件名称格式、超过多大重新生成文件以及删除超过多少天的文件。
 1<!--ERROR日志输出到文件-->
 2<appender name="FILE_ERROR"
 3          class="ch.qos.logback.core.rolling.RollingFileAppender">
 4    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
 5        <!--设置文件命名格式-->
 6        <fileNamePattern>${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
 7        <!--设置日志文件大小,超过就重新生成文件,默认10M-->
 8        <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
 9        <!--日志文件保留天数,默认30天-->
10        <maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
11    </rollingPolicy>
12</appender>
  • LogstashTcpSocketAppender:控制日志输出到Logstash的形式,可以用来配置Logstash的地址、访问策略以及日志的格式。
 1<!--ERROR日志输出到LogStash-->
 2<appender name="LOG_STASH_ERROR" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
 3    <destination>${LOG_STASH_HOST}:4561</destination>
 4    <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
 5        <providers>
 6            <timestamp>
 7                <timeZone>Asia/Shanghai</timeZone>
 8            </timestamp>
 9            <!--自定义日志输出格式-->
10            <pattern>
11                <pattern>
12                    {
13                    "project": "mall-tiny",
14                    "level": "%level",
15                    "service": "${APP_NAME:-}",
16                    "pid": "${PID:-}",
17                    "thread": "%thread",
18                    "class": "%logger",
19                    "message": "%message",
20                    "stack_trace": "%exception{20}"
21                    }
22                </pattern>
23            </pattern>
24        </providers>
25    </encoder>
26    <!--当有多个LogStash服务时,设置访问策略为轮询-->
27    <connectionStrategy>
28        <roundRobin>
29            <connectionTTL>5 minutes</connectionTTL>
30        </roundRobin>
31    </connectionStrategy>
32</appender>

logger

只有配置到logger节点上的appender才会被使用,logger用于配置哪种条件下的日志被打印,root是一种特殊的appender,下面介绍下日志划分的条件。

  • 调试日志:所有的DEBUG级别以上日志;
  • 错误日志:所有的ERROR级别日志;
  • 业务日志:com.macro.mall包下的所有DEBUG级别以上日志;
  • 记录日志:com.macro.mall.tiny.component.WebLogAspect类下所有DEBUG级别以上日志,该类是统计接口访问信息的AOP切面类。

控制框架输出日志

还有一些使用框架内部的日志,DEBUG级别的日志对我们并没有啥用处,都可以设置为了INFO以上级别。

1<!--控制框架输出日志-->
2<logger name="org.slf4j" level="INFO"/>
3<logger name="springfox" level="INFO"/>
4<logger name="io.swagger" level="INFO"/>
5<logger name="org.springframework" level="INFO"/>
6<logger name="org.hibernate.validator" level="INFO"/>

4. logstash 配置

 1input {
 2  tcp {
 3    mode => "server"
 4    host => "0.0.0.0"
 5    port => 4560
 6    codec => json_lines
 7    type => "debug"
 8  }
 9  tcp {
10    mode => "server"
11    host => "0.0.0.0"
12    port => 4561
13    codec => json_lines
14    type => "error"
15  }
16  tcp {
17    mode => "server"
18    host => "0.0.0.0"
19    port => 4562
20    codec => json_lines
21    type => "business"
22  }
23  tcp {
24    mode => "server"
25    host => "0.0.0.0"
26    port => 4563
27    codec => json_lines
28    type => "record"
29  }
30}
31filter{
32  if [type] == "record" {
33    mutate {
34      remove_field => "port"
35      remove_field => "host"
36      remove_field => "@version"
37    }
38    json {
39      source => "message"
40      remove_field => ["message"]
41    }
42  }
43}
44output {
45  elasticsearch {
46    hosts => ["es:9200"]
47    action => "index"
48    codec => json
49    index => "mall-tiny-%{type}-%{+YYYY.MM.dd}"
50    template_name => "mall-tiny"
51  }
52}
  • input:使用不同端口收集不同类型的日志,从4560~4563开启四个端口;
  • filter:对于记录类型的日志,直接将JSON格式的message转化到source中去,便于搜索查看;
  • output:按类型、时间自定义索引格式。

5. SpringBoot 配置

在SpringBoot中的配置可以直接用来覆盖Logback中的配置,比如logging.level.root就可以覆盖<root>节点中的level配置。

1logstash:
2  host: localhost
3logging:
4  level:
5    root: debug

最后在 Kibana 中创建索引后即可查看


标题:ELK 收集服务器日志
作者:Rainsheep
地址:https://www.rainsheep.cn/articles/2021/10/26/1635249927038.html

评论
发表评论
       
       
取消