Corredor

ウェブ、プログラミングの勉強メモ。

Oracle Management Cloud の Log Analytics とやらを使ってみる

Oracle Management Cloud (OMC) というサービスがある。サーバのログを収集・分析して、問題が発生した場合はアラートを上げたりできる。

今回はこの OMC の中の Log Analytics 機能を中心に、使い始めてみる。

OMC の特徴

OMC の特徴は以下のとおり。

  • Web サーバにクラウド・エージェントというツールをインストールしておく
    • このツールは、OMC 管理コンソール (Web ページ) で設定された内容を定期的に受信し、その設定内容に応じてログ情報を送信する
    • つまり、Web サーバ側はクラウド・エージェントを一度インストールしておけばよく、ログ収集の仕方を変えたりする時に再デプロイが不要なのである
  • デフォルトで、OS・ミドルウェア・ロガーツールが出力するログの書式を解析する「ログ・パーサ」が充実している
    • OS が出力する動作ログ
    • Apache や Tomcat サーバがデフォルトで出力するログ
    • 「Log4js」のようなロギングライブラリで出力するログ
    • こうした各種ツールが出力するログのデフォルトの書式を解析するパーサ (= 正規表現) が多数登録されており、ログを表形式にまとめたりする時にうまいことやってくれる
    • 勿論自分で正規表現をガリガリ書いてパーサを作ったりもできるし、自動的にうまい感じにパーサを構築してくれたりもする
  • パースしたログをグラフィカルに表示してくれる「ログ・エクスプローラ」機能がある
    • なんか日本語が文字化けすることがあったりして、ちょっとイマイチなところもあるけど、色々見やすい
  • 特定のログを検知した時に、アラートメールを送信したりできる

お膳立てされているところが多く、サーバ側にクラウド・エージェントを仕込んでおきさえすれば、後から色々と調整したりできる。

前提とするサーバ環境

  • 実装言語は Node.js。Express サーバを Docker コンテナに包んで稼動させているものとする
  • ログを Log4js でファイル出力している
  • 稼動する Docker コンテナは CentOS をベースに使用している

今回はこのようなサーバのログ収集ができるようにしてみる。

OMC インスタンスの作成

Oracle Cloud My Services のメニュー → サービス → Management Cloud と移動し、OMC インスタンスを作成する。

インスタンスを作成したら、右側のメニューアイコンより「OMC URL」を押下すると、OMC 管理コンソールのトップページに遷移する。

Cloud Agent Installer をダウンロードする

前述の「クラウド・エージェント」ソフトウェアを Docker コンテナに同梱するため、まずはそのインストーラファイルをダウンロードする。

OMC 管理コンソールの左メニュー → 「管理」 → 「エージェント」と進み、画面右上のハンバーガーメニュー風アイコン → 「Download Agents」と進む。

次の画面で、

  • エージェント・タイプ : クラウド・エージェント

を選択し、Docker コンテナの OS に応じたエージェントの Zip ファイルをダウンロードする。今回は Cloud Agent - Linux (64-bit) を使用する。現時点では v1.38 というバージョンで、cloudagent_linux.x64_1.38.0.zip というファイルがダウンロードできた。

また、この画面で、TENANCY_NAMEOMC_URL パラメータ値をメモしておく。さらに、ページ中の「登録キー」リンクを押下して、次画面の「キー値」欄に表示されている値をメモしておく。この値は、後述する AGENT_REGISTRATION_KEY 項目の設定値となる。

ログ・ソース「Node.js Log4js Logs」の設定を変更する

今回は Log4js が追記するログファイルを監視したいのだが、Log4js が出力するログファイルをよしなに解析してくれるログソースが用意されている。

ログソースとは、「ログパーサ」を、どんなマシンの、どんなファイルに適用するか、といった設定を担う概念。こんな文言が含まれるログには「要注意」ラベルを付ける、とかいう設定もできたりする。

OMC 管理コンソール左メニュー → 管理 → ログ管理 → ログ・ソース と進み、「ログ・ソースの検索」検索窓より絞り込んで Node.js Log4js Logs というログソースを見つける。

