ELKを使用したDXP 7.0ダッシュボードの例の作成

Liferay DXP 7.0は、検索関連機能に関してElasticsearchと密接な関係があります。 たまたま、ElasticsearchはELKスタックの一部です。 したがって、「ELKスタック全体を使用した場合、何が可能ですか?」

答えは多くの機会があるということです。ここに示す1つのオプションは、DXP 7.0用の「ダッシュボード」の構築、複雑な情報をグラフィック形式で表示するためのさまざまなチャートおよびグラフです。 これらは、情報をすばやく消費可能な形式に合成できるため、人気があります。

この記事では、ELKスタックを使用していくつかのダッシュボードグラフを作成します(ELKスタックがインストールされていることが前提です)。

ここで説明する詳細は、以下を使用して開発およびテストされました。

  • Liferay DXPマスターブランチ
  • Elasticsearch 2.3.3
  • Kibana 4.5.1
  • Logstash 2.3.2
  • Apache HTTPd 2.4

Liferay DXP

構築中のダッシュボードは、Liferay DXPに組み込まれたLiferay監査機能を活用します。 そのため、機能が不足しているため、これらはLiferay Portal 7.0 CEでは機能しません。 Liferay Portal 7.0 CEの監査レイヤーを構築することは可能ですが、これはこのドキュメントの範囲外です。

Elasticsearch

前述のとおり、DXP 7.0は検索関連機能にElasticsearchを使用します。 実稼働環境では、ESはアプリケーションコンテナーの外部に個別にインストールされ、おそらくパブリックビューから離れたバックエンドシステムにインストールされます。

きばな

Kibanaは、Elasticsearchに基づく視覚化ツールです。 Kibanaでは、ESに対して検索クエリを使用し、結果に基づいてチャートやグラフとして視覚化を構築できます。 このドキュメントではいくつかの単純な視覚化を紹介しますが、Kibanaは複雑なクエリを使用して魅力的な視覚化を構築することをサポートしています。 ただし、複雑なクエリと視覚化は、このドキュメントの範囲外です。

Kibanaは、ESサーバーまたは専用サーバーのバックエンドにもインストールする必要があります。 クライアントのブラウザーはリソースのためにKibanaサーバーにアクセスする必要がありますが、これはプロキシーを介して行う必要があります。 このドキュメントでは、Apache httpdを使用してリクエストをKibanaサーバーにプロキシします。

Logstash

logstashの名前は誤解を招くものであり、ログファイル用のツールであるかのような印象を与えます。 実際、logstashは、構造化されていないデータソースからデータを抽出して別の場所に送信するのに適した抽出、変換、および読み込み(ETL)ツールです。 ログファイルから情報を抽出してドキュメントとしてElasticsearchにロードするツールとして始まりましたが、さまざまなプラグインが開発され、データベース、ファイル、Twitterフィードなどからlogstashを機能させることができます。 フィルターおよび変換メカニズムは、抽出されたデータをElasticSearchドキュメントとしてロードするのに適したドキュメントに変換するのに役立ちます。

ビート

logstashに関連するツールは、beatsフレームワークです。 Logstashはリソース集中型のツールになる可能性があり、すべての本番システムにインストールするには重すぎる場合があります。 filebeatsツールを含むビートフレームワークがソリューションです。 ビートフレームワークは、ネットワーク経由で集中型のログスタッシュインスタンスにデータを送信する前に、ローカルで読み取りとフィルタリングを行う軽量エージェントを提供します。これにより、データが存在するシステムにBeatsエージェントをインストールできますが、Logstash処理の大部分が別の(専用)サーバーにオフロードされます。

このドキュメントではビートツールを使用していませんが、実稼働環境では、バックエンド(ESサーバーまたは専用サーバーのいずれか)にlogstashをインストールし、他のシステムでfilebeatsエージェントを使用してlogstashへのデータ送信を処理することをお勧めします。

Apache HTTPd

このドキュメントでは、Apache HTTPdを使用して、Liferay TomcatインスタンスとバックエンドKibanaサーバーにリクエストをプロキシします。

