目次
ビジネスの背景
フレームワーク全体を ELK に次の手順に簡単にまとめます:
従来、ログ出力を行う際には、ログレベル(レベル)とログ内容文字列(メッセージ)を直接出力していました。ただし、いつ何が起こったかに注意を払うだけでなく、同様のログが何回発生したか、ログの詳細とコンテキスト、および関連するログにも注意を払う必要がある場合があります。したがって、単にログをオブジェクトに構造化するだけでなく、ログのキー フィールドも抽出します。
各ログの発生をイベントとして抽象化します。イベントには以下が含まれます:
リクエストの一意の ID: reqId、このフィールドはリクエスト全体を通して実行されますリンク上で発生するすべてのイベント
データ フィールド
logger.debug('checkLogin');
ログイン後にコピー
" >
logger.debug('checkLogin');
ログイン後にコピー
イベントを出力する方法がわかったので、次のステップでは 2 つの質問について検討します。イベントをどこに出力すればよいでしょうか?
下游依赖
一些建议
一些原则
三、ES 索引模版定义
ホームページ ウェブフロントエンド jsチュートリアル NodeフレームワークをELKに接続するプロセスの概要

NodeフレームワークをELKに接続するプロセスの概要

Nov 21, 2018 am 11:23 AM
node.js フロントエンド

この記事の内容は、Node フレームワークを ELK に接続するプロセスをまとめたものです。必要な方は参考にしていただければ幸いです。

クラスタの数が増えると、この原始的な操作によってもたらされる非効率性が、既存のネットワークの問題を特定する際に大きな課題をもたらすだけではありません。同時に、対象を絞った最適化や改善はおろか、サービスフレームワークのさまざまな指標について効果的な定量的診断を行うこともできません。この際、情報検索、サービス診断、データ分析などの機能を備えたリアルタイムログ監視システムの構築が特に重要です。

ELK (ELK Stack: ElasticSearch、LogStash、Kibana、Beats) は、オープンソースと高いパフォーマンスを備え、大手企業で広く使用されている成熟したログ ソリューションです。私たちのビジネスで使用されているサービス フレームワークはどのように ELK システムに接続されていますか?

ビジネスの背景

当社のビジネス フレームワークの背景:

  • ビジネス フレームワークは NodeJs をベースとした WebServer です

  • #このサービスは、winston ログ モジュールを使用してログをローカライズします

  • #サービスによって生成されたログは、それぞれのマシンのディスクに保存されます

  • #サービスは異なるリージョンにデプロイされます 複数のマシン
  • アクセス手順

フレームワーク全体を ELK に次の手順に簡単にまとめます:

    ログ構造設計: 従来のプレーン テキスト ログを構造化オブジェクトに変更し、JSON として出力します。
  • ログ収集: フレームワーク内のいくつかの主要なノードでログを出力します。リクエストのライフ サイクル
  • ES インデックス テンプレートの定義: JSON から ES の実際のストレージへのマッピングの確立
  • 1. ログ構造の設計

従来、ログ出力を行う際には、ログレベル(レベル)とログ内容文字列(メッセージ)を直接出力していました。ただし、いつ何が起こったかに注意を払うだけでなく、同様のログが何回発生したか、ログの詳細とコンテキスト、および関連するログにも注意を払う必要がある場合があります。したがって、単にログをオブジェクトに構造化するだけでなく、ログのキー フィールドも抽出します。

1. ログをイベントに抽象化します

各ログの発生をイベントとして抽象化します。イベントには以下が含まれます:

イベント メタフィールド

イベント発生時刻: 日付時刻、タイムスタンプ

