本文记录了一次日志平台的搭建。主要场景如下:
- 应用将日志发送给RabbitMQ
- Logstash连接到RabbitMQ抽取日志
- Logstash将抽取的日志内容做一些加工,然后存入到Elasticsearch中
- Kibana连接到Elasticsearch,提供日志查询、展现等功能。
整个过程图形表示如下:
1.先下载要用到的Docker镜像文件
1. [root@14-28]# docker images
2. REPOSITORY TAG IMAGE ID CREATED SIZE
3. rabbitmq 3.6-management f2e38e79371c 2 months ago 149MB
4. docker.elastic.co/logstash/logstash 6.2.43 months ago 657MB
5. docker.elastic.co/kibana/kibana 6.2.43 months ago 933MB
6. docker.elastic.co/elasticsearch/elasticsearch 6.2.43 months ago 515MB
注意,rabbitmq是从docker官方镜像仓库拉取的:https://store.docker.com/images/rabbitmq
Elasticsearch相关的3个镜像是从Elasticsearch官网拉取的:https://www.docker.elastic.co/
2.准备容器编排文件
这里用到的docker-compose来编排容器,文件如下:
1. root@Ubuntusvr1:~/elk# cat docker-compose.yml
2. version: '2'
3. services:
4. rabbitmq:
5. 3.6-management
6. ports:
7. "5672:5672"
8. "15672:15672"
9. container_name:
10. rabbitmq-ichub
11. hostname:
12. rabbitmq-ichub
13. environment:
14. "RABBITMQ_DEFAULT_USER=dev"
15. "RABBITMQ_DEFAULT_PASS=123456"
16.
17. elasticsearch:
18. 6.2.4
19. ports:
20. "9200:9200"
21. "9300:9300"
22. container_name:
23. elasticsearch
24. environment:
25. "xpack.security.enabled=false"
26. "discovery.type=single-node"
27. "ES_JAVA_OPTS=-Xms512m -Xmx512m"
28.
29. kibana:
30. 6.2.4
31. container_name:
32. kibana
33. depends_on:
34. - elasticsearch
35. ports:
36. "5601:5601"
37. links:
38. - elasticsearch
39. environment:
40. "xpack.security.enabled=false"
41.
42. logstash:
43. 6.2.4
44. container_name:
45. logstash
46. depends_on:
47. - elasticsearch
48. - rabbitmq
49. ports:
50. "25826:25826"
51. links:
52. - elasticsearch
53. - rabbitmq
54. volumes:
55. - $PWD/logstashpipeline:/usr/share/logstash/pipeline
这里要注意的是,创建rabbitmq容器必须指定hostname参数,因为此镜像是基于NodeName(默认等于hostname)来存储数据的。
loastash容器,我们通过卷指定了配置文件的路径,从而控制容器使用我们的管道配置文件。
另外,这里也指定了depends_on参数,因为容器之间存在依赖项,比如要等RabbitMQ容器起来之后,Logstash容器才能连接到队列上。所以Logstash容器需要依赖RabbitMQ容器。
3.配置logstash从rabbitmq抽取数据。
1. root@Ubuntusvr1:~/elk# cat logstashpipeline/rabbitmq.conf
2. input{
3. {
4. "rabbitmq"
5. "ichub_log_exchange"
6. "topic"
7. "#"
8. "ichub_log"
9. 30
10. durable => true
11. "123456"
12. "dev"
13. "plain"
14. }
15. }
16.
17. filter {
18. {
19. {"message""%{TIMESTAMP_ISO8601:logtime} %{NUMBER:pid} %{WORD:level} (?<dbname>\S*) %{USERNAME:modul}: %{GREEDYDATA:msgbody}"}
20. }
21. {
22. ["logtime", "YYYY-MM-dd HH:mm:ss,SSS"]
23. "@timestamp"
24. }
25. }
26.
27. output
28. {
29. {
30. "elasticsearch:9200"
31. "ichub_prod-%{+YYYY.MM.dd}"
32. }
33. }
其实主要的工作就在这里,分为三块。input配置数据来源,filter过滤数据,output将数据传输给Elasticsearch。
input
这里用到了logstash的rabbitmq的输入插件,其详细的配置文件在这里
值得注意的是,这个插件默认的解码器用的是JSON,因为我们的日志是一行一行的文本,字段之间用空格分割,所以这里配置的codec是plain。
另外,这里明确的指定了rabbitmq的exchange、exchange_type、key,这样logstash启动的时候会连接到RabbitMQ,并自动创建交换器及队列。
filter
这里用到了grok来解析日志。因为我们的时间格式不是默认支持的,所以用到了data插件来专门解析时间,并将解析的时间覆盖到@timestamp字段,作为Elasticsearch的时间索引字段。
由于我们的日志中数据库名这个字段,可能是一个问号“?”,所以不能用默认的WORD模式,这里我用了正则表达式来匹配数据库名。
这里需要解释下日志解析的模式:%{TIMESTAMP_ISO8601:timestap} %{NUMBER:pid} %{WORD:level} (?<dbname>\S*) %{USERNAME:modul}: %{GREEDYDATA:msgbody}
TIMESTAMP_ISO8601:匹配时间
NUMBER:匹配数字
WORD:匹配单词
(?<dbname>\S*):匹配一个不包含非空字符的字符串,本场景主要匹配:ic_new,?这两种情况。
GREEDYDATA:匹配剩下的所有内容
USERNAME:匹配由字母、数字、句点、下划线和横杠组成的字符串。
在用到grok解析日志时,可以使用Kibana自带的grok调试工具
也可以用在线的Grok调试工具
output
这里配置为输出到Elasticsearch服务器,并指定了index的名字,固定字符串开头,根据日期每天创建一个索引。
注意,如果遇到问题,可以将数据输出到控制台,方便定位问题:
1. output
2. {
3. {
4. codec => dots
5. }
6. {
7. "elasticsearch:9200"
8. "ichub-%{+YYYY.MM.dd}"
9. }
10. }
这样我们配置了2个输出,一个输出到控制台,一个输出到Elasticsearch。控制台会有如下信息:
4.创建并启动容器
1. # docker-compose up -d
调试的时候,可以连接到logstash容器去查看实时的日志:
1. # docker logs -f logstash
5.在Kibana中配置索引,查询日志。
打开索引创建页面,如果logstash已经开始传输数据,就能看到我们在配置文件中指定的索引了。
配置好索引后,即可在Discover页面查询到日志数据。
Post Views: 249