解決

ここで紹介する実装は、次の要件を満たすように設計されています。

  1. ELKスタックを使用して、ログインアクティビティを表示するダッシュボードを作成します。
    1. 今週の1日あたりのログイン。
    2. 当日の1時間あたりのログイン。
  2. ELKスタックを使用して、1日あたりのフォーム送信を表示するダッシュボードを作成します。
  3. ELKスタックを使用して、ページの人気を示すダッシュボードを作成します。

これらのダッシュボードの作成に必要なデータはアクティビティベースであるため、監査フレームワークを活用してデータ収集を処理します。 アーキテクチャ図は次のようになります。

ELK_01.png

監査フレームワークを使用すると、イベントの生成に使用されるロジックが、監査ファイルを維持するコードから分離されます。 また、監査フレームワークを活用することで、監査メッセージを生成するためのすぐに使用可能な例が、DXPソースで直接利用できます。

実装の詳細

要件を満たすようにダッシュボードを構築するには、以下を生成する必要があります。

  1. ダッシュボードに必要なデータを提供する適切な監査メッセージを生成するカスタム監査コード。 ログインダッシュボードは、OOTBユーザーモデルリスナー監査イベントジェネレーターを使用して満たすことができます。
  2. 監査メッセージを受信して監査ファイルに書き込むためのAuditMessageProcessor。
  3. 監査ファイルを処理してドキュメントをESにロードするためのlogstash構成ファイル。
  4. 各ダッシュボードのKibana視覚化。
  5. メッセージをLiferay / TomcatおよびKibanaサーバーにプロキシするApacheの設定。

監査コード

ダッシュボードの場合、次のアクションに対して監査情報をトリガーする必要があります。

  1. ユーザーログイン-幸い、これはすでにcom.liferay.portal.security.audit.event.generators.events.LoginPostActionのOOTB監査イベント生成コードによって処理されています。 ログインが発生すると、このポストログインハンドラーが監査メッセージを生成し、これらの監査メッセージをダッシュボードグラフに使用できます。
  2. フォーム送信-LR7でフォームが送信されると、フォームフィールドがシリアル化され、DDMContentレコードとして保存されます。 したがって、フォームがいつ保存、更新、または削除されているかを識別するには、DDMContent ModelListenerが必要になります。 テスト中に、DDMContentsがフォームデータの逆シリアル化に必要な対応するDDMStorageLink要素の前に保存されたことが判明したため、DDMStorageLinksのModelListenerが追加され、最初のフォーム送信が監査されました。
  3. ページビューはさまざまな方法で監査できますが、この実装では、ServicePreActionを使用して、レンダリングされるページを識別します。 LayoutActionクラスから変更されたコードを使用して、レンダリングされるページが識別および監査されます。

添付プロジェクトでは、関連するクラスは次のとおりです。

  • com.liferay.portal.security.audit.event.generators.DDMContentModelListener
  • com.liferay.portal.security.audit.event.generators.DDMStorageLinkModelListener
  • com.liferay.portal.security.audit.event.generators.AuditServicePreAction

AuditMessageインスタンスの作成に使用される com.liferay.portal.security.audit.generators.util パッケージには、いくつかのユーティリティクラスもあります。

AuditMessageProcessor

DXP監査処理メカニズムでは、AuditMessageインスタンスがLiferayMessageBusに配置されます。 デフォルトのメッセージバスリスナー com.liferay.portal.security.audit.router.internal.DefaultAuditRouter、各監査メッセージを受信し、登録された各AuditMessageProcessorインスタンスに転送します。

ELKスタックのlogstashコンポーネントを活用するために、ここに示す実装では、監査メッセージをJSONファイルに書き込みます。 各監査メッセージはJSONにシリアル化され、ローテーションファイルに書き込まれます。

この実装クラスは com.liferay.portal.security.audit.json.log.JsonLoggingAuditMessageProcessor
あり、対応するクラスは
com.liferay.portal.security.audit.json.log.JsonLoggingAuditMessageProcessorConfigurationです。

