ELK组成
参考链接:https://zhuanlan.zhihu.com/p/26399963
ELK架构
- Shipper:负责收集各种来源的日志数据,可以是系统日志、文件、redis、mq等等;
- Broker:作为Shipper与中心Indexer之间的缓冲区(redis,kafka,RabbitMQ),主要是为了可以提高系统的性能和可靠性,当Indexer提取数据失败时,数据保存在redis中,而不至于丢失;
- Indexer:负责从Broker中取出数据,对数据进行格式化和相关处理后,输出到Elasticsearch中存储;
- Elasticsearch:一个分布式搜索引擎和分析引擎,用于数据存储,可提供实时的数据查询。
- Kibana:一个数据可视化服务,根据用户的操作从Elasticsearch中查询数据,形成相应的分析结果,以图表的形式展现给用户。
部署ELK方案
- 在每台生成日志文件的机器上,部署Logstash,作为Shipper的角色,负责从日志文件中提取数据,但是不做任何处理,直接将数据输出到Redis队列(list)中;
- 需要一台机器部署Logstash,作为Indexer的角色,负责从Redis中取出数据,对数据进行格式化和相关处理后,输出到Elasticsearch中存储;
- 部署Elasticsearch集群,当然取决于你的数据量了,数据量小的话可以使用单台服务,如果做集群的话,最好是有3个以上节点,同时还需要部署相关的监控插件;
- 部署Kibana服务,提供Web服务。
在上面的部署方案中,我们将Logstash分为Shipper和Indexer两种角色来完成不同的工作,中间通过Redis做数据管道。
为什么要这样做?为什么不是直接在每台机器上使用Logstash提取数据、处理、存入Elasticsearch?采用这样的架构部署,有三点优势:
- 降低对日志所在机器的影响,这些机器上一般都部署着反向代理或应用服务,本身负载就很重了,所以尽可能的在这些机器上少做事;
- 如果有很多台机器需要做日志收集,那么让每台机器都向Elasticsearch持续写入数据,必然会对Elasticsearch造成压力,因此需要对数据进行缓冲,同时这样的缓冲也可以一定程度的保护数据不丢失;
- 将日志数据的格式化与处理放到Indexer中统一做,可以在一处修改代码、部署,避免需要到多台机器上去修改配置。
docker部署ELK
参考链接:https://logz.io/blog/docker-logging/
推荐docker:https://github.com/deviantony/docker-elk
端口占用情况:
- 5000: Logstash TCP input.
- 9200: Elasticsearch HTTP
- 9300: Elasticsearch TCP transport
- 5601: Kibana
Logspout
Logspout是Docker流行和轻量级的(15.2MB)日志路由器,它将附加到主机中的所有容器,并将Docker日志流输出到syslog服务器(除非定义了不同的输出目标)。
Filebeat
Filebeat属于Elastic的Beats系列日志收集组件, Filebeat是用Go语言开发的,支持追踪特定文件和日志加密的中间组件,它可以配置将日志导出到Logstash或者直接导出到Elasticsearch。
如果没有额外指定,容器的stdout和stderr输出(也称为“docker logs”)输出到JSON文件。所以,如果是一个小型Docker环境,使用Filebeat来收集日志将是不错的选择。但如果使用其他日志记录驱动程序,则可能需要考虑其他方法。
Logging Driver
Docker从1.12开始支持Logging Driver,允许将Docker日志路由到指定的第三方日志转发层,可将日志转发到AWS CloudWatch,Fluentd,GELF或NAT服务器。
docker应用服务器配置
Nginx
日志格式化,日志输出重定向
http {} 节点添加如下配置信息:1
2
3
4
5
6log_format main '[$remote_addr, $request, $status, $body_bytes_sent, '
'$http_user_agent, $http_referer, $http_x_forwarded_for, $request_time, '
'$upstream_response_time, $http_cookie, $http_Authorization, $http_token]';
access_log /dev/stdout main;
error_log /dev/stdout;
注意,在Docker中
/var/log/nginx/access.log -> /dev/stdout
/var/log/nginx/error.log -> /dev/stderr
为了方便logstash进行分割,建议使用如下格式:1
2
3
4
5
6
7
8
9
10
11
12
13log_format main '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"agent":"$http_user_agent",'
'"status":"$status"}';
Logstash 配置信息
1 | input { |
注意:这里input默认是使用TCP,现在修改为UDP,则docker-compse.yml需要修改ports为 “port:5000/udp”
input参数说明
type
- 对应_type
output参数说明
flush_size idle_flush_time
- Logstash 会努力攒到 20000 条数据一次性发送出去,但是如果 10 秒钟内也没攒够 20000 条,Logstash 还是会以当前攒到的数据量发一次。
index
- 写入的 ES 索引的名称,这里可以使用变量。为了更贴合日志场景,Logstash 提供了 %{+YYYY.MM.dd} 这种写法。在语法解析的时候,看到以 + 号开头的,就会自动认为后面是时间格式,尝试用时间格式来解析后续字符串。此外,注意索引名中不能有大写字母,否则 ES 在日志中会报 InvalidIndexNameException,但是 Logstash 不会报错,这个错误比较隐晦,也容易掉进这个坑中。
hosts
- host 可以设置数组,它会从节点列表中选取不同的节点发送数据,达到 Round-Robin 负载均衡的效果。
Logstas 过滤日志
Logspout
查看收集Logspout收集nginx日志1
curl http://ip:port/logs
docker日志处理
在部署一个传统的Linux时,应用程序或者架构记录日志的方式通常记录到文件里,一般会记录到/var/log目录下。
Docker有什么不同呢?不同于以往将所有日志放在主机系统的统一位置,如今日志分散在很多不同容器的相互隔离的环境中。
典型ELK日志收集流程如下所示:
Logstash负责从各种Docker容器和主机中提取日志,这个流程的主要优点是可以更好地用过滤器来解析日志,Logstash将日志转发到Elasticsearch进行索引,Kibana分析和可视化数据。
这个流程可以有多种不同的实现方式, 例如可以使用不同的日志收集和转发组件, 如Fluentd或Filebeat 将日志发送到Elasticsearch。或者添加一个由Kafka或Redis容器组成的中间层,作为Logstash和Elasticsearch之间的缓冲区。
docker-compose
1 | git clone https://github.com/deviantony/docker-elk.git |
正常情况下, ELK套件的三个服务(Elasticsearch, Logstash, Kibana)会启动成功,默认持久化数据目录 /var/lib/elasticsearch (Elasticsearch 的数据存储目录)
测试Elasticsearch1
curl localhost:9200
返回结果1
2
3
4
5
6
7
8
9
10
11
12
13{
"name" : "6cU6dcx",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "PGZdqdKdQiKwh67to_2H7g",
"version" : {
"number" : "5.6.3",
"build_hash" : "1a2f265",
"build_date" : "2017-10-06T20:33:39.012Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}
打开Kibaba web页面 localhost:5601
Logspout 收集日志
如果docker服务使用docker-compose管理,则添加如下配置信息1
2
3
4
5
6
7
8logspout:
image: gliderlabs/logspout:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "10000:80"
command:
syslog://Logstash_IP:Logstash_port
查看logsout收集的日志1
curl http://localhost:10000/logs