Linux运维日志收集ELKStack安装部署

ELK Stack简介

对于日志来说,最常见的需求就是收集、存储、查询、展示,开源社区正好有相对应的开源项目:logstash(收集)、elasticsearch(存储+搜索)、kibana(展示),我们将这三个组合起来的技术称之为ELKStack,所以说ELKStack指的是Elasticsearch、Logstash、Kibana技术栈的结合。

Elasticsearch介绍及安装

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二流行的企业搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

Elasticsearch部署 Elasticsearch首先需要Java环境,所以需要提前安装好JDK,可以直接使用yum安装。也可以从Oracle官网下载JDK进行安装。开始之前要确保JDK正常安装并且环境变量也配置正确: 安装JDK。

1
2
3
4
5
yum -y install java
java --version #确认java环境
## 下载5.6版本
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.16.rpm
sudo rpm -ivh elasticsearch-5.6.16.rpm

编辑配置文件

vim /etc/elasticsearch/elasticsearch.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cluster.name: my-application    elk集群名称
node.name: node-1 elk节点名
path.data: /var/lib/elasticsearch/ elk数据存放目录
path.logs: /var/log/elasticsearch/ elk日志存放目录
bootstrap.memory_lock: true 内存缓存
#开启内存缓存启动失败时,需要在/usr/lib/systemd/system/elasticsearch.service"添加
#LimitMEMLOCK=infinity

network.host: 100.1.1.11 监听网卡
http.port: 9200 监听端口
discovery.zen.ping.unicast.hosts: ["100.1.1.11", "100.1.1.12"] 组播
#head访问时5.x以上需要配置
http.cors.enabled: true 开启HTTP访问
http.cors.allow-origin: "*" 允许的网段

集群配置

安装kibana

Kibana 是为 Elasticsearch设计的开源分析和可视化平台。你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互。你可以很容易实现高级的数据分析和可视化,以图标的形式展现出来。

1
2
3
4
5
6
cd /server/tools
yum -y install java-1.8.0-openjdk
wget https://artifacts.elastic.co/downloads/kibana/kibana-5.6.0-x86_64.rpm
rpm -ivh kibana-5.6.0-x86_64.rpm
rpm -qc kibana
/etc/kibana/kibana.yml ### 安装成功

编辑配置文件

1
2
3
4
5
6
7
8
9
10
11
egrep -v "#|^$" /etc/kibana/kibana.yml
server.port: 5601
server.host: "100.1.1.11"
server.name: "redis01"
elasticsearch.url: "http://100.1.1.11:9200"
kibana.index: ".kibana"

### 启动
systemctl daemon-reload
systemctl enable kibana.service
systemctl start kibana.service

安装filebeat

Filebeat是本地文件的日志数据采集器,可监控日志目录或特定日志文件(tail file),并将它们转发给Elasticsearch或Logstatsh进行索引、kafka等。带有内部模块(auditd,Apache,Nginx,System和MySQL),可通过一个指定命令来简化通用日志格式的收集,解析和可视化。

1
2
3
4
5
cd /server/tools
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.6.0-x86_64.rpm
rpm -ivh filebeat-5.6.0-x86_64.rpm
rpm -qc filebeat
/etc/filebeat/filebeat.yml ### 安装完成

nginx日志收集配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
######################INPUTS#############
filebeat.prospectors:
- input_type: log #日志类型
enabled: true # 开启日志收集
paths: # 日志路径
- /var/log/nginx/access.log
json.keys_under_root: true # json 格式
json.add_error_key: true

######################OUTPUT#############
output.elasticsearch:
hosts: ["100.1.1.11:9200"] # es地址
index: "nginx-%{+yyyy.MM}" #创建索引模板
#7.0 index: "filebeat-%{[agent.version]}-%{+yyyy.MM.dd}"
#6.0 index: "filebeat-%{[beat.version]}-%{+yyyy.MM.dd}"
setup.template.name: "nginx" #模板名称
setup.template.pattern: "nginx-*" # 设置默认模板
setup.template.enabled: false #禁止模板加载

filebeat创建索引模板
filebeat output配置

NGINX访问日志和错误日志收集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
######################INPUTS#############
filebeat.prospectors:
- input_type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.add_error_key: true
tags: ["access"] # 添加标签
- input_type: log
paths:
- /var/log/nginx/error.log
tags: ["error"]

######################OUTPUT#############
output.elasticsearch:
hosts: ["100.1.1.11:9200"]
indices:
- index: "nginx-access-%{+yyyy.MM}"
when.contains: # 筛选条件
tags: "access" # 通过标签来选择
- index: "nginx-error-%{+yyyy.MM}"
when.contains:
tags: "error"
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false

tags标签使用方法