イベントの展開と生成

ビジュアライゼーションを構築するには、ESインデックスで利用可能なドキュメントが必要です。 バンドルをビルドしてDXP環境にデプロイし、イベントの生成を開始します。 数回ログインおよびログアウトし、ポータル内を移動し、フォームを定義して値の送信を開始します。

次のステップに進むにつれ、環境に戻って新しいイベントをいくつか生成します。これにより、すべてのイベントをレポートできる時間が広がります。

Logstash構成ファイル

logstash構成ファイルは、特定のプロセスの入力、フィルター、および出力を定義します。

入力構成

この実装では、入力は監査jsonファイルです。

input {
  file {
    # For the demo just using a fixed path to file.
    path => "/Users/dnebinger/liferay/clients/liferay/elk/bundles/logs/json/audit.json"
    # Since the file may roll over, we should start at the beginning
    start_position => beginning
    # Don't ignore older records
    ignore_older => 0
    # our file is a json file so use it for the codec.
    codec => "json"
  }
}

フィルター構成

フィルターは、読み取りレコードでいくつかの変換を行います。

filter {
  # Apply some changes to the incoming records
  mutate {
    add_field => {
      # Copy the eventType field to the action field.
      "action" => "%{eventType}"
    }

    # Strip out the values that we don't care to include in the index.
    remove_field => [ "sessionID","path","host" ]
  }

  # If path is provided, clone to the not analyzed and not indexed fields.
  if "" in [additionalInfo][path] {
    mutate {
      add_field => { "[additionalInfo][pathUrl]" => "%{[additionalInfo][path]}" }
      add_field => { "[additionalInfo][pathString]" => "%{[additionalInfo][path]}" }
    }
  }

  # The audit timestamp is mashed together, we need to extract it out.
  # Date follows the following format: 20160608135725305
  date {
    match => [
      "timestamp",
      "yyyyMMddHHmmssSSS"
    ]
  }
}

出力構成

出力の場合、レコードはElasticsearchにアップロードされます。

output {
  # Target elasticsearch
  elasticsearch {
    # Point at the backend server.  If a cluster we'd use multiple hosts.
    hosts => ["192.168.1.2"]
    # Specify the index where our records should go
    index => "audit-%{+YYYY.MM.dd}"
  }

  # For debugging purposes, also write the records to the console.
  stdout { codec => rubydebug }
}

Logstashの実行

インデックスの準備

インデックスをロードする前に、一部のフィールドを手動で定義して、分析とインデックス作成を無効にします。 これらの種類の変更は、すべてのデータのインデックスを再作成する必要がないように、インデックスが最初にロードされる前に行う必要があります。

コマンドラインで次のコマンドを発行して、フィールドを事前定義します。

curl -XPUT 192.168.1.2:9200/audit/logs/_mapping -d '
{
  "logs": {
    "properties": {
      "additionalInfo": {
        "properties": {
          "pathUrl": { "type":"string", "index":"not_analyzed" },
          "pathString": { "type":"string", "index":"no" }
        }
      }
    }
  }
}
'

監査ログがlogstashによって処理されると、残りの列はデフォルト設定で追加されます。

Logstashを実行する

構成ファイルの準備ができたら、logstashを開始できます。 logstashディレクトリから、次のコマンドを実行します。

 bin/logstash agent -f audit.conf

一部の監査イベントは既に作成されているため、logstashが開始すると、ファイルの処理が開始され、コンソールに次のようなメッセージが表示されます。

{
     "companyId" => "20116",
       "classPK" => "20164",
    "clientHost" => "::1",
      "clientIP" => "::1",
    "serverName" => "localhost",
     "className" => "com.liferay.portal.kernel.model.User",
     "eventType" => "LOGIN",
    "serverPort" => 80,
      "userName" => "Test Test",
        "userId" => "20164",
     "timestamp" => "20160610231917907",
      "@version" => "1",
    "@timestamp" => "2016-06-11T03:19:17.907Z",
        "action" => "LOGIN"
}

