前言
????????日志分析是运维工程师解决系统故障,发现问题的主要手段。日志系统主要包括系统日志、应用程序日志、和安全日志。 ????????通常日志被分散的存储在不同的服务器上。如果服务器的数量是数十台或超过百台,查阅日志需要一一登录这些服务器,很繁琐且效率低下,为此,可以使用集中化的日志管理。 ????????集中化管理日志之后,日志的统计和分析又成为了一件比较麻烦的事,传统做法是使用grep、awk、wc等Linux命令实现统计和分析,但是对于更高要求的查询、排序和统计,还有所不足。 ????????开源的实时日志分析ELK平台能够完美的解决上述的问题。ELK由ElasticSearch、Logstash和Kibana三个开源工具组成。
一、ElasticSearch、Logstash和Kibana 简介
1.1、ElasticSearch 介绍
Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。 Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二流行的企业搜索引擎。
1.2、Elasticsearch的基础核心概念
1.2.1 接近实时(NRT)
Elasticsearch是一个接近实时的搜索平台,这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒)
1.2.2 集群(cluster)
一个集群就是由一个或多个节点组织在一起,它们共同持有你整个的数据,并一起提供索引和搜索功能。其中一个节点为主节点,这个主节点是可以通过选举产生的,并提供跨节点的联合索引和搜索的功能。集群有一个唯一性标示的名字,默认是elasticsearch,集群名字很重要,每个节点是基于集群名字加入到其集群中的。因此,确保在不同环境中使用不同的集群名字。一个集群可以只有一个节点。强烈建议在配置elasticsearch时,配置成集群模式。
1.2.3 节点(node)
节点就是一台单一的服务器,是集群的一部分,存储数据并参与集群的索引和搜索功能。像集群一样,节点也是通过名字来标识,默认是在节点启动时随机分配的字符名。当然,你可以自己定义。该名字也很重要,在集群中用于识别服务器对应的节点。(建议自定义,方便管理)
1.2.4 索引(index)
一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,如果你想,可以定义任意多的索引。 索引相对当关系型数据库的库。
1.2.5 类型(type)
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。 类型相当于关系型数据库的表。
1.2.6 文档(document)
一个文档是一个可被索引的基础信息单元。在一个index/type里面,只要你想,你可以存储任意多的文档。注意,虽然一个文档在物理上位于一个索引中,实际上一个文档必须在一个索引内被索引和分配一个类型。 文档相当于关系型数据库的列。
1.2.7 分片和副本(shards & replicas)
在实际情况下,索引存储的数据可能超过单个节点的硬件限制。如一个10亿文档需1TB空间可能不适合存储在单个节点的磁盘上, 或者从单个节点搜索请求太慢了。为了解决这个问题,elasticsearch提供将索引分成多个分片的功能。当在创建索引时,可以定义想要分片的数量。每一个分片就是一个全功能的独立的索引,可以位于集群中任何节点上。 分片的两个最主要原因: 1、水平分割扩展,增大存储量 2、分布式并行跨分片操作,提高性能和吞吐量 副本也有两个最主要原因: 1、高可用性,以应对分片或者节点故障。出于这个原因,分片副本要在不同的节点上。 2、qps能,增大吞吐量,搜索可以并行在所有副本上执行。
1.2、Logstash 介绍
Logstash是一个完全开源的工具,它可以对你的日志进行收集、过滤,并将其存储,供以后使用。 Logstash的理念很简单,它只做3件事情:
- Collect:数据输入
- Enrich:数据加工,如过滤,改写等
- Transport:数据输出
1.2.1 logStash的主要组件
Shipper:日志收集者。负责监控本地日志文件的变化,及时把日志文件的最新内容收集起来。通常,远程代理端(agent)只需要运行这个组件即可 Indexer:日志存储者,负责接收日志并写入到本地文件 Broker:日志Hub,负责连接多个Shipper和多个Indexer Search and Storage:允许对事件进行搜索和存储 Web Interface:基于Web的展示界面 正是由于以上组件在LogStash架构中可独立部署,才提供了更好的集群扩展性
1.2.2 LogStash主机分类
代理主机(agent host):作为事件的传递者(shipper),将各种日志数据发送至中心主机;只需运行Logstash 代理(agent)程序; 中心主机(central host):可运行包括中间转发器(Broker)、索引器(Indexer)、搜索和存储器(Search and Storage)、 Web界面端(Web Interface):在内的各个组件,以实现对日志数据的接收、处理和存储
1.3、Kibana 介绍
Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。 使用Kibana,可以通过各种图表进行高级数据分析及展示。Kibana让海量数据更容易理解。它操作简单,基于浏览器的用户界面 可以快速创建仪表板(dashboard)实时显示Elasticsearch查询动态。设置Kibana非常简单。无需编写代码,几分钟内就可以 完成Kibana安装并启动Elasticsearch索引监测。 主要功能: 1、Kibana架构为Elasticsearch定制,可以将任何结构化和非结构化数据加入Elasticsearch索引。Kibana还充分利用了Elasticsearch强大的搜索和分析功能。 2、整合你的数据。Kibana能够更好地处理海量数据,并据此创建柱形图、折线图、散点图、直方图、饼图和地图。 3、复杂数据分析。Kibana提升了Elasticsearch分析能力,能够更加智能地分析数据,执行数学转换并且根据要求对数据切割分块。 4、让更多团队成员受益。强大的数据库可视化接口让各业务岗位都能够从数据集合受益。 5、接口灵活,分享更容易。使用Kibana可以更加方便地创建、保存、分享数据,并将可视化数据快速交流。 6、配置简单。Kibana的配置和启用非常简单,用户体验非常友好。Kibana自带Web服务器,可以快速启动运行。 7、可视化多数据源。Kibana可以非常方便地把来自Logstash、ES-Hadoop、Beats或第三方技术的数据整合到Elasticsearch,支持的第三方技术包括Apache Flume、Fluentd等。 8、简单数据导出。Kibana可以方便地导出感兴趣的数据,与其它数据集合并融合后快速建模分析,发现新结果。
二、ELK 工作原理
日志生产集群(nginx、redis、mysql等)→→ 日志收集并格式化 →→ 格式化的日志上传至es集群 →→ 前端展示(Kibana)→→ 客户端访问Kibana查看日志 简单来说,进行日志处理分析,一般需要经过以下几个步骤:
- 将日志进行集中化管理(beats)
- 将日志格式化(logstash)
- 对格式化后的数据进行索引和存储(elasticsearch)
- 前端数据的展示(kibana)
三、EKL系统部署
实验环境: ES集群节点1:192.168.177.100 安装elasticsearch、kibana、ntp ES集群节点2:192.168.177.110 安装elasticsearch、ntp 日志生产服务器:192.168.177.111 安装logstash httpd、ntp 实现步骤:
3.1步骤一:配置elasticsearch环境(node1、node2都要做)
更改主机名 配置域名解析 查看Java环境
hostnamectl set-hostname node1
vim /etc/hosts
192.168.177.100 node1
192.168.177.110 node2
[root@node1 ~]
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
[root@node1 ~]
hostnamectl set-hostname node2
vim /etc/hosts
192.168.177.100 node1
192.168.177.110 node2
[root@node2 ~]
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
[root@node2 ~]
所有主机做时钟同步
yum -y install ntp
ntpdate ntp1.aliyun.com
3.2步骤二:部署elasticsearch软件(node1、node2都要做)
1、安装elasticsearch—rpm包(提前上传elasticsearch-5.5.0.rpm到/opt目录下)
[root@node1 ~]
[root@node1 opt]
2、加载系统服务
[root@node1 opt]
[root@node1 opt]
3、更改elasticsearch主配置文件
[root@node1 opt]
[root@node1 opt]
17 cluster.name: my-elk-cluster 集群名字
23 node.name: node1 节点名字
33 path.data: /data/elk_data 数据存放路径
37 path.logs: /var/log/elasticsearch/ 日志存放路径
43 bootstrap.memory_lock: false 不在启动的时候锁定内存:锁定物理内存地址,防止es内存被交换出去,也就是避免es使用swap交换分区,频繁的交换,会导致IOPS变高。
55 network.host: 0.0.0.0 提供服务绑定的IP地址,0.0.0.0代表所有地址
59 http.port: 9200 侦听端口为9200
68 discovery.zen.ping.unicast.hosts: ["node1", "node2"] 集群发现通过单播实现
再次检查配置是否正确
[root@node1 opt]
cluster.name: my-elk-cluster
node.name: node1
path.data: /data/elk_data
path.logs: /var/log/elasticsearch/
bootstrap.memory_lock: false
network.host: 0.0.0.0
http.port: 9200
discovery.zen.ping.unicast.hosts: ["node1", "node2"]
4、创建数据存放路径并授权
[root@node1 opt]
[root@node1 opt]
5、启动elasticsearch是否成功开启
[root@node1 elasticsearch]
[root@node1 elasticsearch]
tcp6 0 0 :::9200 :::* LISTEN 113066/java
查看节点信息,宿主机浏览器输入 http://192.168.177.100:9200 和 http://192.168.177.110:9200 查看集群是否健康,宿主机浏览器输入:http://192.168.177.100:9200/_cluster/health?pretty 查看集群状态,宿主机浏览器输入:http://192.168.177.100:9200/_cluster/state?pretty
3.3步骤三:安装elasticsearch-head插件(node1、node2都要做)
依次安装node-v8.2.1.tar.gz、phantomjs-2.1.1-linux-x86_64.tar.bz2、elasticsearch-head.tar.gz 提前上传node-v8.2.1.tar.gz到opt目录下并安装
安装环境依赖包
yum install gcc gcc-c++ make -y
[root@localhost opt]
[root@node1 opt]
[root@node1 opt]
[root@node1 node-v8.2.1]
[root@node1 node-v8.2.1]
[root@node1 node-v8.2.1]
提前上传phantomjs-2.1.1-linux-x86_64.tar.bz2 到 /usr/local/src 目录下 安装phantomjs前端框架
[root@node1 node-v8.2.1]
[root@node1 src]
[root@node1 src]
[root@node1 bin]
提前上传elasticsearch-head.tar.gz 到 /usr/local/src 目录下 安装 elasticsearch-head 数据可视化工具
[root@node1 bin]
[root@node1 src]
[root@node1 src]
[root@node1 elasticsearch-head]
修改主配置文件,在文件末尾插入以下两行 http.cors.enabled: true 开启跨域访问支持,默认为false http.cors.allow-origin: “*” 跨域访问允许的域名地址
[root@node1 ~]
http.cors.enabled: true
http.cors.allow-origin: "*"
[root@node1 ~]
启动 elasticsearch-head
[root@node1 ~]
[root@node1 elasticsearch-head]
[1] 123253
[root@node1 elasticsearch-head]
> elasticsearch-head@0.0.0 start /usr/local/src/elasticsearch-head
> grunt server
Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:9100
查看 elasticsearch-head 查看可视化工具是否成功应用 在宿主机浏览器输入:http://192.168.177.100:9100/ ,在Elasticsearch 后面的栏目中输入http://192.168.177.100:9200 在虚拟机192.168.177.100(node1)的终端上创建索引、类型、文档 [root@node1 elasticsearch-head]# curl -XPUT ‘localhost:9200/index-demo2/test/1?pretty&pretty’ -H ‘content-Type: application/json’ -d ‘{“user”:“lisi”,“mesg”:“this is my name”}’ { “_index” : “index-demo2”, “_type” : “test”, “_id” : “1”, “_version” : 1, “result” : “created”, “_shards” : { “total” : 2, “successful” : 2, “failed” : 0 }, “created” : true } 在宿主机浏览器查看记录,索引默认被分片5个,并且有一个副本
3.4步骤四:安装logstash并做一些日志搜集输出到elasticsearch中
在 192.168.177.111 日志生产服务器上安装 httpd logstash
hostnamectl set-hostname httpd
yum -y install httpd
systemctl start httpd
如果没有安装java 请yum安装
[root@httpd ~]
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
安装logstash,提前上传 logstash-5.5.1.rpm 到 opt目录
[root@httpd ~]
[root@httpd opt]
[root@httpd opt]
[root@httpd opt]
[root@httpd opt]
logstash 与 elasticsearch 做对接测试 测试命令:logstash 选项介绍: -f:通过这个选项可以指定logstash的配置文件,根据配置文件配置logstash -e:后面跟着字符串 该字符串可以被当做logstash的配置(如果是” ”,则默认使用stdin做为输入、stdout作为输出) -t:测试配置文件是否正确,然后退出
logstash -e ‘input { stdin{} } output { stdout{} }’ 此命令需要手动输入收集得内容
[root@httpd data]
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path //usr/share/logstash/config/log4j2.properties. Using default config which logs to console
16:47:14.849 [[main]-pipeline-manager] INFO logstash.pipeline - Starting pipeline {"id"=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>500}
16:47:14.879 [[main]-pipeline-manager] INFO logstash.pipeline - Pipeline main started
The stdin plugin is now waiting for input:
16:47:14.944 [Api Webserver] INFO logstash.agent - Successfully started Logstash API endpoint {:port=>9602}
www.baidu.com //stdin{} 输入采用标准输入
2021-08-13T08:51:48.987Z httpd www.baidu.com //stdout{}输出采用标准输出
www.sina.com //stdin{} 输入采用标准输入
2021-08-13T08:51:54.497Z httpd www.sina.com //stdout{}输出采用标准输出
www.qq.com //stdin{} 输入采用标准输入
2021-08-13T08:51:59.841Z httpd www.qq.com //stdout{}输出采用标准输出
www.aliyun.com //stdin{} 输入采用标准输入
2021-08-13T08:52:05.253Z httpd www.aliyun.com //stdout{}输出采用标准输出
使用rubydebug显示详细输出,在 192.168.177.111 (httpd服务器)终端上输入以下内容 logstash -e ‘input { stdin{} } output { stdout{ codec=>rubydebug } }’ 此命令需要手动输入收集得内容
[root@httpd data]
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path //usr/share/logstash/config/log4j2.properties. Using default config which logs to console
17:20:17.084 [[main]-pipeline-manager] INFO logstash.pipeline - Starting pipeline {"id"=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>500}
17:20:17.106 [[main]-pipeline-manager] INFO logstash.pipeline - Pipeline main started
The stdin plugin is now waiting for input:
17:20:17.157 [Api Webserver] INFO logstash.agent - Successfully started Logstash API endpoint {:port=>9602}
www.baidu.com
{
"@timestamp" => 2021-08-13T09:20:28.602Z, //详细输出stdout{ codec=>rubydebug } codec是一种编解码器
"@version" => "1",
"host" => "httpd",
"message" => "www.baidu.com"
}
www.aliyun.com
{
"@timestamp" => 2021-08-13T09:20:44.200Z,
"@version" => "1",
"host" => "httpd",
"message" => "www.aliyun.com"
}
使用logstash将信息写入elasticsearch中,在 192.168.177.111 (httpd服务器)终端上输入以下内容 logstash -e ‘input { stdin{} } output { elasticsearch { hosts=>[“192.168.177.100:9200”] } }’ stdin{}:标准输入,output {} 标准输出,elasticsearch { hosts=>[“192.168.177.100:9200”] }:对接elasticsearch集群
[root@httpd data]
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path //usr/share/logstash/config/log4j2.properties. Using default config which logs to console
17:25:51.655 [[main]-pipeline-manager] INFO logstash.outputs.elasticsearch - Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>[http://192.168.177.100:9200/]}}
17:25:51.658 [[main]-pipeline-manager] INFO logstash.outputs.elasticsearch - Running health check to see if an Elasticsearch connection is working {:healthcheck_url=>http://192.168.177.100:9200/, :path=>"/"}
17:25:51.745 [[main]-pipeline-manager] WARN logstash.outputs.elasticsearch - Restored connection to ES instance {:url=>
17:25:51.747 [[main]-pipeline-manager] INFO logstash.outputs.elasticsearch - Using mapping template from {:path=>nil}
17:25:52.154 [[main]-pipeline-manager] INFO logstash.outputs.elasticsearch - Attempting to install template {:manage_template=>{"template"=>"logstash-*", "version"=>50001, "settings"=>{"index.refresh_interval"=>"5s"}, "mappings"=>{"_default_"=>{"_all"=>{"enabled"=>true, "norms"=>false}, "dynamic_templates"=>[{"message_field"=>{"path_match"=>"message", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false}}}, {"string_fields"=>{"match"=>"*", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false, "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}}}}], "properties"=>{"@timestamp"=>{"type"=>"date", "include_in_all"=>false}, "@version"=>{"type"=>"keyword", "include_in_all"=>false}, "geoip"=>{"dynamic"=>true, "properties"=>{"ip"=>{"type"=>"ip"}, "location"=>{"type"=>"geo_point"}, "latitude"=>{"type"=>"half_float"}, "longitude"=>{"type"=>"half_float"}}}}}}}}
17:25:52.180 [[main]-pipeline-manager] INFO logstash.outputs.elasticsearch - New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>[
17:25:52.211 [[main]-pipeline-manager] INFO logstash.pipeline - Starting pipeline {"id"=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>500}
17:25:52.260 [[main]-pipeline-manager] INFO logstash.pipeline - Pipeline main started
The stdin plugin is now waiting for input:
17:25:52.343 [Api Webserver] INFO logstash.agent - Successfully started Logstash API endpoint {:port=>9602}
www.baidu.com //上传到elasticsearch集群中的内容
logstash对日志文件的收集,在 192.168.177.111(httpd服务器)的 /etc/logstash/conf.d/ 目录下创建配置文件
//对系统日志的收集,需要给其他用户读权限
chmod o+r /var/log/messages
vim /etc/logstash/conf.d/system.conf
input {
file{
path => "/var/log/messages" //文档
type => "system" //类型
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["192.168.177.100:9200"] //对接的es集群节点
index => "system-%{+YYYY.MM.dd}" //索引
}
}
重启logstash服务
systemctl restart logstash.service
宿主机浏览器查看系统日志收集情况 虽然 logstash + elastcisearch 已经做到了日志收集的功能,但是显示并不友好,此时使用kibana来实现友好显示收集的日志信息 在192.168.177.100(es集群node1节点)安装kibana,提前上传 kibana-5.5.1-x86_64.rpm 到/usr/local/src目录
[root@node1 ~]
[root@node1 src]
[root@node1 src]
[root@node1 kibana]
[root@node1 kibana]
定位到第2行,去掉注释,开启kibana的端口,
server.port: 5601
定位到第7行,去掉注释,设置kibana监听地址
server.host: "0.0.0.0" //表示任意主机都可以访问kibana
定位到21行,去掉注释,配置kibana对接es集群
elasticsearch.url: "http://192.168.177.100:9200"
定位到31行,去掉注释,在es集群中添加.kibana索引
30 kibana.index: ".kibana"
[root@node1 kibana]
[root@node1 kibana]
配置完毕,先在宿主机浏览器访问 http://192.168.177.100:5601 查看是否收集到系统日志 配置对httpd服务的访问日志和错误日志的收集,在 192.168.177.111(httpd服务器)上 /etc/logstash/conf.d/ 目录下创建配置文件
[root@httpd conf.d]
[root@httpd conf.d]
http_log.conf system.conf
[root@httpd conf.d]
input {
file{
path => "/etc/httpd/logs/access_log" //收集的日志文件名
type => "access" //类型是访问
start_position => "beginning" //从日志的开头开始收集
}
file{
path => "/etc/httpd/logs/error_log"
type => "error" //类型是错误
start_position => "beginning"
}
}
output {
if [type] == "access" { //判断input中的type字段,根据type创建索引名称
elasticsearch {
hosts => ["192.168.177.100:9200"] //对接的es集群节点
index => "apache_access-%{+YYYY.MM.dd}" //创建的索引名称
}
}
if [type] == "error" {
elasticsearch {
hosts => ["192.168.177.100:9200"]
index => "apache_error-%{+YYYY.MM.dd}"
}
}
}
重启logstash服务
systemctl restart logstash.service
宿主机浏览器输入 http://192.168.177.100:9100 查看索引信息
宿主机浏览器输入 http://192.168.177.100:5601 查看索引信息
|