イベント レベル: レベル (例: ERROR、INFO、WARNING、DEBUG##)

#イベント名:event、例: client-request

イベントが発生する相対時間 (単位: ナノ秒): reqLife、このフィールドはイベントが発生し始める時間 (間隔) です。リクエストに関連する

イベントが発生する場所: 行、コードの場所、サーバー、サーバーの場所

リクエスト メタ フィールド

リクエストの一意の ID: reqId、このフィールドはリクエスト全体を通して実行されますリンク上で発生するすべてのイベント

リクエスト ユーザー ID: reqUid、このフィールドはユーザー ID であり、ユーザーのアクセスまたはリンクのリクエストを追跡できます

データ フィールド

イベントのタイプが異なると、異なる出力詳細が必要になります。これらの詳細 (非メタ フィールド) を d -- data に入れます。これにより、イベント構造がより明確になり、同時にデータ フィールドがメタ フィールドを汚染するのを防ぎます。

例: client-init イベントなど。サーバーがユーザーのリクエストを受信するたびに出力されます。ユーザーの IP、URL、その他のイベントを一意のデータ フィールドとして分類し、d オブジェクトに入れます#。

##完全な例を示します

{
    "datetime":"2018-11-07 21:38:09.271",
    "timestamp":1541597889271,
    "level":"INFO",
    "event":"client-init",
    "reqId":"rJtT5we6Q",
    "reqLife":5874,
    "reqUid": "999793fc03eda86",
    "d":{
        "url":"/",
        "ip":"9.9.9.9",
        "httpVersion":"1.1",
        "method":"GET",
        "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
        "headers":"*"
    },
    "browser":"{"name":"Chrome","version":"70.0.3538.77","major":"70"}",
    "engine":"{"version":"537.36","name":"WebKit"}",
    "os":"{"name":"Mac OS","version":"10.14.0"}",
    "content":"(Empty)",
    "line":"middlewares/foo.js:14",
    "server":"127.0.0.1"
}
ログイン後にコピー
ブラウザ、OS、エンジンなどのいくつかのフィールド 外層のログをできるだけ平らにしたい場合があるのはなぜですか (最大深さは 2 です) ) インデックス作成による不必要な ES パフォーマンスの損失を回避します。実際の出力では、深さが1より大きい値を文字列として出力します。場合によっては、一部のオブジェクト フィールドが重要になるため、出力の深さが 2 を超えないようにするために、これらの特別なフィールドを外層に配置します。

通常、ログを出力するときは、

イベント名データ フィールドに注意するだけで済みます。また、ログを出力する方法ではコンテキストにアクセスすることで一律に取得、計算、出力することができます。

2. ログ変換出力

ログ イベントの定義方法については前述しましたが、古いコードのログ呼び出しメソッドと互換性を保ちながら、既存のログ ソリューションに基づいてアップグレードするにはどうすればよいでしょうか。 。

主要ノードのログをアップグレード

// 改造前
logger.info('client-init => ' + JSON.stringfiy({
    url,
    ip,
    browser,
    //...
}));

// 改造后
logger.info({
    event: 'client-init',
    url,
    ip,
    browser,
    //...
});
ログイン後にコピー

古いログ呼び出しメソッドとの互換性

logger.debug('checkLogin');
ログイン後にコピー

winston の log メソッド自体は文字列またはオブジェクトの受信メソッドをサポートしているため、 old 文字列が渡されると、フォーマッタが実際に受け取るのは { level: 'debug', message: 'checkLogin' } です。フォーマッタは、ログ出力の前に Winston のログ形式を調整するプロセスであり、この種の呼び出しメソッドによるログ出力を、ログ出力前に純粋な出力イベントに変換する機会を提供します。これを変更する必要はありません。呼び出しメソッド。

ログ出力形式を変換する

前述したように、winston はログを出力する前に、事前定義されたフォーマッタを通過するため、互換性のあるロジックの処理に加えて、いくつかの共通の機能を追加できます。ここでロジックを扱います。電話に関しては、私たちは現場そのものにのみ焦点を当てています。

    #メタ フィールドの抽出と処理
  • フィールド長の制御
  • 互換性のあるロジック処理
  • メタ フィールドを抽出する方法。これにはコンテキストの作成と使用が含まれます。ここでは、ドメインの作成と使用について簡単に説明します。
//--- middlewares/http-context.js
const domain = require('domain');
const shortid = require('shortid');