これらのメッセージが流れると、レコードはファイルから消費され、変換され、ドキュメントとしてElasticsearchにロードされます。

キバナの視覚化

Kibanaビジュアライゼーションは、実際にはKibana UI内で作成されます。 最初のステップは、インデックスパターンを定義することです。 インデックスパターンは、視覚化を構築するための基盤です。

インデックスパターンの作成

以下の図に従ってインデックスパターンを作成します。

ELK_02.png

検索クエリを定義する

次のステップは、検索クエリを作成することです。 1つ目は、当日の時間単位のログインです。 Discoverタブをクリックして開始します。

右上の時間枠を変更することから始めます。 リンクをクリックして、時間枠を今日に変更します。これは、表示するレコードを制限する時間枠を定義します。

次に、Kibanaバナーの下にあるドロップダウンのインデックスを、新しく定義した監査インデックスパターンに変更します。 ページは次のようになります。

ELK_03.png

Available Fieldsセクションから、action、userName、およびuserIdフィールドを追加します。 これにより、レコードのタイムスタンプ、アクション(NAVIGATEやLOGINなど)、およびイベントのユーザー詳細が表示されます。 1時間あたりのログインのクエリを作成しているので、検索バーを次のように変更します。

 action:LOGIN 

Enterキーを押します。

ELK_04.png

[保存]ボタンをクリックして、クエリをログインとして保存します。 この同じ検索が、時間ごとのログインおよび日ごとのログインの視覚化にも使用されます。