このログソースの詳細画面に飛んだら、以下のように設定しておく。

  • 自動連動 : チェックする → コレにより、ウェブサーバを再デプロイしたりした時に関連付け作業をしなくて済むようになる
  • 「含まれているパターン」タブ : ウェブサーバ内の、監視したいログファイルのパスを指定する
    • 例えばウェブサーバ内の /my-app/logs/my-app.log というパスにログファイルが吐かれる場合は、「ファイル名パターン : /my-app/logs/*.log」みたいに指定できる
    • 最初から設定されている {log_directory}/{log_filename_pattern} というパターン指定だけでも設定できる。この変数に与える値をどう設定するかは後述
  • アラート設定をしたい場合は、「ラベル」タブにて任意の条件を追加し、好きなラベルを選択するか新規生成するかしておく
    • ラベルに応じてアラート通知をメールで送信するには、「管理」→「アラート・ルール」というメニューから設定する。「エンティティ・タイプ : Node.js」「ラベル : 作成したラベル名」「通知 … 電子メール : 電子メール・チャネル」と選択肢たらメール・チャネルを作成し、通知対象のメールアドレスを設定する

クラウドエージェント・インストーラを同梱した Docker イメージを作る

管理画面側での初期設定は以上。以降、ログを実際にどうパースするか、どんなログを抽出・集計するか、といった設定は、実際に「クラウド・エージェント」にログを送信させるよう設定してから変更しても問題ない。

続いては、ログを送信させる Web サーバ側の設定。先程ダウンロードしたクラウドエージェントの Zip ファイルと、いくつかの設定ファイルを用意して、サーバ起動時に初期設定してやる必要がある。今回は Web サーバを Docker コンテナとして稼動させる例として記述する。

まずはプロジェクトディレクトリ直下に次のような構成でファイルを格納する。

  • ./cloud-agent-installer/ (ディレクトリ名は任意)
    • cloudagent_linux.x64_1.38.0.zip … 先程ダウンロードしたクラウドエージェントの Zip ファイル
    • agent.rsp … エージェントの設定ファイル
    • linux-entity-agent.json … デフォルトの Linux ホストの設定を更新するためのファイル
    • nodejs-entity-agent.json … Node.js サーバとしての「エンティティ・エージェント」を追加するためのファイル

Zip ファイルは先程のモノとして、それ以外のファイルの内容は以下のとおり。

  • agent.rsp … エージェントの設定ファイル
    • このファイルは、Zip ファイル内に元のファイルが格納されている。元ファイルをコピーしたら、以下の4項目についてダミーの値を記述しておく。このダミーの値を後で置換する。
###################################### Registration Parameters #####################################

# 最初は「TENANT_NAME=」という行になっていると思うので、「__TENANT_NAME__」とダミーの値を設定しておく
TENANT_NAME=__TENANT_NAME__

# 以下も同様…
AGENT_REGISTRATION_KEY=__AGENT_REGISTRATION_KEY__

AGENT_BASE_DIRECTORY=__AGENT_BASE_DIRECTORY__

##################################### Communication Parameters #####################################

# この4項目だけ
OMC_URL=__OMC_URL__
  • linux-entity-agent.json … デフォルトの Linux ホストの設定を更新するためのファイル
    • Linux OS のシステムログを拾うための「エンティティ・エージェント」がデフォルトで仕込まれているのだが、そのエージェントがログを送信する際、サーバ自身の名前がよく分からなくなるので、ホスト名を設定してやるために用意する。 name プロパティに __HOSTNAME__ というダミーの値を設定しておき、あとで $ hostname コマンドで拾える Docker コンテナのホスト名に置換してやる。
{
  "entities": [
    {
      "name": "__HOSTNAME__",
      "type": "omc_host_linux",
      "properties":{
        "capability": {
          "displayName": "capability",
          "value": "monitoring"
        }
      }
    }
  ]
}
  • nodejs-entity-agent.json … Node.js サーバとしての「エンティティ・エージェント」を追加するためのファイル
    • 「Node.js Log4js Logs」ログ・ソースを使うには、「Node.js」タイプの「エンティティ・エージェント」を設定する必要がある。その設定を追加するためのモノ。
    • properties.host_nameport_listfull_module_name プロパティは、OMC の APM (Application Performance Monitoring) という性能監視用の別機能を利用する際に指定する項目。Log Analytics においては使用しないので、値は適当で良いし、必要なら正しく設定する。
    • name プロパティ、はホスト名に置換するのでダミー値を設定しておく。
    • log_directorylog_filename_pattern プロパティは、前述のログソースの設定画面に出てきていたパターン指定に使われる。ココで、コンテナ内の収集させたいログファイルをパターン指定できるというワケ。勿論、ログソースの設定画面で後からファイルパターンを設定すれば、そのファイルを収集するよう自動的に設定変更が反映されるので、お好みで。
{
  "entities": [
    {
      "name": "__HOSTNAME__",
      "type": "omc_nodejs",
      "properties": {
        "host_name": {
          "displayName": "__HOSTNAME__",
          "value": "__HOSTNAME__"
        },
        "port_list": {
          "displayName": "8080",
          "value": "8080"
        },
        "full_module_name": {
          "displayName": "/my-app/index.js",
          "value": "/my-app/index.js"
        },
        "log_directory": {
          "displayName": "/my-app/logs",
          "value": "/my-app/logs"
        },
        "log_filename_pattern": {
          "displayName": "error-*.log",
          "value": "error-*.log"
        }
      }
    }
  ]
}

ファイルの準備はコレで OK。あとは Dockerfile と、Docker コンテナ起動時に実行するシェルスクリプトをちょっと書いてやる。

  • Dockerfile
# Oracle Cloud Agent を正常にインストールできる OS として CentOS 7 を選んだ
FROM centos:7

# 起動スクリプトをコピーする
COPY ./start.sh /
# Cloud Agent Installer をコピーする
COPY ./cloud-agent-installer/ /cloud-agent-installer/
# 必要に応じてアプリの資材もコピーする…

# Cloud Agent Installer のインストールに bc と unzip コマンドを使うのでインストールしておく
RUN set -x && \
    : 'Install bc and unzip command (for Cloud Agent Installer)' && \
    yum install -y bc unzip
# 必要に応じてアプリの実行環境も設定しておく…

# 必要に応じてコンテナが公開するポートを指定しておいたり…
EXPOSE 8080

# コンテナ起動時に /start.sh を実行する
CMD ["sh", "/start.sh"]

start.sh の内容は以下の要領で。

  • start.sh
#!/bin/bash

# ================================================================================
# 起動スクリプト : Cloud Agent のインストールと初期設定を行い Web サーバを起動する
# ================================================================================


# 実行コマンドを出力する
set -x


# 変数定義
# --------------------------------------------------------------------------------

# 設定情報を定義する : 別途環境変数で渡しても OK

# クラウド・エージェントのダウンロード画面で確認した TENANT_NAME
TENANT_NAME='xxxxxxxxxxxxxxxxx'

# 「登録キー値」画面で確認した値
AGENT_REGISTRATION_KEY='yyyyyyyyyyyyyyy'

# クラウド・エージェントのインストール先ディレクトリ : 適当に指定する・インストーラがあるディレクトリとは別の場所にディレクトリごと新規生成させないとエラーになる
AGENT_BASE_DIRECTORY='/cloud-agent/'

# クラウド・エージェントのダウンロード画面で確認した OMC_URL
OMC_URL='https://xxxxxxxxxxxxxxxxx.uscom-xxxx-1.oraclecloud.com/'

# 以下全般的な変数

# 設定ファイルが格納されているベースディレクトリ
base_path='/cloud-agent-installer'

# インストーラの解凍先ディレクトリ
installer_path="${base_path}/installer"

# インストールした資材の格納先ディレクトリ (AGENT_BASE_DIRECTORY 変数と同じ値だが末尾にスラッシュなしで使用するローカル変数)
dest_path='/cloud-agent'

# omcli コマンドのフルパス
omcli="${dest_path}/agent_inst/bin/omcli"


# インストーラの解凍とエージェント定義の準備
# --------------------------------------------------------------------------------

# ベースディレクトリ配下の ./installer/ ディレクトリ配下にインストーラを解凍する (ココで unzip コマンドが必要になる)
unzip -d "${installer_path}" "${base_path}/cloudagent_linux.x64_*.zip"

# agent.rsp の内容を環境変数で置換する
agent_rsp='agent.rsp'
base_agent_rsp="${base_path}/${agent_rsp}"

# 置換する文字列にスラッシュ `/` が含まれているため sed コマンドの区切り文字にアットマーク `@` を使用する
sed -i s@__TENANT_NAME__@"${TENANT_NAME}"@ "${base_agent_rsp}"
sed -i s@__AGENT_REGISTRATION_KEY__@"${AGENT_REGISTRATION_KEY}"@ "${base_agent_rsp}"
sed -i s@__AGENT_BASE_DIRECTORY__@"${AGENT_BASE_DIRECTORY}"@ "${base_agent_rsp}"
sed -i s@__OMC_URL__@"${OMC_URL}"@ "${base_agent_rsp}"

# agent.rsp を上書き移動する
cat "${base_agent_rsp}"
mv -f "${base_path}/${agent_rsp}" "${installer_path}/${agent_rsp}"


# エージェントのインストール
# --------------------------------------------------------------------------------

# インストール前に動作検証する (このスクリプト内で bc コマンドが使用される)
sh "${installer_path}/AgentInstall.sh" EXECUTE_PREREQ=true
# インストールを開始する : agent.rsp に定義したディレクトリに資材が置かれる
sh "${installer_path}/AgentInstall.sh"

# エージェントを起動する (インストール時にも起動するようだが念のため)
"${omcli}" start agent
# 事前のエンティティの状況を確認する
"${omcli}" status_entity agent


# Linux エージェントの設定更新
# --------------------------------------------------------------------------------

# Host Linux エージェントの設定ファイルにホスト名を設定する
linux_entity_agent="${base_path}/linux-entity-agent.json"
sed -i s/__HOSTNAME__/`hostname -f`/ "${linux_entity_agent}"

# Host Linux エージェントを更新する
cat "${linux_entity_agent}"
"${omcli}" update_entity agent "${linux_entity_agent}"


# Node.js エージェントの設定追加
# --------------------------------------------------------------------------------

# Node.js エージェントの設定ファイルにホスト名を設定する
nodejs_entity_agent="${base_path}/nodejs-entity-agent.json"
sed -i s/__HOSTNAME__/`hostname -f`/ "${nodejs_entity_agent}"

# Node.js エージェントを追加する
cat "${nodejs_entity_agent}"
"${omcli}" add_entity agent "${nodejs_entity_agent}"


# 設定後確認
# --------------------------------------------------------------------------------

# 操作後のエンティティの状況を確認する
"${omcli}" status_entity agent


# サーバ起動
# --------------------------------------------------------------------------------

# サーバを起動する (ココでは Node.js アプリのテイ)
cd /my-app/
npm start

こんな感じで設定完了。

実際に起動してみる

クラウド・エージェントはローカル端末で起動してもログを収集してくれるので、試してみたければ Docker コンテナをローカルで起動してみれば良い。

起動後、start.sh に記載した初期設定に3・4分かかるのが難点。実際に Web サーバが起動するまで最初に5分近くかかる。

サーバが起動したら、何か Log4js でログが追記されるような操作をしてみよう。OMC 管理画面の「ログ・エクスプローラ」を開き、ログが転送され、表示されるか確認してみる。実際に触ってみた感じだと、ログ・エクスプローラでログが見られるようになるのは、ログ出力されてから2・3分経ってから、という感じ。また、ログに日本語文字列が含まれると時たま文字化けする。UTF-8 なのに ISO-8859-1 と解釈した時の化け方をするので、なんかこう、「米国企業」って感じ。w

Docker コンテナが死んでも、管理画面上はエンティティが一覧に残り続けて鬱陶しいので、「管理」→「エンティティ構成」→「エンティティの削除」と進み、不要になったエンティティを定期的に消してあげると良いだろう。

以上

最初に一度設定してしまえば後は管理画面でいかようにも設定できるのは良いところだが、その「最初に設定する」ところが物凄く面倒臭い…。