生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]
疯狂的技术宅 前端先锋
每日前端夜话0xFD 每日前端夜话,陪你聊前端。 每天晚上18:00准时推送。 正文共:1533 字 预计阅读时间:7分钟 翻译:疯狂的技术宅 作者:Abhinav Dhasmana 来源:bitsrc.io
Photo by Ugne Vasyliute on Unsplash 设置正确的日志记录基础结构可帮助我们查找发生的问题、调试和监视应用程序。从最基本的角度来看,我们应该从基础架构中得到以下内容:
- 能够在我们的日志中自由搜索文本
- 能够搜索特定的 api 日志
- 能够根据所有 API 的 statusCode 进行搜索
- 随着我们向日志中添加更多的数据,系统应该是可扩展的
架构
使用ElasticSearch,Fluentd 和 Kibana 的架构图
提示:复用 JavaScript 组件
使用Bit(https://github.com/teambit/bit)在不同项目之间共享和重用 JavaScript 组件。团队协作共享组件可以更快地构建应用程序。让 Bit 承担繁重的工作,可以使你可以轻松地发布、安装和更新各个组件,而不会产生任何开销。在此处了解更多信息(https://bit.dev/)。
带有 Bit 的 Loader 组件:轻松地在项目之间共享和同步
本地设置
我们将用 Docker 来管理服务。
弹性搜寻
使用以下命令启动并运行 ElasticSearch
1docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --name myES docker.elastic.co/elasticsearch/elasticsearch:7.4.1
可以通过以下命令检查你的容器是否已启动并运行
1curl -X GET "localhost:9200/_cat/nodes?v&pretty"
Kibana
可以用另一个 docker run 命令启动 Kibana 并使其运行。
1docker run —-link myES:elasticsearch -p 5601:5601 kibana:7.4.1
请注意,我们正在使用 --link 命令链接 kibana 和弹性搜索服务器
如果转到 http://localhost:5601/app/kibana,将会看到我们的 kibana 仪表板。
现在,可以使用 kibana 对我们的弹性搜索集群运行所有查询。我们可以导航到
1http://localhost:5601/app/kibana#/dev_tools/console?_g=()
并运行我们之前运行的查询(稍微冗长一些)
使用 kibana 查询弹性簇节点
Fluentd
Fluentd 是对所有数据进行格式化的地方。
让我们首先构建我们的 Dockerfile。它有两件事:
- 安装必要的软件包
- 将配置文件复制到 docker 文件中 适用于 fluentd 的 Dockerfile:
1FROM fluent/fluentd:latest
2MAINTAINER Abhinav Dhasmana <Abhinav.dhasmana@live.com>
3
4USER root
5
6RUN apk add --no-cache --update --virtual .build-deps \
7 sudo build-base ruby-dev \
8 && sudo gem install fluent-plugin-elasticsearch \
9 && sudo gem install fluent-plugin-record-modifier \
10 && sudo gem install fluent-plugin-concat \
11 && sudo gem install fluent-plugin-multi-format-parser \
12 && sudo gem sources --clear-all \
13 && apk del .build-deps \
14 && rm -rf /home/fluent/.gem/ruby/2.5.0/cache/*.gem
15
16COPY fluent.conf /fluentd/etc/
fluent 的配置文件:
1# Recieve events over http from port 9880
2<source>
3 @type http
4 port 9880
5 bind 0.0.0.0
6</source>
7
8# Recieve events from 24224/tcp
9<source>
10 @type forward
11 port 24224
12 bind 0.0.0.0
13</source>
14
15# We need to massage the data before if goes into the ES
16<filter **>
17 # We parse the input with key "log" (https://docs.fluentd.org/filter/parser)
18 @type parser
19 key_name log
20 # Keep the original key value pair in the result
21 reserve_data true
22 <parse>
23 # Use apache2 parser plugin to parse the data
24 @type multi_format
25 <pattern>
26 format apache2
27 </pattern>
28 <pattern>
29 format json
30 time_key timestamp
31 </pattern>
32 <pattern>
33 format none
34 </pattern>
35 </parse>
36</filter>
37
38
39# Fluentd will decide what to do here if the event is matched
40# In our case, we want all the data to be matched hence **
41<match **>
42# We want all the data to be copied to elasticsearch using inbuilt
43# copy output plugin https://docs.fluentd.org/output/copy
44 @type copy
45 <store>
46 # We want to store our data to elastic search using out_elasticsearch plugin
47 # https://docs.fluentd.org/output/elasticsearch. See Dockerfile for installation
48 @type elasticsearch
49 time_key timestamp_ms
50 host 0.0.0.0
51 port 9200
52 # Use conventional index name format (logstash-%Y.%m.%d)
53 logstash_format true
54 # We will use this when kibana reads logs from ES
55 logstash_prefix fluentd
56 logstash_dateformat %Y-%m-%d
57 flush_interval 1s
58 reload_connections false
59 reconnect_on_error true
60 reload_on_failure true
61 </store>
62</match>
让我们使这台 Docker 机器跑起来
1docker build -t abhinavdhasmana/fluentd .docker run -p 9880:9880 --network host abhinavdhasmana/fluentd
Node.js 应用
我已经创建了一个用于演示的小型 Node.js 程序,你可以在 https://github.com/abhinavdhasmana/logging-using-EFK 中找到。这是一个用 Express Generator 创建的小型 Express 应用。它用 morgan 生成 apache 格式的日志。你也可以用自己的应用。只要输出保持不变,我们的基础架构就不会在意。让我们构建并运行 docker 映像。
1docker build -t abhinavdhasmana/logging .
当然,我们可以通过下面给出的单个 docker compose 文件来获取所有 docker 容器。
为 EFK 设置撰写的 docker compose文件:
1version: "3"
2services:
3 fluentd:
4 build: "./fluentd"
5 ports:
6 - "9880:9880"
7 - "24224:24224"
8 network_mode: "host"
9 web:
10 build: .
11 ports:
12 - "3000:3000"
13 links:
14 - fluentd
15 logging:
16 driver: "fluentd"
17 options:
18 fluentd-address: localhost:24224
19 elasticsearch:
20 image: elasticsearch:7.4.1
21 ports:
22 - "9200:9200"
23 - "9300:9300"
24 environment:
25 - discovery.type=single-node
26 kibana:
27 image: kibana:7.4.1
28 links:
29 - "elasticsearch"
30 ports:
31 - "5601:5601"
就是这样而已。我们的基础架构已准备就绪。现在可以通过访问 http://localhost:3000 来生成一些日志。
现在,我们再次转到 kibana 仪表板,并定义要使用的索引:
设置在 kibana 中使用的索引 注意,在我们的 fluent.conf 中提到了 logstash_prefix fluentd,因此我们在这里使用相同的字符串。接下来是一些基本的 kibana 设置。
设置 kibana 配置 弹性搜索使用动态映射来猜测其索引字段的 type。下面的截图显示了这些:
弹性搜索的截图示例 让我们检查一下如何满足开始时提到的要求:
- 能够在日志中自由文本搜索: 在 ES 和 kibana 的帮助下,我们可以在任何字段上进行搜索以获得结果。
- 能够搜索特定的api日志: 在 kibana 左侧的 “Available fields” 部分中,我们可以看到字段 path。对其应用过滤器可以查找我们感兴趣的 API。
- 能够根据所有API的
statusCode
进行搜索: 与上述相同。使用 code 字段并应用过滤器。 - 随着向日志中添加更多的数据,系统应该是可扩展的: 我们使用以下环境变量 discovery.type = single-node 在单节点模式下开始了弹性搜索。可以从集群模式开始,添加更多节点,或者在我们选择的任何云提供商上使用托管解决方案。我已经尝试过了 AWS,并且易于设置。AWS 还免费提供 Elasticsearch 的托管 kibana 实例。 原文:https://blog.bitsrc.io/setting-up-a-logging-infrastructure-in-nodejs-ec34898e677e