tomcat日志收集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
##  安装tomcat
yum install tomcat tomcat-webapps tomcat-admin-webapps
rpm -qc tomcat
vim /etc/tomcat/tomcat.conf
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_" suffix=".log"
pattern="{&quot;client&quot;:&quot;%h&quot;, &quot;client user&quot;:&quot;%l&quot;, &quot;authenticated&quot;:&quot;%u&quot;, &quot;access time&quot;:&quot;%t&quot;, &quot;method&quot;:&quot;%r&quot;, &quot;status&quot;:&quot;%s&quot;, &quot;send bytes&quot;:&quot;%b&quot;, &quot;Query?string&quot;:&quot;%q&quot;, &quot;partner&quot;:&quot;%{Referer}i&quot;, &quot;Agent version&quot;:&quot;%{User-Agent}i&quot;}"/>
## 以上配置文件在135行

### 编辑filebeat配置文件

######################INPUTS#############
filebeat.prospectors:
- input_type: log
enabled: true
paths:
- /var/log/tomcat/localhost_access_*.log
json.keys_under_root: true
json.add_error_key: true
tags: ["tomcat"]
######################OUTPUT#############
output.elasticsearch:
hosts: ["100.1.1.11:9200"]
#index: "nginx-%{+yyyy.MM}"
indices:
- index: "tomcat-access-%{+yyyy.MM}"
when.contains:
tags: "tomcat"
setup.template.name: "tomcat"
setup.template.pattern: "tomcat-*"
setup.template.enabled: false

收集java日志

收集Elasticsearch日志

1
2
3
[2020-05-28T15:37:37,594][INFO ][o.e.n.Node               ] [node-1] JVM arguments [-Xms2g, -Xmx2g, -XX:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -XX:+AlwaysPreTouch, -Xss1m, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -Djna.nosys=true, -Djdk.io.permissionsUseCanonicalPath=true, -Dio.netty.noUnsafe=true, -Dio.netty.noKeySetOptimization=true, -Dio.netty.recycler.maxCapacityPerThread=0, -Dlog4j.shutdownHookEnabled=false, -Dlog4j2.disable.jmx=true, -Dlog4j.skipJansi=true, -XX:+HeapDumpOnOutOfMemoryError, -Des.path.home=/usr/share/elasticsearch]
[2020-05-28T15:37:42,736][INFO ][o.e.p.PluginsService ] [node-1] loaded module [aggs-matrix-stats]
[2020-05-28T15:37:42,736][INFO ][o.e.p.PluginsService ] [node-1] loaded module [ingest-common]

读取“[时间”开头,读取下一行如果不是“[时间”开头会缓存到上一条,继续读取,直到读取到”[时间”开头,会把前面所有缓存的内容归属于上面一条发送。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
######################ES#############
filebeat.prospectors:
- input_type: log
enabled: true
paths:
- /var/log/elasticsearch/elasticsearch.log
tags: ["es"]
multiline.pattern: '^\[' # 匹配以什么开头
multiline.negate: true #
multiline.match: after
######################OUTPUT#############
output.elasticsearch:
hosts: ["100.1.1.11:9200"]
indices:
- index: "es-acc-%{+yyyy.MM}"
when.contains:
tags: "es"
setup.template.name: "es"
setup.template.pattern: "es-*"
setup.template.enabled: false

先以b开始匹配如果不是算在这一条,如果是b开头就属于下一条。

docker容器日志收集

安装docker-compose

1
2
3
yum -y install epel-release
yum -y install python-pip
pip install docker-compose

使用docker-compose创建容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3'
services:
db:
image: mysql:5.7
# 设置labels
labels:
service: db
# logging设置增加labels.service
logging:
options:
labels: "service"
ports:
- "3306:3306"
nginx:
image: nginx:latest
# 设置labels
labels:
service: nginx
# logging设置增加labels.service
logging:
options:
labels: "service"
ports:
- "80:80"

filebeat日志收集

filebeat在6.0后才能使用docker类型的日志收集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
######################INPUTS#############
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/lib/docker/containers/*/*-json.log
json.keys_under_root: true
json.add_error_key: true

######################OUTPUT#############
output.elasticsearch:
hosts: ["100.1.1.11:9200"]
#index: "nginx-%{+yyyy.MM}"
indices:
- index: "docker-ng-acc-%{+yyyy.MM}"
when.contains:
stream: "stdout"
attrs.service: "nginx"
- index: "docker-ng-error-%{+yyyy.MM}"
when.contains:
stream: "stderr"
attrs.service: "nginx"

- index: "docker-db-acc-%{+yyyy.MM}"
when.contains:
stream: "stdout"
attrs.service: "db"
- index: "docker-db-error-%{+yyyy.MM}"
when.contains:
stream: "stderr"
attrs.service: "db"
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false

kibana展示

ELK Stack日志分析