生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]
Photo by Ugne Vasyliute on Unsplash
设置正确的日志记录基础结构可帮助我们查找发生的问题、调试和监视应用程序。从最基本的角度来看,我们应该从基础架构中得到以下内容:

  • 能够在我们的日志中自由搜索文本

  • 能够搜索特定的 api 日志

  • 能够根据所有 API 的 statusCode 进行搜索

  • 随着我们向日志中添加更多的数据,系统应该是可扩展的

架构

生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]
使用ElasticSearch,Fluentd 和 Kibana 的架构图

提示:复用 JavaScript 组件

使用Bit(https://github.com/teambit/bit)在不同项目之间共享和重用 JavaScript 组件。团队协作共享组件可以更快地构建应用程序。让 Bit 承担繁重的工作,可以使你可以轻松地发布、安装和更新各个组件,而不会产生任何开销。在此处了解更多信息(https://bit.dev/)。

生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]

带有 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=()

并运行我们之前运行的查询(稍微冗长一些)

生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]

使用 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/*.gem1516COPY fluent.conf /fluentd/etc/f

luent 的配置文件

 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 forward11  port 2422412  bind 0.0.0.013</source>1415# We need to massage the data before if goes into the ES16<filter **>17  # We parse the input with key "log" (https://docs.fluentd.org/filter/parser)18  @type parser19  key_name log20  # Keep the original key value pair in the result21  reserve_data true22  <parse>23    # Use apache2 parser plugin to parse the data24    @type multi_format25    <pattern>26      format apache227    </pattern>28    <pattern>29      format json30      time_key timestamp31    </pattern>32    <pattern>33      format none34    </pattern>35  </parse>36</filter>373839# Fluentd will decide what to do here if the event is matched40# 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 inbuilt43# copy output plugin https://docs.fluentd.org/output/copy44  @type copy45  <store>46  # We want to store our data to elastic search using out_elasticsearch plugin47  # https://docs.fluentd.org/output/elasticsearch. See Dockerfile for installation48    @type elasticsearch49    time_key timestamp_ms50    host 0.0.0.051    port 920052    # Use conventional index name format (logstash-%Y.%m.%d)53    logstash_format true54    # We will use this when kibana reads logs from ES55    logstash_prefix fluentd56    logstash_dateformat %Y-%m-%d57    flush_interval 1s58    reload_connections false59    reconnect_on_error true60    reload_on_failure true61  </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      - fluentd15    logging:16      driver: "fluentd"17      options:18        fluentd-address: localhost:2422419  elasticsearch:20    image: elasticsearch:7.4.121    ports:22      - "9200:9200"23      - "9300:9300"24    environment:25      - discovery.type=single-node26  kibana:27    image: kibana:7.4.128    links:29      - "elasticsearch"30    ports:31      - "5601:5601"

就是这样而已。我们的基础架构已准备就绪。现在可以通过访问 http://localhost:3000 来生成一些日志。

现在,我们再次转到 kibana 仪表板,并定义要使用的索引:

生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]

设置在 kibana 中使用的索引
注意,在我们的 fluent.conf 中提到了 logstash_prefix fluentd,因此我们在这里使用相同的字符串。接下来是一些基本的 kibana 设置。

生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]
设置 kibana 配置
弹性搜索使用动态映射来猜测其索引字段的 type。下面的截图显示了这些:

生产环境下的 Node.js 日志记录方案[每日前端夜话0xFD]

弹性搜索的截图示例
让我们检查一下如何满足开始时提到的要求:

* 能够在日志中自由文本搜索: 在 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

更多相关文章

  1. 用 globalThis 访问全局对象[每日前端夜话0xF6]
  2. 9 个强大的 JavaScript 小技巧[每日前端夜话0xFC]
  3. 从 JavaScript、ES6、ES7 到 ES10,你学到哪儿了?[每日前端夜话0xF8
  4. 一文学会 Node.js 中的流[每日前端夜话0xF4]
  5. 你即将使用的ES2020新功能[每日前端夜话0xF3]
  6. 15个 Vue.js 高级面试题[每日前端夜话0xF2]
  7. 能用 CSS 能播放声音吗?[每日前端夜话0xF1]
  8. 你可能不知道的15个 Git 命令[每日前端夜话0xF5]
  9. 23 个初级 Vue.js 面试题[每日前端夜话0xF0]

随机推荐

  1. Android面试题总结(七)原理篇
  2. 在AndroidStudio中使用V8包中的RenderScr
  3. Android实现全屏的方法
  4. UI 开源代码 FileBrowserView
  5. android根据ListView内部Item最大长度来
  6. Android设定屏幕只竖屏或只横屏的两种方
  7. 如何关联androidSDK源代码
  8. Android 全局Activity动画设置
  9. Android开发9——Activity的启动模式
  10. 浅谈Android Surface机制