次はページヒット検索です。 新しい検索を開始するには、[New Searchリンクをクリックします。 クエリを次のように設定します。

 action:NAVIGATION 

アクション、userName、およびadditionalInfo.pageUrlを選択したフィールドに追加します。 この検索をページヒットとして保存します。

フォーム送信検索の場合、[New Searchリンクをクリックして、新しい検索を開始します。 クエリを次のように設定します。

 action:ADD AND className:com.liferay.dynamic.data.mapping.model.DDMContent 

選択したフィールドにactionとclassNameを追加し、この検索をForms Submittedとして保存します。

ビジュアライゼーションを作成する

ビューを切り替えるには、[Visualizeリンクをクリックします。

縦棒グラフをクリックして、時間ごとのログインの視覚化を作成します。 保存された検索オプションからを選択し、ログイン検索を選択します。

右上隅で、Todayが選択されているオプションであることを確認します。 Y-Axisセクションで、カスタムラベルをLoginsます。

[バケットセクションで、[X軸]オプションを選択します。 集計に日付ヒストグラムを選択し、間隔を時間ごとに設定し、カスタムラベルを時間ます。

緑色の>ボタンをクリックして、視覚化を更新します。 うまくいけば、次のようなものが表示されます。

ELK_05.png

このビジュアライゼーションを時間ごとのログインとして保存します。

次の視覚化のために、[New Visualization]ボタンをクリックします保存済み検索ログイン検索から。 X-Axisラベルには、Day使用します。 右上隅で、[今週]オプションに変更します。 このビジュアライゼーションをログインとして保存します。

次の視覚化のために、上記の手順を繰り返しますが、Forms Submitted検索を使用します。 Y軸場合はフォームを使用し、X軸ラベルの場合は使用します。 このビジュアライゼーションを日目までに送信されたフォームとして保存します。

最後の視覚化については、[New Visualization]ボタンをクリックしますが、Pie Chart使用します。 検索にはページヒットを使用します。 バケットタイプ分割スライスを選択し、を集計に使用します。 使用additionalInfo.pathUrl、フィールドに10サイズとのためにページカスタムラベルのため。

円グラフは次のようになります。

ELK_06.png

選択-視覚化またはダッシュボード

現在、Liferay内で個別に使用できる4つの異なる視覚化があります。 もう1つの選択肢は、Kibanaダッシュボードを作成することです。

Kibanaダッシュボードは、Kibana側で定義され、フリーフォームのLiferayページとして機能します。 ダッシュボードでは、視覚化を追加、サイズ変更、移動できます。

ダッシュボードオプションはページの広い領域を占有する必要がありますが、どちらもLiferayページに埋め込むことができます。 そのため、個々の視覚化の方がうまく機能する場合があります。

Liferayにビジュアライゼーションを配置する

Kibanaサーバーはバックエンドサーバー上にあるため、通常はブラウザーでアドレス指定できませんが、Kibanaは視覚化を機能させるためにブラウザーにいくつかのリソース(jsおよびcss)を公開する必要があります。

IFrameポートレットは、Liferayで視覚化をページに配置するために使用されますが、Liferayはリソースをプロキシしません。

Kibanaサーバーをブラウザーに公開するために、フロントWebサーバーを使用して、ほとんどの要求をLiferayにルーティングし、一部の要求をKibanaサーバーにルーティングします。

ここで使用する設定では、Apache HTTPdを使用してAJP経由でLiferay / Tomcatにリクエストを送信し、/ kibana /および/ bundles /リクエストをKibanaサーバーにルーティングしました。 Kibanaは、server.basePath設定とhttpd用に定義されたプロキシステートメントで構成する必要がありました。 これらのファイルは、src / main / resources / kibana / kibana.ymlおよびsrc / main / resources / apache / mod_jk.confとしてプロジェクトで使用できます。

視覚化URLの取得

IFrameポートレットを設定するには、URLが必要です。 これらのURLはKibanaからのものです(server.basePathが設定され、Kibanaが再起動された後)。

視覚化とダッシュボードのどちらを使用する場合でも、プロセスは同じです。 Liferayに配置するビジュアライゼーションまたはダッシュボードを開き、[Share ...]ボタンをクリックします。 2つの行が利用可能です。上部は埋め込み(IFrame)リンクで、2番目は共有リンクです。 両方のリンクは同じですが、共有リンクには周囲のIFrameタグがありません。

これらの各リンクの右側には、2つのボタンがあります。 つ目は完全な視覚化のコード文字列を返す[ショートURL を生成]ボタンで、2つ目は[クリップボードにコピーリンクです。 短いURLを使用する方が管理が簡単ですが、長い形式にもいくつかの価値があります。 使用するフォームを選択して、値をコピーします。 Liferay側で、IFrameポートレットをページに配置し、ソースURLとしてURLを使用するように構成します。 すべてが正常に機能している場合、視覚化はページ上にあるはずです。

ELK_07.png

したがって、長い形式のURLにも価値があります。 URLには、視覚化とダッシュボードのレンダリングに使用されるすべての詳細が実際に含まれています。 ある程度の時間とある程度の理解があれば、Kibanaに行って作業を行わなくても、Kibana視覚化を構築または変更することができます。 Kibana UIを利用して視覚化を定義する方が確かに簡単ですが、必須ではありません。

追加情報

ELKスタックを使用していくつかのLiferay機能を活用することで、ダッシュボードの作成は本当に簡単になります。 スタック内のすべてのツールの柔軟性は、これまで利用できなかったあらゆる種類の可能性への扉を本当に開きます。

グーグルでスピンして、Kibana Dashboard Examplesを検索すると、本当にすばらしいものがいくつかあります。 そして今、それらはLiferayページ内に埋め込むことができ、Liferayデータを入力することもできます。

このドキュメント、これらの例、およびこのサンプルコードは、可能性のほんの一部にすぎませんが、これらは実際の例です。

現在進行中の1つのプロジェクトには、一定期間に送信されたさまざまな種類のフォームの数のダッシュボードを表示するための要件があります。 この例のコードを使用すると、すべてのフォーム送信により監査レコードが生成されるため、すべてのフォームデータは消費可能な形式でElasticsearchに格納されます。 フォームとさまざまなデータタイプに基づく視覚化により、要件が要求する個々のダッシュボードグラフが作成されます。 クライアントはこれらの洗練されたレスポンシブチャートとグラフをすべて取得しますが、実装チームは監査イベントジェネレーターを追加し、Elasticsearch検索に基づいて視覚化を定義するだけです。

この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています