生產環境下的 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 從入門到進階全系列教程。

相關文章
相關標籤/搜索