一、ELK介绍
1.1 什么是ELK
ELK是由ElasaticSearch、Logstash、Kibana三个开源软件组成的一个组合体。ELK是一套完整的日志收集、分析和展示的企业级解决方案,每个软件分工不同。
1.2 什么是ElasticSearch
ElasticSearch是一个可扩展的开源全文搜索和分析引擎,可实现数据的实时全文搜索,支持分布式,提供API接口。它使用Java语言开发,是建立在全文搜索引擎Apache Lucene基础之上的搜索引擎。特点如下:
- 实时搜索、实时分析
- 分布式架构,实时文件存储
- 文件导向,所有对象都是文档
- 高可用,易扩展,支持集群、分片与复制
- 接口友好,支持json
1.3 什么是Logstash
Logstash是一个具有实时传输能力的数据收集引擎,可以通过插件实现日志收集和转发,支持日志过滤,支持普通log、json格式的日志解析,最终将经过处理的日志转发给ElasticSearch
1.4 什么是Kibana
Kibana为ElasticSearch提供一个查看数据的web界面,主要通过ElasticSearch的API接口进行数据查找,并进行前端可视化数据的展示,还可以针对特定格式(eg:json)的数据生成相应的表格、柱状图、饼图等
1.5 ELK能解决什么问题
- 日志查询,问题排查,故障恢复
- 应用日志分析,错误报警
- 性能分析,用户行为分析
二、ELK部署
2.1 环境介绍
操作系统 | 主机名 | Ip | 部署软件 |
Ubuntu 22.04 | node1 | 192.168.131.11 | ElasticSearch |
node2 | 192.168.131.12 | ElasticSearch | |
node3 | 192.168.131.13 | ElasticSearch | |
node4 | 192.168.131.14 | Logstash,filebeat,Tomcat,Nginx | |
node5 | 192.168.131.15 | Kibana,Redis |
2.2 ElasticSesrch部署
#安装java
apt-get -y install openjdk-11-jdk
#安装ES软件包
wget https://mirrors.tuna.tsinghua.edu.cn/elasticstack/7.x/apt/pool/main/e/elasticsearch/elasticsearch-7.9.3-amd64.deb
dpkg -i elasticsearch-7.9.3-amd64.deb
#编辑ES的配置文件
vim /etc/elasticsearch/elasticsearch.yml
#ELK集群名称,名称相同即属于同一集群
cluster.name: ELK-cluster
#当前节点在集群内的名称(不同节点名称不一样)
node.name: node1
#ES数据保存目录
path.data: /var/lib/elasticsearch
#ES日志保存目录
path.logs: /var/log/elasticsearch
#服务启动时锁定足够的内存,防止数据写入swap
bootstrap.memory_lock: true
#监听ip
network.host: 0.0.0.0
#监听端口
http.port: 9200
#集群中node节点发现列表
discovery.seed_hosts: ["192.168.131.11","192.168.131.12","192.168.131.13"]
#集群中哪些节点可被选为master
cluster.initial_master_nodes: ["192.168.131.11","192.168.131.12","192.168.131.13"]
#设置是否可以通过正则或者_all删除或关闭索引库,true表示必须显式指定索引库名称。生产环境宜设为true,删除索引库时需指定
action.destructive_requires_name: true
#修改内存限制,最好是物理机内存的一半
vim /etc/elasticsearch/jvm.options
-Xms1g
-Xmx1g
vim /lib/systemd/system/elasticsearch.service
#无限制使用内存
LimitMEMLOCK=infinity
启动ES后查看效果
2.3 Google浏览器安装ElasticSearch head插件
2.4 Master与Node的区别
- Master节点的职责:统计各个node节点状态信息、集群状态信息,索引的创建&删除,索引分配管理,删除Node节点
- Node节点的职责:从Master节点同步数据,可通过选举成为新的Master
注意:
- 集群状态为绿色表示健康,Master节点和Node节点都在线,主分片和副本分片无丢失,无数据丢失;
- 黄色表示警告,由于主机宕机导致副本分片丢失,但未丢失数据;
- 红色表示严重级别,由于主机宕机导致主分片丢失,产生部分数据丢失
2.5 Cerebro
新开源的ElasticSearch集群web管理程序,自0.9.4版本开始需要java11或更高版本,具体参考github地址:https://github.com/lmenezes/cerebro
unzip cerebro-0.9.4.zip
cd cerebro-0.9.4
#编辑cerebro配置文件
vim conf/application.conf
hosts = [
{
host = "http://192.168.131.11:9200"
name = "ELK-cluster"
headers-whitelist = [ "x-proxy-user", "x-proxy-roles", "X-Forwarded-For" ]
}
./bin/cerebro
访问http://cerebro的IP地址:9000,输入ES集群中的任意一台机器地址+9200端口,效果如下:
2.6 Logstash部署
#安装软件包
wget https://mirrors.tuna.tsinghua.edu.cn/elasticstack/7.x/apt/pool/main/l/logstash/logstash-7.9.3.deb
dpkg -i logstash-7.9.3.deb
#测试Logstash分别输出到ES和指定文件
cd /etc/logstash/conf.d
vim test.conf
input {
标准输入,用来测试
stdin {}
}
output {
#输出到ES
elasticsearch {
hosts => ["192.168.131.11:9200"]
index => "test-%{+YYYY.MM.dd}"
}
#输出到指定文件
file {
path => "/tmp/test.log"
}
}
/usr/share/logstash/bin/logstash -f test.conf
打开文件验证:
ES验证收到数据:
2.7 Kibana部署&配置
#安装软件包
wget https://mirrors.tuna.tsinghua.edu.cn/elasticstack/7.x/apt/pool/main/k/kibana/kibana-7.9.3-amd64.deb
dpkg -i kibana-7.9.3-amd64.deb
#编辑Kibana配置文件
vim /etc/kibana/kibana.yml
#监听端口
server.port: 5601
#监听地址
server.host: "0.0.0.0"
#ES主机地址
elasticsearch.hosts: ["http://192.168.131.11:9200"]
#支持中文
i18n.locale: "zh-CN"
之后重启kibana
2.8 Kibana创建索引&验证
访问http://Kibana机器ip:5601点击左侧的Stack Management->点击左侧Kibana下方的索引模式->点击创建索引模式
如果默认未显示柱状图,可能是最近未写入新数据。通过Logstash重新写入数据即可
2.9 Filebeat介绍&部署
Filebeat 是用于转发和集中日志数据的轻量级传送程序。作为服务器上的代理安装,Filebeat监视指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或Logstash进行索引。
Logstash 直接收集日志,需要安装JDK,资源消耗较大。生产一般使用filebeat代替logstash, 基于go开发,部署方便,重要的是只需要10M多内存,比较节约资源。
filebeat 支持从系统日志、Redis,TCP、UDP标准输入等读取数据,再输入至 Elasticsearch、logstash、Redis、Kafka等
filebeat的工作方式如下:启动Filebeat时,它将启动一个或多个输入,这些输入将在日志数据指定的位置中查找。对于Filebeat 所找到的每个日志,Filebeat都会启动收集器。每个收集器都读取一个日志以获取新内容,并将新日志 数据发送到filebeat,filebeat会汇总事件并将汇总的数据发送到为Filebeat配置的输出。
#安装软件包
wget https://mirrors.tuna.tsinghua.edu.cn/elasticstack/7.x/apt/pool/main/f/filebeat/filebeat-7.9.3-amd64.deb
dpkg -i filebeat-7.9.3-amd64.deb
三、ELK实战案例
3.1 用filebeat收集tomcat访问日志&错误日志到ES并利用kibana展示
3.1.1 安装 Tomcat 并配置使用 Json 格式的访问日志
apt-get -y install tomcat9
vim /etc/tomcat9/server.xml
……
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="tomcat_access_log" suffix=".txt"
pattern="{"clientip":"%h","ClientUser":"%l","authenticated":"%u","AccessTime":"%t","method":"%r","status":"%s","SendBytes":"%b","Query?string":"%q","partner":"%{Referer}i","AgentVersion":"%{User-Agent}i"}"/>
</Host>
</Engine>
</Service>
</Server>
之后重启tomcat
3.1.2 设置filebeat配置文件
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/tomcat9/tomcat_access_log.*.txt
默认False会将json数据存储至message,改为true则会独立message外存储
设为true,覆盖默认的message字段,使用自定义json格式中的key
tags: ["tomcat-access"]
- type: log
enabled: true
paths:
- /var/log/tomcat9/catalina.*
tags: ["tomcat-error"]
##下面内容是收集tomcat多行错误日志而使用的。多行实际是同一个事件的日志内容
multiline.type: pattern #此为默认值,可省略
multiline.negate: true
multiline.match: after
multiline.maxlines: 10000 #默认只合并500行,指定最大合并1万行
output.elasticsearch:
#指定ELK集群服务器地址和端口
indices:
- index: "tomcat-access-%{[agent.version]}-%{+yyyy.MM.dd}"
when.contains:
tags: "tomcat-access"
- index: "tomcat-error-%{[agent.version]}-%{+yyy.MM.dd}"
when.contains:
tags: "tomcat-error"
setup.ilm.enabled: false
setup.template.name: "tomcat"
setup.template.pattern: "tomcat-*"
之后重启filebeat
3.1.3 在Kibana创建索引模式并查看
创建访问日志的索引模式如下:
创建错误日志的索引模式如下:
查看访问日志的索引,显示指定字段,针对某个字段进行相关业务分析
查看错误日志的索引,可看到多行已合并为一个日志
3.2 Logstash利用Redis作缓存从filebeat收集nginx日志和系统日志
当短时间内产生大量日志时,Logstash由于单台的瓶颈不能及时处理,需要添加redis或kafka作缓存以减轻Logstash的压力。架构如下:
3.2.1 安装nginx并配置日志使用json格式
vim /etc/nginx/nginx.conf
……
log_format access_json '{ "@timestamp": "$time_local", '
'"host":"$server_addr", '
'"client_ip":"$remote_addr", '
'"size":"$body_bytes_sent", '
'"responsetime":"$request_time", '
'"upstream_response_time":$upstream_response_time,'
'"upstreamhost":$upstream_addr,'
'"http_host":$host,'
'"uri":$uri,'
'"domain":$host,'
'"xff":$http_x_forwarded_for,'
'"status": "$status", '
'"request": "$request", '
'"request_method": "$request_method", '
'"referer":"$http_referer", '
'"body_bytes_sent":"$body_bytes_sent", '
'"http_x_forwarded_for": "$http_x_forwarded_for", '
'"http_user_agent": "$http_user_agent", '
'"status": "$status" }}';
access_log /var/log/nginx/access.log access_json;
重启nginx后,多访问几次(包括404的),查看日志记录:
3.2.2 利用filebeat收集nginx日志和系统日志到redis
vim /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true #默认false会将json数据存储至message,改为true则会独立message外存储
json.overwrite_keys: true #设为true,覆盖默认的message字段,使用自定义json格式中的key
tags: ["nginx-access"]
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
tags: ["nginx-error"]
- type: log
enabled: true
paths:
- /var/log/syslog
tags: ["syslog"]
output.redis:
hosts: ["192.168.131.15:6379"]
key: "filebeat"
password: "123456"
#db: 0
之后重启filebeat
3.2.3 配置logstash收集redis数据并发送至ES
cd /etc/logstash
vim redis_to_es.conf
input {
redis {
host => '192.168.131.15'
port => "6379"
password => "123456"
db => "0"
data_type => 'list'
key => "filebeat"
}
}
output {
if "syslog" in [tags] {
elasticsearch {
hosts => ["192.168.131.11:9200"]
index => "syslog-%{+YYYY.MM.dd}"
}
}
if "nginx-access" in [tags] {
elasticsearch {
hosts => ["192.168.131.11:9200","192.168.131.12:9200","192.168.131.13:9200"]
index => "nginx-accesslog-%{+YYYY.MM.dd}"
template_overwrite => true
}
}
if "nginx-error" in [tags] {
elasticsearch {
hosts => ["192.168.131.11:9200"]
index => "nginx-errorlog-%{+YYYY.MM.dd}"
template_overwrite => true
}
}
}
启动:/usr/share/logstash/bin/logstash -f redis_to_es.conf
3.2.4 在Kibana创建索引并查看
四、排错
启动kibana,界面显示Kibana server is not ready yet。
先排查kibana配置文件写的ES服务地址是否启动和ES配置文件中与节点ip相关的配置写的是否正确。以上无误后用ES的插件查看索引,把里面的.kibana_1删掉(或因数据混乱导致),再重启Kibana,问题就解决了