module.exports = (req, res, next) => {
    const d = domain.create();
    d.id =  shortid.generate(); // reqId;
    d.req = req;
    
    //...

    res.on('finish', () => process.nextTick(() => {
        d.id = null;
        d.req = null;
        d.exit();
    });

    d.run(() => next());
}

//--- app.js
app.use(require('./middlewares/http-context.js'));

//--- formatter.js
if (process.domain) {
    reqId = process.domain.id;
}
ログイン後にコピー

このようにして、リクエスト内のすべてのイベントに

reqId

を出力することができ、イベントを相関させるという目的を達成できます。 2. ログの収集

イベントを出力する方法がわかったので、次のステップでは 2 つの質問について検討します。イベントをどこに出力すればよいでしょうか?

    イベントについてはどのような詳細を出力する必要がありますか?
  1. 言い換えると、リクエスト リンク全体において、どのノードが懸念されるのでしょうか? 問題が発生した場合、どのノードの情報を使用して問題を迅速に特定できるでしょうか?また、どのノードデータを統計解析に使用できるのでしょうか?
  2. 以下のフローチャートに示すように、一般的なリクエスト リンク (ユーザー リクエスト、サービス側の受信リクエスト、下流サーバー/データベースへのサービス リクエスト (*複数回)、データ集約レンダリング、サービス レスポンス) と組み合わせる

次に、次のようにイベントを定義できます:

ユーザー要求

NodeフレームワークをELKに接続するプロセスの概要

client-init: フレームが受信したときに印刷します。リクエスト (解析されていない)。リクエスト アドレス、リクエスト ヘッダー、HTTP のバージョンとメソッド、ユーザー IP およびブラウザを含みます。

client-request: リクエストの受信 (解析) 時にフレームに出力されます。リクエスト アドレス、リクエスト ヘッダー、Cookie、リクエスト パッケージ本体

client-response: フレームによって返されたリクエストを出力します。次のものが含まれます: リクエスト アドレス、応答コード、応答ヘッダー、応答パッケージ本体

下游依赖

http-start: 打印于请求下游起始:请求地址,请求包体,模块别名(方便基于名字聚合而且域名)

http-success: 打印于请求返回 200:请求地址,请求包体,响应包体(code & msg & data),耗时

http-error:  打印于请求返回非 200,亦即连接服务器失败:请求地址,请求包体,响应包体(code & message & stack),耗时。

http-timeout:  打印于请求连接超时:请求地址,请求包体,响应包体(code & msg & stack),耗时。

字段这么多,该怎么选择? 一言以蔽之,事件输出的字段原则就是:输出你关注的,方便检索的,方便后期聚合的字段。

一些建议

  1. 请求下游的请求体和返回体有固定格式, e.g. 输入:{ action: 'getUserInfo', payload: {} } 输出: { code: 0, msg: '', data: {}} 我们可以在事件输出 action,code 等,以便后期通过 action 检索某模块具体某个接口的各项指标和聚合。

一些原则

  1. 保证输出字段类型一致 由于所有事件都存储在同一个 ES 索引, 因此,相同字段不管是相同事件还是不同事件,都应该保持一致,例如:code不应该既是数字,又是字符串,这样可能会产生字段冲突,导致某些记录(document)无法被冲突字段检索到。

  2. ES 存储类型为 keyword, 不应该超过 ES mapping 设定的 ignore_above 中指定的字节数(默认4096个字节)。否则同样可能会产生无法被检索的情况

三、ES 索引模版定义

这里引入 ES 的两个概念,映射(Mapping)与模版(Template)。

首先,ES 基本的存储类型大概枚举下,有以下几种

  • String: keyword & text

  • Numeric: long, integer, double

  • Date: date

  • Boolean: boolean

一般的,我们不需要显示指定每个事件字段的在ES对应的存储类型,ES 会自动根据字段第一次出现的document中的值来决定这个字段在这个索引中的存储类型。但有时候,我们需要显示指定某些字段的存储类型,这个时候我们需要定义这个索引的 Mapping, 来告诉 ES 这此字段如何存储以及如何索引。

e.g.

还记得事件元字段中有一个字段为 timestamp ?实际上,我们输出的时候,timestamp 的值是一个数字,它表示跟距离 1970/01/01 00:00:00 的毫秒数,而我们期望它在ES的存储类型为 date 类型方便后期的检索和可视化, 那么我们创建索引的时候,指定我们的Mapping。

PUT my_logs
{
  "mappings": {
    "_doc": { 
      "properties": { 
        "title":    {
            "type": "date",
            "format": "epoch_millis"
         }, 
      }
    }
  }
}
ログイン後にコピー

但一般的,我们可能会按日期自动生成我们的日志索引,假定我们的索引名称格式为 my_logs_yyyyMMdd (e.g. my_logs_20181030)。那么我们需要定义一个模板(Template),这个模板会在(匹配的)索引创建时自动应用预设好的 Mapping。

PUT _template/my_logs_template
{
  "index_patterns": "my_logs*",
  "mappings": {
    "_doc": { 
      "properties": { 
        "title":    {
            "type": "date",
            "format": "epoch_millis"
         }, 
      }
    }
  }
}
ログイン後にコピー
提示:将所有日期产生的日志都存在一张索引中,不仅带来不必要的性能开销,也不利于定期删除比较久远的日志。

小结

至此,日志改造及接入的准备工作都已经完成了,我们只须在机器上安装 FileBeat -- 一个轻量级的文件日志Agent, 它负责将日志文件中的日志传输到 ELK。接下来,我们便可使用 Kibana 快速的检索我们的日志。

以上がNodeフレームワークをELKに接続するプロセスの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ Mar 16, 2024 pm 12:09 PM

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

フロントエンド開発に Go 言語を使用するにはどうすればよいですか? フロントエンド開発に Go 言語を使用するにはどうすればよいですか? Jun 10, 2023 pm 05:00 PM

インターネット技術の発展に伴い、フロントエンド開発の重要性がますます高まっています。特にモバイル デバイスの人気により、効率的で安定しており、安全で保守が容易なフロントエンド開発テクノロジーが必要です。 Go 言語は、急速に発展しているプログラミング言語として、ますます多くの開発者によって使用されています。では、フロントエンド開発に Go 言語を使用することは可能でしょうか?次に、この記事ではフロントエンド開発にGo言語を使用する方法を詳しく説明します。まずはフロントエンド開発にGo言語が使われる理由を見てみましょう。多くの人は Go 言語は

フロントエンドの面接官からよく聞かれる質問 フロントエンドの面接官からよく聞かれる質問 Mar 19, 2024 pm 02:24 PM

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Jan 19, 2024 am 08:37 AM

Django は、迅速な開発とクリーンなメソッドを重視した Python で書かれた Web アプリケーション フレームワークです。 Django は Web フレームワークですが、Django がフロントエンドなのかバックエンドなのかという質問に答えるには、フロントエンドとバックエンドの概念を深く理解する必要があります。フロントエンドはユーザーが直接対話するインターフェイスを指し、バックエンドはサーバー側プログラムを指し、HTTP プロトコルを通じてデータと対話します。フロントエンドとバックエンドが分離されている場合、フロントエンドとバックエンドのプログラムをそれぞれ独立して開発して、ビジネス ロジックとインタラクティブ効果、およびデータ交換を実装できます。

golang はフロントエンドとして使用できますか? golang はフロントエンドとして使用できますか? Jun 06, 2023 am 09:19 AM

Golang はフロントエンドとして使用できます。Golang は、フロントエンド アプリケーションなど、さまざまなタイプのアプリケーションの開発に使用できる非常に多用途なプログラミング言語です。Golang を使用してフロントエンドを作成することで、 JavaScript などの言語によって引き起こされる一連の問題、たとえば、型安全性の低さ、パフォーマンスの低下、コードの保守の困難などの問題です。

C# 開発経験の共有: フロントエンドとバックエンドの共同開発スキル C# 開発経験の共有: フロントエンドとバックエンドの共同開発スキル Nov 23, 2023 am 10:13 AM

C# 開発者としての私たちの開発作業には、通常、フロントエンドとバックエンドの開発が含まれますが、テクノロジーが発展し、プロジェクトが複雑になるにつれて、フロントエンドとバックエンドの共同開発はますます重要かつ複雑になってきています。この記事では、C# 開発者が開発作業をより効率的に完了できるようにする、フロントエンドとバックエンドの共同開発テクニックをいくつか紹介します。インターフェイスの仕様を決定した後、フロントエンドとバックエンドの共同開発は API インターフェイスの相互作用から切り離せません。フロントエンドとバックエンドの共同開発をスムーズに進めるためには、適切なインターフェース仕様を定義することが最も重要です。インターフェイスの仕様にはインターフェイスの名前が含まれます

Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Mar 28, 2024 pm 01:06 PM

Go 言語は、高速で効率的なプログラミング言語として、バックエンド開発の分野で広く普及しています。ただし、Go 言語をフロントエンド開発と結びつける人はほとんどいません。実際、フロントエンド開発に Go 言語を使用すると、効率が向上するだけでなく、開発者に新たな視野をもたらすことができます。この記事では、フロントエンド開発に Go 言語を使用する可能性を探り、読者がこの分野をよりよく理解できるように具体的なコード例を示します。従来のフロントエンド開発では、ユーザー インターフェイスの構築に JavaScript、HTML、CSS がよく使用されます。

フロントエンドにインスタントメッセージングを実装する方法 フロントエンドにインスタントメッセージングを実装する方法 Oct 09, 2023 pm 02:47 PM

インスタント メッセージングを実装する方法には、WebSocket、ロング ポーリング、サーバー送信イベント、WebRTC などが含まれます。詳細な紹介: 1. クライアントとサーバーの間に永続的な接続を確立してリアルタイムの双方向通信を実現できる WebSocket フロントエンドは WebSocket API を使用して WebSocket 接続を作成し、送受信によるインスタント メッセージングを実現できます。 2. Long Polling(リアルタイム通信を模擬する技術)など

See all articles