文章目录
一、Splunk简介
1、功能
是一个分析计算机系统产生的机器数据,并在广泛的场景中提供数据收集、分析、可视化分布式的数据计算平台。商业产品
2、优势
Splunk 是一个数据引擎。
针对所有IT系统和基础设施数据, 提供数据搜索、报表和可视化展现。
Splunk是软件 – 5分钟就可以下载和安装。
可以运行在各种主流的操作系统平台。
二、ELK简介
1、日志分析前言
在日常运维工作中,对于系统和业务日志的处理尤为重要
日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误。
2、日志分析传统方案
通常,日志被分散的储存在不同的设备上。如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志。这样繁琐且效率低下。当务之急是使用集中化的日志管理,例如:开源的syslog,将所有服务器上的日志收集汇总。集中化管理日志后,日志的统计和检索又成为一件比较麻烦的事情,一般使用grep、awk和wc等Linux命令能实现检索和统计,但是对于要求更高的查询、排序和统计等要求和庞大的机器数量依然使用这样的方法难免有点力不从心。
3、日志分析系统:ELK简介
是一个基于浏览器页面的Elasticsearch前端展示工具,也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮你汇总、分析和搜索重要数据日志
Elasticsearch:弹性搜索,日志存储(接收Logstash提交的日志。存储日志)
是一个基于Lucene的开源分布式搜索服务器。特点:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源, 自动搜索负载等。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二流行的企业搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。 在elasticsearch中,所有节点的数据是均等的。
Logstash:收集日志(部署在产生日志的应用服务器上,用于收集日志,有多少台生产服务器,就部署多少个Logstash)
是一个完全开源工具,可以对你的日志进行收集、过滤、分析,并将其存储供以后使用(如,搜索),logstash带有一个web界面,搜索和展示所有日志。
Kibana:日志分析、汇总、展示(通过WEB页面向用户展示)
是一个基于浏览器页面的Elasticsearch前端展示工具,也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮你汇总、分析和搜索重要数据日志
4、ELK工作原理
Logstash收集AppServer产生的Log,并存放到ElasticSearch集群中,而Kibana则从ES集群中查询数据生成图表,再返回给Browser。产生日志—>收集日志->存储日志->展示日志->查看日志
5、Elasticsearch、Logstash插件功能集合
目前项目中使用的是elasticsearch-1.5.1版本,使用到的插件如下:
- hq 监控,管理elasticsearch集群以及通过web界面来进行查询操作
项目地址:https://github.com/royrusso/elasticsearch-HQ - analysis-ik ik分词器,中文分词
项目地址:https://github.com/medcl/elasticsearch-analysis-ik - bigdesk 统计分析和图表化elasticsearch集群状态信息
项目地址:https://github.com/lukas-vlcek/bigdesk - head 最实用的通过web界面来查看elasticsearch集群状态信息
项目地址:https://github.com/mobz/elasticsearch-head - inquisitor 一个帮助调试查询语句细节的工具
项目地址:https://github.com/polyfractal/elasticsearch-inquisitor - marvel 超赞的一个通过json查询的工具,可惜是收费项目,非开源
项目地址:https://www.elastic.co/downloads/marvel - sql 一款国人写的通过类似sql语法进行查询的工具
项目地址:https://github.com/NLPchina/elasticsearch-sql - kopf 一个通过web界面来管理和监控elasticsearch集群状态信息
项目地址:https://github.com/lmenezes/elasticsearch-kopf
三、ELK集群部署
1、部署Elasticsearch集群存储日志
ES主从集群:集群要求时间一致(内存>2G)
master收集到日志后,会把一部分数据碎片到slave上(随机的一部分数据);同时,master和slave又都会各自做副本,并把副本放到对方机器上,这样就保证了数据不会丢失。如果master宕机了,那么客户端在日志采集配置中将elasticsearch主机指向改为slave,就可以保证ELK日志的正常采集和web展示。
10.11.67.32 elk-node1
10.11.67.148 elk-node2
基础环境安装:elk-node1个elk-node2同时操作(以elk-node1为栗)
1)下载并安装GPG Key
[root@elk-node1 ~]# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
2)添加yum仓库
[root@elk-node1 ~]# vim /etc/yum.repos.d/elk.repo
[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=http://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1
3)安装elasticsearch
[root@elk-node1 ~]# yum -y install elasticsearch redis nginx java
4)安装相关测试软件(略)
下载安装epel源:epel-release-latest-7.noarch.rpm
[root@elk-node1 ~]# wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
[root@elk-node1 ~]# rpm -ivh epel-release-latest-7.noarch.rpm
5)测试java环境
[root@elk-node1 ~]# java -version
elk-node1和elk-node2的配置一样,配置文件节点名称不一样就行
测试是一样的,就是换个IP
[root@elk-node1 ~]# mkdir -pv /data/es-data
[root@elk-node1 ~]# chown -R elasticsearch.elasticsearch /data/
[root@elk-node1 ~]# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: huanqiu 组名(同一个组,组名必须一致)
node.name: elk-node1 节点名称,建议和主机名一致
path.data: /data/es-data 数据存放的路径
path.logs: /var/log/elasticsearch/ 日志存放的路径
bootstrap.mlockall: true 锁住内存,不被使用到交换分区去(通常在内部不足时,休眠的程序内存信息会交换到交换分区)
network.host: 0.0.0.0 网络设置
http.port: 9200 端口
discovery.zen.ping.multicast.enabled: false 关闭多播
discovery.zen.ping.unicast.hosts: [“10.11.67.32”,“10.11.67.148”] 主服务器和自己的地址
启动并查看
[root@elk-node1 ~]# systemctl start elasticsearch
[root@elk-node1 ~]# systemctl enable elasticsearch
[root@elk-node1 ~]# systemctl status elasticsearch
[root@elk-node1 ~]# netstat -antlp |egrep “9200|9300”
[root@elk-node1 ~]# ss -antlp |egrep “9200|9300”
命令行检查
[root@elk-node1 ~]# curl -i -XGET ‘http://10.11.67.32:9200/_count?pretty’ -d ‘{“query”:{“match_all”:{}}}’
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 95
{
“count” : 0,
“_shards” : {
“total” : 0,
“successful” : 0,
“failed” : 0
}
}
浏览器访问:http://10.18.41.31:9200/
浏览器访问:http://10.18.41.148:9200/
elk-node1和elk-node2安装head和kopf插件
head插件:最实用的通过web界面来查看elasticsearch集群状态信息
kopf插件:通过web界面来管理和监控elasticsearch集群状态信息
[root@elk-node1 ~]# /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head
[root@elk-node1 ~]# chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/plugins
[root@elk-node1 ~]# /usr/share/elasticsearch/bin/plugin install lmenezes/elasticsearch-kopf
[root@elk-node1 ~]# chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/plugins
[root@elk-node1 ~]# systemctl restart elasticsearch
浏览器访问测试
http://10.11.67.32:9200/_plugin/head/
http://10.11.67.148:9200/_plugin/kopf
至此,ES集群部署完成
2、部署Logstash收集日志
Logstash应该是部署在生产服务器上,这里因为实验环境有限,在现有的两台服务器上部署Logstash,(以elk-node1为例)
1)下载并安装GPG Key
[root@elk-node1 ~]# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
2)添加yum仓库
[root@elk-node1 ~]# vim /etc/yum.repos.d/logstash.repo
[logstash-2.1]
name=Logstash repository for 2.1.x packages
baseurl=http://packages.elastic.co/logstash/2.1/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1
3)安装logstash
[root@elk-node1 ~]# yum -y install logstash
4)logstash启动(略)
集群配置需要重启。今天测试环境单机重启没有必要
5)数据收集测试1:命令行单行操作
基本的输入输出
[root@elk-node1 ~]# /opt/logstash/bin/logstash -e ‘input { stdin{} } output { stdout{} }’
-e 执行。(后期用-f带脚本的形式执行)
input{} 输入函数
output{} 输出函数
stdin{} 标准输入
stdout{} 标准输出
使用rubydebug详细输出
[root@elk-node1 ~]# /opt/logstash/bin/logstash -e ‘input { stdin{} } output { stdout{codec => rubydebug} }’
把内容写到elasticsearch中
[root@elk-node1 ~]# /opt/logstash/bin/logstash -e ‘input { stdin{} } output { elasticsearch{hosts => [“10.11.67.32:9200”]} }’
去浏览器查看(ES集群会自动进行互相复制)
http://10.11.67.32:9200/_plugin/head/
写到elasticsearch中又写在文件中一份
[root@elk-node1 ~]# /opt/logstash/bin/logstash -e ‘input { stdin{} } output { elasticsearch{hosts => [“10.11.67.32:9200”]} }’
命令行只是用来测试用,重启就米有了,所以需要写到配置文件里面里面
6)数据收集测试2:logstash的配置文件的编写
简单的配置方式
[root@elk-node1 ~]# vim /etc/logstash/conf.d/01-logstash.conf
input{
stdin{}
}
output{
elasticsearch{
hosts => ["10.11.67.32:9200"]}
stdout{codec => rubydebug}
}
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f /etc/logstash/conf.d/01-logstash.conf
先前台启动logstash,输出没有错误,配置文件语法正确
然后再后台启动&
收集系统日志
[root@elk-node1 ~]# vim /etc/logstash/conf.d/02-logstash.conf
input{
file{
path => "/var/log/messages"
type => "system"
start_position => "beginning"
}
}
output{
elasticsearch{
hosts => ["10.11.67.32:9200"]
index => "system-%{+YYYY.MM.dd}"
}
}
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f /etc/logstash/conf.d/02-logstash.conf &
收集java日志
多输入源,就多写几个input
请替换掉hosts地址
注意日志文件是否存在
type名称需要小写
[root@elk-node1 ~]# vim /etc/logstash/conf.d/03-logstash.conf
input{
file{
path => "/var/log/messages"
type => "system"
start_position => "beginning"
}
}
input{
file{
path => "/var/log/elasticsearch/huanqiu.log"
type => "es-error"
start_position => "beginning"
}
}
output{
if [type] == "system"{
elasticsearch{
hosts => ["10.11.67.32:9200"]
index => "system-%{+YYYY.MM.dd}"
}
}
if [type] == "es-error"{
elasticsearch{
hosts => ["10.11.67.32:9200"]
index => "es-error-%{+YYYY.MM.dd}"
}
}
}
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f /etc/logstash/conf.d/03-logstash.conf &
后台运行也没问题,成功和失败信息也会在前台提示
多行模式
[root@elk-node1 ~]# vim /etc/logstash/conf.d/04-logstash.conf
input {
stdin {
codec => multiline { //多行模式。碰到指定模式之前,日志为无效。遇见模式时,才将模式之前的信息,收集成日志。
pattern => "^\[" //模式
negate => true //无效
what => "previous" //之前
}
}
}
output {
stdout {
codec => "rubydebug"
}
}
[root@elk-node1 ~]# vim /etc/logstash/conf.d/04-logstash.conf
3、部署Kibana分析日志
安装Kibana(部署在能和Elasticsearch通信的服务器上)
进入源码常用的安装目录
安装后修改Kibana配置文件(添加Elasticsearch的IP路径)
[root@elk-node1 ~]# cd /usr/local/src
[root@elk-node1 ~]# wget https://download.elastic.co/kibana/kibana/kibana-4.3.1-linux-x64.tar.gz
[root@elk-node1 ~]# tar -xvf kibana-4.3.1-linux-x64
[root@elk-node1 ~]# mv kibana-4.3.1-linux-x64 /usr/local/
创建软连接方便查找
[root@elk-node1 ~]# ln -s /usr/local/kibana-4.3.1-linux-x64/ /usr/local/kibana
[root@elk-node1 ~]# cd /usr/local/kibana/config/
[root@elk-node1 ~]# cp kibana.yml kibana.yml.bak
[root@elk-node1 ~]# vim kibana.yml
server.port: 5601
server.host: “0.0.0.0”
elasticsearch.url: “http://192.168.1.160:9200”
kibana.index: “.kibana”
因为他一直运行在前台,要么选择开一个shell窗口,要么选择使用screen。
[root@elk-node1 ~]# yum -y install screen
[root@elk-node1 ~]# screen
这样就另开启了一个终端窗口,并将程序保存在屏风的前台运行,在屏风内启动Kibana
[root@elk-node1 ~]# /usr/local/kibana/bin/kibana
然后按ctrl+a+d组合键,暂时断开screen会话
这样在上面另启的screen屏里启动的kibana服务就一直运行在前台了…
[root@elk-node1 ~]# screen -ls
There is a screen on:
15041.pts-0.elk-node1 (Detached)
1 Socket in /var/run/screen/S-root.
注:screen重新连接会话
下例显示当前有两个处于detached状态的screen会话,你可以使用screen -r <screen_pid>重新连接上:
[root@tivf18 root]# screen –ls
There are screens on:
8736.pts-1.tivf18 (Detached)
8462.pts-0.tivf18 (Detached)
2 Sockets in /root/.screen.
[root@tivf18 root]# screen -r 8736
浏览器访问http://10.11.67.32:5601/
通过索引进行日志的管理
1.添加索引名称
如下,如果是添加上面设置的java日志收集信息,则在下面填写es-error;
如果是添加上面设置的系统日志信息system*,以此类型(可以从logstash界面看到日志收集项)
2.然后点击上面的Discover,在Discover中查看:
3.查看日志登陆,需要点击“Discover”–>“message”,点击它后面的“add”
需要右边查看日志内容时带什么属性,就在左边点击相应属性后面的“add”
如下图,添加了message和path的属性:
这样,右边显示的日志内容的属性就带了message和path
5.点击右边日志内容属性后面隐藏的<<,就可将内容向前缩进
6.添加新的日志采集项,点击Settings->+Add New,比如添加system系统日志。注意后面的*不要忘了。
7.删除kibana里的日志采集项,如下,点击删除图标即可。
如果打开kibana查看日志,发现没有日志内容,出现“No results found”,
如下图所示,这说明要查看的日志在当前时间没有日志信息输出,可以点击右上角的时间钟来调试日志信息的查看。
4、扩展:elasticsearch缓存(+redis)
接下来描述会遇见到的一个问题:
一旦我们的elasticsearch出现问题,就不能进行日志采集处理了!
这种情况下该怎么办呢?
解决方案;
可以在client和elasticsearch之间添加一个中间件作为缓存,先将采集到的日志内容写到中间件上,然后再从中间件输入到elasticsearch中。
这就完美的解决了上述的问题了。
(4)ELK中使用redis作为中间件,缓存日志采集内容
1)redis的配置和启动
[root@elk-node1 ~]# vim /etc/redis.conf #修改下面两行内容
daemonize yes
bind 192.168.1.160
[root@elk-node1 ~]# systemctl start redis
[root@elk-node1 ~]# lsof -i:6379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 19474 redis 4u IPv4 1344465 0t0 TCP elk-node1:6379 (LISTEN)
[root@elk-node1 ~]# redis-cli -h 192.168.1.160
192.168.1.160:6379> info
# Server
redis_version:2.8.19
.......
2)编写从Client端收集数据的文件
[root@elk-node1 ~]# vim redis-out.conf
input {
stdin {}
}
output {
redis {
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "demo"
}
}
3)执行收集数据的文件,并输入数据hello redis
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f redis-out.conf
Settings: Default filter workers: 1
Logstash startup completed #下面输入数据hello redis
hello redis
4)在redis中查看数据
[root@elk-node1 ~]# redis-cli -h 192.168.1.160
192.168.1.160:6379> info
# Server
.......
.......
# Keyspace
db6:keys=1,expires=0,avg_ttl=0 #在最下面一行,显示是db6
192.168.1.160:6379> select 6
OK
192.168.1.160:6379[6]> keys *
1) "demo"
192.168.1.160:6379[6]> LINDEX demo -1
"{\"message\":\"hello redis\",\"@version\":\"1\",\"@timestamp\":\"2016-11-14T08:04:25.981Z\",\"host\":\"elk-node1\"}"
5)继续随便写点数据
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f redis-out.conf
Settings: Default filter workers: 1
Logstash startup completed
hello redis
123456
asdf
ert
wang
shi
bo
guohuihui
as
we
r
g
asdfjkdfsak
5423wer
34rt3
6y
7uj
u
io9
sdjfhsdk890
huanqiu
huanqiuchain
hqsb
asda
6)在redis中查看
在redis中查看长度:
[root@elk-node1 ~]# redis-cli -h 192.168.1.160
192.168.1.160:6379> info
# Server
redis_version:2.8.19
.......
.......
# Keyspace
db6:keys=1,expires=0,avg_ttl=0 #显示是db6
192.168.1.160:6379> select 6
OK
192.168.1.160:6379[6]> keys *
1) "demo"
192.168.1.160:6379[6]> LLEN demo
(integer) 24
7)将redis中的内容写到ES中
[root@elk-node1 ~]# vim redis-in.conf
input {
redis {
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "demo"
}
}
output {
elasticsearch {
hosts => ["192.168.1.160:9200"]
index => "redis-in-%{+YYYY.MM.dd}"
}
}
执行:
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f redis-in.conf --configtest
Configuration OK
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f redis-in.conf &
在redis中查看,发现数据已被读出:
192.168.1.160:6379[6]> LLEN demo
(integer) 0
登陆elasticsearch界面查看:
8)接着,将收集到的所有日志写入到redis中。这了重新定义一个添加redis缓存后的总文件shipper.conf。(可以将之前执行的总文件file.conf停掉)
[root@elk-node1 ~]# vim shipper.conf
input {
file {
path => "/var/log/messages"
type => "system"
start_position => "beginning"
}
file {
path => "/var/log/elasticsearch/huanqiu.log"
type => "es-error"
start_position => "beginning"
codec => multiline {
pattern => "^\["
negate => true
what => "previous"
}
}
file {
path => "/var/log/nginx/access_json.log"
codec => json
start_position => "beginning"
type => "nginx-log"
}
syslog {
type => "system-syslog"
host => "192.168.1.160"
port => "514"
}
}
output {
if [type] == "system"{
redis {
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "system"
}
}
if [type] == "es-error"{
redis {
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "demo"
}
}
if [type] == "nginx-log"{
redis {
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "nginx-log"
}
}
if [type] == "system-syslog"{
redis {
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "system-syslog"
}
}
}
执行上面的文件(提前将上面之前启动的file.conf文件的执行给结束掉!)
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f shipper.conf --configtest
Configuration OK
[root@elk-node1 ~]# /opt/logstash/bin/logstash -f shipper.conf
Settings: Default filter workers: 1
Logstash startup completed
在redis中查看:
[root@elk-node1 ~]# redis-cli -h 192.168.1.160
192.168.1.160:6379> info
# Server
redis_version:2.8.19
.......
.......
# Keyspace
db6:keys=1,expires=0,avg_ttl=0 #显示是db6
192.168.1.160:6379> select 6
OK
192.168.1.160:6379[6]> keys *
1) "demo"
2) "system"
192.168.1.160:6379[6]> keys *
1) "nginx-log"
2) "demo"
3) "system"
另开一个窗口,添加点日志:
[root@elk-node1 ~]# logger "12325423"
[root@elk-node1 ~]# logger "12325423"
[root@elk-node1 ~]# logger "12325423"
[root@elk-node1 ~]# logger "12325423"
[root@elk-node1 ~]# logger "12325423"
[root@elk-node1 ~]# logger "12325423"
又会增加日志:
192.168.1.160:6379[6]> keys *
1) "system-syslog"
2) "nginx-log"
3) "demo"
4) "system"
其实可以在任意的一台ES中将数据从redis读取到ES中。
下面咱们在elk-node2节点,将数据从redis读取到ES中:
编写文件:
[root@elk-node2 ~]# cat file.conf
input {
redis {
type => "system"
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "system"
}
redis {
type => "es-error"
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "es-error"
}
redis {
type => "nginx-log"
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "nginx-log"
}
redis {
type => "system-syslog"
host => "192.168.1.160"
port => "6379"
db => "6"
data_type => "list"
key => "system-syslog"
}
}
output {
if [type] == "system"{
elasticsearch {
hosts => ["192.168.1.160:9200"]
index => "system-%{+YYYY.MM.dd}"
}
}
if [type] == "es-error"{
elasticsearch {
hosts => ["192.168.1.160:9200"]
index => "es-error-%{+YYYY.MM.dd}"
}
}
if [type] == "nginx-log"{
elasticsearch {
hosts => ["192.168.1.160:9200"]
index => "nignx-log-%{+YYYY.MM.dd}"
}
}
if [type] == "system-syslog"{
elasticsearch {
hosts => ["192.168.1.160:9200"]
index => "system-syslog-%{+YYYY.MM.dd}"
}
}
}
执行:
[root@elk-node2 ~]# /opt/logstash/bin/logstash -f file.conf --configtest
Configuration OK
[root@elk-node2 ~]# /opt/logstash/bin/logstash -f file.conf &
去redis中检查,发现数据已经被读出到elasticsearch中了。
192.168.1.160:6379[6]> keys *
(empty list or set)
同时登陆logstash和kibana看,发现可以正常收集到日志了。
可以执行这个 去查看nginx日志
[root@elk-node1 ~]# ab -n10000 -c1 http://192.168.1.160/
也可以启动多个redis写到ES中,具体根据自己的实际情况而定。