生产环境下的 Node.js 日志记录方案

使用 ElasticSearch,Fluentd和Kibana 设置 Node.js 日志记录基础结构。前端

做者:Abhinav Dhasmananode

翻译:疯狂的技术宅webpack

原文:blog.bitsrc.io/setting-up-…git

未经容许严禁转载github

Photo by Ugne Vasyliute on Unsplash

设置正确的日志记录基础结构可帮助咱们查找发生的问题、调试和监视应用程序。从最基本的角度来看,咱们应该从基础架构中获得如下内容:web

  • 可以在咱们的日志中自由搜索文本
  • 可以搜索特定的 api 日志
  • 可以根据全部 API 的 statusCode 进行搜索
  • 随着咱们向日志中添加更多的数据,系统应该是可扩展的

架构

使用ElasticSearch,Fluentd 和 Kibana 的架构图

提示:复用 JavaScript 组件

使用BitGithub)在不一样项目之间共享和重用 JavaScript 组件。团队协做共享组件能够更快地构建应用程序。让 Bit 承担繁重的工做,可使你能够轻松地发布、安装和更新各个组件,而不会产生任何开销。 在此处了解更多信息docker

带有 Bit 的 Loader 组件:轻松地在项目之间共享和同步

本地设置

咱们将用 Docker 来管理服务。apache

弹性搜寻

使用如下命令启动并运行 ElasticSearchnpm

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --name myES docker.elastic.co/elasticsearch/elasticsearch:7.4.1
复制代码

能够经过如下命令检查你的容器是否已启动并运行json

curl -X GET "localhost:9200/_cat/nodes?v&pretty"
复制代码

Kibana

能够用另外一个 docker run 命令启动 Kibana 并使其运行。

docker run —-link myES:elasticsearch -p 5601:5601 kibana:7.4.1
复制代码

请注意,咱们正在使用 --link 命令连接 kibana 和弹性搜索服务器

若是转到 http://localhost:5601/app/kibana,将会看到咱们的 kibana 仪表板。

如今,可使用 kibana 对咱们的弹性搜索集群运行全部查询。咱们能够导航到

http://localhost:5601/app/kibana#/dev_tools/console?_g=()
复制代码

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

使用 kibana 查询弹性簇节点

Fluentd

Fluentd 是对全部数据进行格式化的地方。

让咱们首先构建咱们的 Dockerfile。它有两件事:

  • 安装必要的软件包
  • 将配置文件复制到 docker 文件中

适用于 fluentd 的 Dockerfile:

FROM fluent/fluentd:latest
MAINTAINER Abhinav Dhasmana <Abhinav.dhasmana@live.com>

USER root

RUN apk add --no-cache --update --virtual .build-deps \
  sudo build-base ruby-dev \
  && sudo gem install fluent-plugin-elasticsearch \
  && sudo gem install fluent-plugin-record-modifier \
  && sudo gem install fluent-plugin-concat \
  && sudo gem install fluent-plugin-multi-format-parser \
  && sudo gem sources --clear-all \
  && apk del .build-deps \
  && rm -rf /home/fluent/.gem/ruby/2.5.0/cache/*.gem

COPY fluent.conf /fluentd/etc/
复制代码

fluent 的配置文件:

# Recieve events over http from port 9880
<source>
  @type http
  port 9880
  bind 0.0.0.0
</source>

# Recieve events from 24224/tcp
<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

# We need to massage the data before if goes into the ES
<filter **>
  # We parse the input with key "log" (https://docs.fluentd.org/filter/parser)
  @type parser
  key_name log
  # Keep the original key value pair in the result
  reserve_data true
  <parse>
    # Use apache2 parser plugin to parse the data
    @type multi_format
    <pattern>
      format apache2
    </pattern>
    <pattern>
      format json
      time_key timestamp
    </pattern>
    <pattern>
      format none
    </pattern>
  </parse>
</filter>


# Fluentd will decide what to do here if the event is matched
# In our case, we want all the data to be matched hence **
<match **>
# We want all the data to be copied to elasticsearch using inbuilt
# copy output plugin https://docs.fluentd.org/output/copy
  @type copy
  <store>
  # We want to store our data to elastic search using out_elasticsearch plugin
  # https://docs.fluentd.org/output/elasticsearch. See Dockerfile for installation
    @type elasticsearch
    time_key timestamp_ms
    host 0.0.0.0
    port 9200
    # Use conventional index name format (logstash-%Y.%m.%d)
    logstash_format true
    # We will use this when kibana reads logs from ES
    logstash_prefix fluentd
    logstash_dateformat %Y-%m-%d
    flush_interval 1s
    reload_connections false
    reconnect_on_error true
    reload_on_failure true
  </store>
</match>
复制代码

让咱们使这台 Docker 机器跑起来

docker build -t abhinavdhasmana/fluentd .docker run -p 9880:9880  --network host  abhinavdhasmana/fluentd
复制代码

Node.js 应用

我已经建立了一个用于演示的小型 Node.js 程序,你能够在 github.com/abhinavdhas… 中找到。这是一个用 Express Generator 建立的小型 Express 应用。它用 morgan 生成 apache 格式的日志。你也能够用本身的应用。只要输出保持不变,咱们的基础架构就不会在乎。让咱们构建并运行 docker 映像。

docker build -t abhinavdhasmana/logging .
复制代码

固然,咱们能够经过下面给出的单个 docker compose 文件来获取全部 docker 容器。

为 EFK 设置撰写的 docker compose文件:

version: "3"
services:
 fluentd:
 build: "./fluentd"
 ports:
 - "9880:9880"
 - "24224:24224"
 network_mode: "host"
 web:
 build: .
 ports:
 - "3000:3000"
 links:
 - fluentd
 logging:
 driver: "fluentd"
 options:
 fluentd-address: localhost:24224
 elasticsearch:
 image: elasticsearch:7.4.1
 ports:
 - "9200:9200"
 - "9300:9300"
 environment:
 - discovery.type=single-node
 kibana:
 image: kibana:7.4.1
 links:
 - "elasticsearch"
 ports:
 - "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 实例。

欢迎关注前端公众号:前端先锋,免费领取 webpack 从入门到进阶全系列教程。

相关文章
相关标签/搜索