日志系统
场景
- 一般常见我们需要进行日志分析场景是:直接在日志文件中grep、awk就可以获得自己想要的信息。但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档、文本搜索太慢怎么办、如何多维度查询。需要集中化的日志管理,所有服务器上的日志收集汇总。常见解决思路是建立集中式日志收集系统,将所有节点上的日志统一收集,管理,访问。
- 大型系统是一个分布式部署的架构,不同的服务模块部署在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。
- 对大量的日志业务数据进行分析,如平台PV、UV、IP、PageTOP等维度进行分析查询等。另外安全审计、数据挖掘、行为分析等都少不了日志对其作为支撑。
作用
- 信息查找:通过检索日志信息,定位相应的bug,找出解决方案。
- 服务诊断:通过对日志信息进行统计、分析,了解服务器的负荷和服务运行状态,找出耗时请求进行优化等等。
- 数据分析:如果是格式化的log,可以做进一步的数据分析,统计、聚合出有意义的信息,比如根据请求中的商品id,找出TOP10用户感兴趣商品
架构
日志系统三个基本组件:
- 采集端:agent(采集日志源数据,封装数据源,将数据源中的数据发送给collector)
- 聚合端:collector(按一定规则进行数据处理、接收多个agent的数据,并进行汇总后导入后端的store中)
- 存储端:store(日志存储系统,应该具有可扩 展性和可靠性,如HDFS ES等)
常见方案
流式分析
ELK方案
组件
- Elasticsearch日志存储和搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
- Logstash是一个完全开源的工具,他可以对你的日志进行收集、过滤,并将其存储供以后使用(支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作。)。
- Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。
- Filebeat:和Logstash一样属于日志收集处理工具,基于原先 Logstash-fowarder 的源码改造出来的。与Logstash相比,filebeat更加轻量,占用资源更少
流程
应用程序(AppServer)–>Logstash–>ElasticSearch–>Kibana–>浏览器(Browser)
Logstash收集AppServer产生的Log,并存放到ElasticSearch集群中,而Kibana则从ElasticSearch集群中查询数据生成图表,再返回给Browser。
考虑到聚合端(日志处理、清洗等)负载问题和采集端传输效率,一般在日志量比较大的时候在采集端和聚合端增加队列,以用来实现日志消峰。
ELK日志流程可以有多种方案(不同组件可自由组合,根据自身业务配置),常见有以下:
- Logstash(采集、处理)—> ElasticSearch (存储)—>Kibana (展示)
- Logstash(采集)—> Logstash(聚合、处理)—> ElasticSearch (存储)—>Kibana (展示)
- Filebeat(采集、处理)—> ElasticSearch (存储)—>Kibana (展示)
- Filebeat(采集)—> Logstash(聚合、处理)—> ElasticSearch (存储)—>Kibana (展示)
- Filebeat(采集)—> Kafka/Redis(消峰) —> Logstash(聚合、处理)—> ElasticSearch (存储)—>Kibana (展示)
部署
主机 | 角色 |
---|---|
主机1 | elasticsearch |
主机2 | kibana、zookeeper、kafka |
主机3 | logstash |
主机4 | nginx、filebeat |
jdk配置
[root@localhost ~]# tar -zxf jdk-8u201-linux-x64.tar.gz -C /usr/local/
[root@localhost ~]# ls /usr/local/
bin etc games include jdk1.8.0_201 lib lib64 libexec sbin share src
[root@localhost ~]# vim /etc/profile 末尾追加内容
export JAVA_HOME=/usr/local/jdk1.8.0_201
export JRE_HOME=/usr/local/jdk1.8.0_201/jre
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
[root@localhost ~]# source /etc/profile
[root@localhost ~]# java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
elasticsearch部署
[root@localhost ~]# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.tar.gz
[root@localhost ~]# tar -zxf elasticsearch-6.3.2.tar.gz -C /usr/local/
[root@localhost ~]# ln -s /usr/local/elasticsearch-6.3.2/ /usr/local/es
[root@localhost ~]# chown -R es:es /usr/local/es/
mkdir -p /es/{data,log}
groupadd es
useradd es -g es -p es
chown -R es:es /es/data
chown -R es:es /es/log
修改系统参数
echo '* soft nofile 819200' >> /etc/security/limits.conf
echo '* hard nofile 819200' >> /etc/security/limits.conf
echo '* soft nproc 2048' >> /etc/security/limits.conf
echo '* hard nproc 4096' >> /etc/security/limits.conf
echo '* soft memlock unlimited' >> /etc/security/limits.conf
echo '* hard memlock unlimited' >> /etc/security/limits.conf
echo 'vm.max_map_count=655360' >> /etc/sysctl.conf
sysctl -p
es参数设置
vim /usr/local/es/config/elasticsearch.yml
cluster.name: bdqn
node.name: es
node.master: true
node.data: true
path.data: /es/data
path.logs: /es/log
network.host: 0.0.0.0
http.port: 9200
discovery.zen.minimum_master_nodes: 1
bootstrap.memory_lock: false
bootstrap.system_call_filter: false #这两行写在一起
配置文件中,除了上边的修改项,其他的均为注释项。最后一项如果为true,则限制es的某些系统调用,可能会导致es启动失败
seccomp(全称securecomputing mode)是linuxkernel从2.6.23版本开始所支持的一种安全机制。在Linux系统里,大量的系统调用(systemcall)直接暴露给用户态程序。但是,并不是所有的系统调用都被需要,而且不安全的代码滥用系统调用会对系统造成安全威胁。通过seccomp,我们限制程序使用某些系统调用,这样可以减少系统的暴露面,同时是程序进入一种“安全”的状态。
#根据机器配置,合理修改jvm参数
vim /usr/local/es/config/jvm.options
-Xms1g
-Xmx1g
es控制
[root@es1 ~]# su es
[es@es1 root]$ /usr/local/es/bin/elasticsearch -d
[es@es1 root]$ curl 192.168.43.249:9200
{
"name" : "es",
"cluster_name" : "bdqn",
"cluster_uuid" : "KvsP1lh5Re2cxdgfNbk_eA",
"version" : {
"number" : "6.3.2",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "053779d",
"build_date" : "2018-07-20T05:20:23.451332Z",
"build_snapshot" : false,
"lucene_version" : "7.3.1",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
[root@es1 ~]# iptables -F
kibana部署
# 下载和安装
wget https://artifacts.elastic.co/downloads/kibana/kibana-6.3.2-linux-x86_64.tar.gz
tar zxvf kibana-6.3.2-linux-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/kibana-6.3.2-linux-x86_64/ /usr/local/kibana
# 配置kibana
vim /usr/local/kibana/config/kibana.yml
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.url: "http://192.168.43.249:9200"
#启动kibana
/usr/local/kibana/bin/kibana
kafka部署
部署zookeeper
wget http://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz
tar zxvf zookeeper-3.4.12.tar.gz -C /usr/local
cd /usr/local/zookeeper-3.4.12
cp conf/zoo_sample.cfg conf/zoo.cfg
# 编辑zoo.cfg文件
vim /usr/local/zookeeper-3.4.12/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/zkdata
dataLogDir=/data/zookeeper/zkdatalog
clientPort=2181
#创建目录
mkdir -p /data/zookeeper/{zkdata,zkdatalog}
#配置ZK节点ID
echo 1 > /data/zookeeper/zkdata/myid
#启动
/usr/local/zookeeper-3.4.12/bin/zkServer.sh start
#停止
/usr/local/zookeeper-3.4.12/bin/zkServer.sh stop
#查看状态
/usr/local/zookeeper-3.4.12/bin/zkServer.sh status
kafka部署
#下载2.12-2.1版本
wget http://mirrors.hust.edu.cn/apache/kafka/2.1.0/kafka_2.12-2.1.0.tgz
#解压应用至指定位置
tar zxvf kafka_2.12-2.1.0.tgz -C /usr/local/
ln -s /usr/local/kafka_2.12-2.1.0/ /usr/local/kafka
# vim /usr/local/kafka/config/server.properties
broker.id=2
listeners = PLAINTEXT://192.168.43.74:9092 #本机
num.network.threads=5
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/data/kafka/kfdata
delete.topic.enable=true #新增
num.partitions=2
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.flush.interval.messages=10000 #取消注释
log.flush.interval.ms=1000 #取消注释
log.retention.hours=72
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=192.168.43.74:2181
zookeeper.connection.timeout.ms=6000
group.initial.rebalance.delay.ms=0
kafka管理
#启动服务:
/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
#停止服务:
/usr/local/kafka/bin/kafka-server-stop.sh
kafka队列
创建topic
/usr/local/kafka/bin/kafka-topics.sh --create \
--zookeeper 192.168.43.74:2181 \
--replication-factor 1 --partitions 2 \
--topic elktest
查看kafka队列
/usr/local/kafka/bin/kafka-topics.sh --zookeeper 192.168.43.74:2181 --topic "elktest" --describe
kafka通信验证
生产消息
/usr/local/kafka/bin/kafka-console-producer.sh --broker-list 192.168.43.74:9092 --topic elktest
在命令提示符里输入hello,回车
消费消息
/usr/local/kafka_2.12-2.1.0/bin/kafka-console-consumer.sh --bootstrap-server 192.168.43.74:9092 --topic elktest --from-beginning
filebeat部署
工作原理
在任何环境下,应用程序都有停机的可能性。 Filebeat 读取并转发日志行,如果中断,则会记住所有事件恢复联机状态时所在位置。
Filebeat带有内部模块(auditd,Apache,Nginx,System和MySQL),可通过一个指定命令来简化通用日志格式的收集,解析和可视化。
FileBeat 不会让你的管道超负荷。FileBeat 如果是向 Logstash 传输数据,当 Logstash 忙于处理数据,会通知 FileBeat 放慢读取速度。一旦拥塞得到解决,FileBeat将恢复到原来的速度并继续传播。
Filebeat保持每个文件的状态,并经常刷新注册表文件中的磁盘状态。状态用于记住harvester正在读取的最后偏移量,并确保发送所有日志行。Filebeat将每个事件的传递状态存储在注册表文件中。所以它能保证事件至少传递一次到配置的输出,没有数据丢失。
Filebeat 有两个主要组件:
-
harvester:一个harvester负责读取一个单个文件的内容。harvester逐行读取每个文件,并把这些内容发送到输出。每个文件启动一个harvester。harvester负责打开和关闭这个文件,这就意味着在harvester运行时文件描述符保持打开状态。在harvester正在读取文件内容的时候,文件被删除或者重命名了,那么Filebeat会续读这个文件。这就有一个问题了,就是只要负责这个文件的harvester没有关闭,那么磁盘空间就不会释放。默认情况下,Filebeat保存文件打开直到close_inactive到达。
-
Input:一个input负责管理harvesters,并找到所有要读取的源。如果input类型是log,则input查找驱动器上与已定义的glob路径匹配的所有文件,并为每个文件启动一个harvester。
安装配置
https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.3.2-linux-x86_64.tar.gz
tar zxvf filebeat-6.3.2-linux-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/filebeat-6.3.2-linux-x86_64/ /usr/local/filebeat
启动之前需要配置,现在先不做配置,下边的启动命令也先不执行
启动
/usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml
传输方案
output.elasticsearch
如果你希望使用 filebeat 直接向 elasticsearch 输出数据,需要配置 output.elasticsearch
output.elasticsearch:
hosts: ["192.168.43.249:9200"]
output.logstash
如果使用filebeat向 logstash输出数据,然后由 logstash 再向elasticsearch 输出数据,需要配置 output.logstash。 logstash 和 filebeat 一起工作时,如果 logstash 忙于处理数据,会通知FileBeat放慢读取速度。一旦拥塞得到解决,FileBeat 将恢复到原来的速度并继续传播。这样,可以减少管道超负荷的情况。
output.logstash:
hosts: ["192.168.199.5:5044"] #logstaship
output.kafka
如果使用filebeat向kafka输出数据,然后由 logstash 作为消费者拉取kafka中的日志,并再向elasticsearch 输出数据,需要配置 output.logstash
output.kafka:
enabled: true
hosts: ["192.168.43.74:9092"]
topic: elktest
logstash部署
工作原理
Logstash 有两个必要元素:input 和 output ,一个可选元素:filter。 这三个元素,分别代表 Logstash 事件处理的三个阶段:输入 > 过滤器 > 输出
- 负责从数据源采集数据。
- filter 将数据修改为你指定的格式或内容。
- output 将数据传输到目的地。
在实际应用场景中,通常输入、输出、过滤器不止一个。Logstash 的这三个元素都使用插件式管理方式,可以根据应用需要,灵活的选用各阶段需要的插件,并组合使用。
配置文件
- logstash.yml:logstash 的默认配置文件,配置如node.name、path.data、pipeline.workers、queue.type等,这其中的配置可以被命令行参数中的相关参数覆盖
- jvm.options:logstash 的 JVM 配置文件。
- startup.options (Linux):包含系统安装脚本在 /usr/share/logstash/bin 中使用的选项为您的系统构建适当的启动脚本。安装 Logstash 软件包时,系统安装脚本将在安装过程结束时执行,并使用 startup.options 中指定的设置来设置用户,组,服务名称和服务描述等选项。
- pipelines.yml: 定义数据处理流程的文件
input 常用模块
Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件。能够以连续的流式传输方式,可从日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。
- file:从文件系统上的文件读取
- syslog:在众所周知的端口514上侦听系统日志消息,并根据RFC3164格式进行解析
- redis:从redis服务器读取,使用redis通道和redis列表。 Redis经常用作集中式Logstash安装中的“代理”,它将接收来自远程Logstash“托运人”的Logstash事件排队。
- beats:处理由Filebeat发送的事件。
常用的filter模块
过滤器是Logstash管道中的中间处理设备。可以将条件过滤器组合在一起,对事件执行操作。
- grok:解析和结构任意文本。 Grok目前是Logstash中将非结构化日志数据解析为结构化和可查询的最佳方法。
- mutate:对事件字段执行一般转换。您可以重命名,删除,替换和修改事件中的字段。
- drop:完全放弃一个事件,例如调试事件。
- clone:制作一个事件的副本,可能会添加或删除字段。
- geoip:添加有关IP地址的地理位置的信息
- elasticsearch:将事件数据发送给 Elasticsearch(推荐模式)。
- file:将事件数据写入文件或磁盘。
- graphite:将事件数据发送给 graphite(一个流行的开源工具,存储和绘制指标, http://graphite.readthedocs.io/en/latest/)。
- statsd:将事件数据发送到 statsd (这是一种侦听统计数据的服务,如计数器和定时器,通过UDP发送并将聚合发送到一个或多个可插入的后端服务)。
- json:以JSON格式对数据进行编码或解码。
- multiline:将多行文本事件(如java异常和堆栈跟踪消息)合并为单个事件。
使用beats传输至ES:
input {
beats {
port => 5044 # 此端口需要与 filebeat.yml 中的端口相同
}
}
output {
elasticsearch {
hosts => "192.168.199.4:9200"
manage_template => false
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
}
从Kafka读取传输至ES:
input {
kafka {
bootstrap_servers => "192.168.199.6:9092"
auto_offset_reset => "latest"
consumer_threads => 5
decorate_events => true
topics => ["elktest"]
}
}
output {
elasticsearch {
hosts => ["192.168.199.4:9200"]
index => "elktest-%{+YYYY.MM.dd}"
}
}
安装测试
# 下载安装
wget https://artifacts.elastic.co/downloads/logstash/logstash-6.3.2.tar.gz
tar zxvf logstash-6.3.2.tar.gz -C /usr/local/
ln -s /usr/local/logstash-6.3.2/ /usr/local/logstash
vim /usr/local/logstash/config/logstash.yml
#开启配置文件自动加载
config.reload.automatic: true
#定义配置文件重载时间周期
config.reload.interval: 10
#定义访问主机名,一般为域名或IP
http.host: "192.168.199.5"
#配置文件目录
path.config: /usr/local/logstash/config/*.conf #注意:和/之间有空格
#日志输出路径
path.logs: /var/log/logstash
#测试(敲入命令后,输入任意消息) #目前还没有conf文件,暂时不可以敲这个命令
/usr/local/logstash/bin/logstash -e 'input{stdin{}}output{stdout{}}'
使用
实验重点在于理解各组件协调流程,学习beats(filebeat)的使用
NginxLog ----> Filebeat —> Logstash —> ES —>Kibana
节点说明
主机名 | 地址 | 角色 | 作用 | 版本 |
---|---|---|---|---|
es | 192.168.43.249 | Elasticsearch | 日志存储 | elasticsearch-6.3.2 |
logstash | 192.168.43.147 | Logstash | 日志处理 | Logstatsh-6.3.2 |
zkk | 192.168.199.43.74 | Kibana | 日志展示 | kibana-6.3.2 |
app1 | 192.168.43.253 | Nginx、FileBeat | 日志生产、日志采集 | filebeat-6.3.2 |
实验前提
- ES安装配置并启动
- Filebeat安装完成
- Logstash安装完成
- Kibana安装配置完成
- 防火墙开放相关端口
- 禁用selinux
服务配置
1. filebeat配置
[root@es3 ~]# vim /usr/local/filebeat/filebeat.yml
#=========================== Filebeat inputs =============================
#filebeat.inputs:
# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.
filebeat:
prospectors:
- type: log
paths:
- /usr/local/nginx/logs/access.log
tags: ["nginx"]
# Change to true to enable this input configuration.
enabled: true
#----------------------------- Logstash output --------------------------------
output.logstash:
hosts: ["192.168.43.147:5044"]
在logstas output上边有一个elasticsearch output 需要注释掉
#运行
/usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml
2. filebeat主机安装nginx并启动
3. logstash配置
[root@localhost ~]# vim /usr/local/logstash/config/nginx-access.conf
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => "192.168.43.249:9200"
index => "nginx-%{+YYYY.MM.dd}"
}
}
#运行
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/nginx-access.conf
4. kibana展示
在kibana主机上访问本机5601端口firefox 192.168.43.74:5601
点击左侧菜单的discover 在新页面的输入框内输入nginx-* 作为索引样式,然后点击下一步
添加完索引之后,点击左侧菜单的可视化,创建一个可视化图表,在新页面里选择vertical bar
选择我们已经创建的索引样式,即可看到数据,如果不明显,去nginx那自己访问自己几次
查看es上的索引列表进行验证
[root@es1 ~]# curl 192.168.43.249:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana kT2cHcPUQEuRZ4bNr4bhZQ 1 0 2 0 10.6kb 10.6kb
red open index WgQXJcVDSf6BiVAogsKk5g 5 1 1 0 3.6kb 3.6kb
yellow open nginx-2019.02.08 qKww-bo7SOqGSjEb3wAj8A 5 1 26 0 229.2kb 229.2kb
red open bdqntest BnAC8m91TzKWGPsxwj23nA 5 1 0 0 781b 781b
实验二
实验重点在于理解各组件协调流程,理解加入消息队列后的架构
NginxLog —> Filebeat —> Kafka —> Logstash —> ES —>Kibana
主机名 | 地址 | 角色 | 作用 | 版本 |
---|---|---|---|---|
es | 192.168.43.249 | Elasticsearch | 日志存储 | elasticsearch-6.3.2 |
logstash | 192.168.43.147 | Logstash | 日志处理 | Logstatsh-6.3.2 |
zkk | 192.168.199.43.74 | Kibana、kafka、zookeeper | 日志展示 | kibana-6.3.2 |
app1 | 192.168.43.253 | Nginx、FileBeat | 日志生产、日志采集 | filebeat-6.3.2 |
实验前提
1、 ES安装配置并启动 2、 Filebeat安装完成 3、 Logstash安装完成 4、 Kibana安装配置完成 5、 防火墙开放相关端口 6、 禁用selinux 7、 Zookeeper运行启动 8、 Kafka已配置运行
服务配置
1. kafka配置
#创建topic 并测试消费者正常 (前边已经创建过)
/usr/local/kafka_2.12-2.1.0/bin/kafka-topics.sh --create \
--zookeeper 192.168.43.74:2181 \
--replication-factor 1 --partitions 2 \
--topic elktest1
2. filebeat配置
[root@es3 nginx-1.15.4]# vim /usr/local/filebeat/filebeat.yml
在上边实验的基础上,把logstash output注释掉 在它下边自己写对kafka的output
output.kafka:
enabled: true
hosts: ["192.168.43.74:9092"]
topic: "elktest1"
#运行filebeat
/usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml
3. logstash配置
[root@localhost ~]# vim /usr/local/logstash/config/nginx-access.conf
input{
kafka{
bootstrap_servers => "192.168.43.74:9092"
topics => "elktest"
consumer_threads => 1
decorate_events => true
auto_offset_reset => "latest"
}
}
output {
elasticsearch {
hosts => ["192.168.43.249:9200"]
index => "nginx-kafka-%{+YYYY-MM-dd}"
}
}
#运行
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/nginx-access.conf
4. kibana展示
kibana主机启动kafka(如果之前启动过,这不忽略)
#启动zookeeper
/usr/local/zookeeper-3.4.12/bin/zkServer.sh start
#启动kafka
/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
在kibana主机上访问本机5601端口firefox 192.168.43.74:5601