こんにちは、アピリオ中西です。これまで10回に渡って連載してきました MuleSoft 入門ブログですが、ここまで読み進めてきた方は、MuleSoft を利用して簡単な API を実装して運用するための基礎知識を理解してもらえたのではないでしょうか。
今回の記事では、Mule API の本番運用で必要となる Anypoint Platform のランタイムログを定期的にアーカイブする機能を持つ、Mule アプリケーションの実装方法について紹介しようと思います。それなりの MuleSoft 実装の理解が必要となるため、かなり応用的な内容となっていますがご了承ください。
ランタイムログの保管制限
CloudHub にデプロイした Mule アプリケーションのランタイムログは、[Runtime Manager] - [Logs] から確認することができます。このランタイムログは、障害発生時のトラブルシューティングや、アクセス情報を監査ログとして出力して管理する際に利用します。
[ランタイムログの画面]
しかし、ランタイムログは 30 日間もしくは100 MB の保管制限が設けられているため、定期的にアーカイブする必要があります。ログファイルは手動でダウンロードすることができますが、アプリケーションが増えてくると煩雑になり、オペレーションミスも生じかねません。
そこで、指定した環境下にデプロイされている各 Mule アプリケーションのログの前日からの差分を取得し、オンラインストレージに格納する日次スケジューラー機能を持つ Mule アプリケーション開発を試みました。オンラインストレージは Box の無料の個人利用枠を採用しています。実際の運用時には有償版や S3 などを利用する想定です。
MuleSoft Platform APIの利用
本実装の技術の要は、MuleSoft の Platform API である「Access Management API」と「CloudHub API」です。いずれも Exchange の Developer Portal から詳細仕様を確認することができます。
少し本題からは逸れますが、Exchange は主に社内外のアセットを管理する機能の他にも、特定の API を公開ポータルでシェアする機能があります。これにより、Anypoint Platform のアカウントを保有していないユーザも API の I/F 定義を確認することができます。
[MuleSoft Developer Portal]
利用した API の詳細を以下に記載します。
本実装においては上記2種類を利用していますが、Developer Portal には汎用的なAPIが多数公開されています。Runtime Manager の各操作を API を介して行うことができるため、デプロイ等の CI ツール作成時にも利用できると思います。
ランタイムログ自動アーカイブの仕組み
[ランタイムログ自動アーカイブ機能の概要図]
Muleアプリケーションは Design Center で作成した API 定義の実装に該当します。Mule アプリケーションを CloudHub にデプロイすることで、一意なドメインURLが付与され、クライアントアプリケーションや他の API から呼び出せるようになります。
一方で、今回実装したMuleアプリケーションには API の呼び出しに対する処理ではなく、定期的に自動実行する処理を実装しています。MuleSoft入門(3)Anypoint Studio による API の実装(2/2)で、Mule アプリケーションの実装時には MuleSoft が様々なモジュールとコンポーネントを標準で提供しているとお話ししましたが、今回利用した定期実行の機能も、「Scheduler」という標準のコンポーネントを利用しています。
[Scheduler コンポーネント]
Scheduler コンポーネントは Core モジュールに含まれ、一定の時間間隔もしくは指定した時間で定期的にフローを実行する機能を提供します。本実装では上記画像のように、スケジューラによる定期実行で、別の Mule Configuration File (フローを定義する xml )の処理を呼び出しています。
本題の、自動アーカイブの処理の概要は次の通りです。
(1) Anypoint Platform のユーザ名/パスワード認証を用いてアクセストークンを取得 (2) 指定した環境下のMuleアプリケーションを一括取得 (3) Muleアプリケーションのデプロイ情報を取得 (4) 各インスタンス(Worker)のログファイルを取得 (5) 前回実行時のログとの差分のみを取得 (6) Box API を利用してログファイルをアップロードする (7) (3)~(6)の処理を、取得したMuleアプリケーション分繰り返し処理を行う
順を追って解説します。
(1) Anypoint Platform のユーザ名/パスワード認証を用いてアクセストークンを取得
[Access Management API の利用例]
まず、Access Management API の /login をコールし、アクセストークンを取得します。Request Payload には Anypoint 組織のユーザ名/パスワードを含める必要があります。私はプロパティとして切り出し、Mule::p 関数で読み込むように実装しました。詳しい I/F 定義は リンク先 をご参照ください。
payload.access_token as String
上記 DataWeave スクリプトを Set Variable コンポーネントに定義し、アクセストークンを変数で保持しておきます。
(参考)Request コネクタは Response Payload を任意の変数にセットする [target] 属性を定義することができます。そのため、Set Variable コンポーネントを利用しなくても実装をすることは可能です。しかし、今回のように複雑な実装の場合は変数の定義元がフローを一目見ただけでは分かりにくく、メンテナンス性を損なう恐れがあるため、あえて Set Variable コンポーネントで定義しています。
[Request コネクタにおける target 属性の設定箇所]
(2) 指定した環境下の Mule アプリケーションを一括取得
ランタイム情報の取得には CloudHub API を利用します。まず CloudHub API の /v2/applications をコールし、CloudHub にデプロイしている Mule アプリケーションの情報を一括で取得します。この時、指定するヘッダーは以下の2つです。
Authentication : (1)の手順で取得したアクセストークンを "Authorization" : 'Bearer ******' という形式で付与する
X-ANYPNT-ENV-ID : Sandbox/Production などの環境を示す一意なUUIDを指定。[Access Management] - [Environments] から取得できる
その他の I/F 定義の詳細はリンク先をご参照ください。
[CloudHub API のヘッダー情報の指定イメージ]
/v2/applications をコールすると、下記のような payload が返却されます。
[ { "domain":"example-app", "fullDomain":"example-app.cloudhub.io", "description":"", "properties":{}, "propertiesOptions":{}, "status":"STARTED", "workers":{ (以下略) ... ]
各 Mule アプリケーションを特定する一意なキーは "domain" に格納されており、アプリケーションの名称と一致します。
payload flatMap(item, i) -> ( [item.domain as String] )
上記 DataWeave スクリプトを Set Variable コンポーネントに定義し、Mule アプリケーション名の配列を変数で保持しておきます。
(3) Muleアプリケーションのデプロイ情報を取得
以下にランタイムログの画面を再掲します。
[ランタイムログの画面]
画面右の Deployments と書かれている部分がデプロイ関連情報す。これは CloudHub API の /v2/applications/{domain}/deployments をコールすることで一括で取得することができます。ヘッダーには(2)同様、環境情報とトークンを付与します。また、{domain} URI パラメータには、(2)で取得したアプリケーション名を指定します。その他の I/F 定義の詳細はリンク先をご参照ください。
/v2/applications/{domain}/deployments をコールすると、下記のような payload が返却されます。
{ "data": [ { "deploymentId": "566f011be4b06b370949daff", "createTime": "2015-12-14T17:49:15.731Z", "startTime": "2015-12-14T17:49:19.329Z", "endTime": "2015-12-14T17:53:52.828Z", "instances": [ { "instanceId": "566f011be4b06b370949daff-0", "publicIPAddress": "52.91.11.88", "status": "STARTED", "region": "us-east-1" } ] }, { "deploymentId": "566f00c2e4b06b3709496e0d", "createTime": "2015-12-14T17:47:46.833Z", "startTime": "2015-12-14T17:47:49.282Z", "endTime": "2015-12-14T17:49:18.366Z", "instances": [] } (以下略) ... }
"deploymentId" は一意なデプロイ情報を、"instanceId" は一意なWorker 情報を示します。つまり、Worker を2つ設定してデプロイした場合は "instances" のサイズは 2 になります。
payload.data
上記 DataWeave スクリプトを Set Variable コンポーネントに定義し、Mule アプリケーション名のデプロイ情報を変数で保持しておきます。
(4) 各インスタンス(Worker)のログファイルを取得
[ログ自動アーカイブのロジック]
(3)の手順でアプリケーションのデプロイ情報を取得できました。デプロイ情報は過去のものも含めて配列に格納されているため、For Each コンポーネントでループ処理を行う必要があります。さらに、一つのデプロイ情報には複数のインスタンス(Worker)が存在する可能性があるので、再度For Each コンポーネントでループ処理を行います。
インスタンスのログを取得するには、CloudHub API の /v2/applications/{domain}/instances/{instanceId}/log-file をコールします。ヘッダーには他の API と同様、環境情報とアクセストークンを指定し、URI パラメータには以下の2つを指定します。
domain : 対象のアプリケーション名。(2)の手順で取得したアプリケーション名の配列のうち、現在処理中のものを指定する。
instanceId : 対象のインスタンスのID。上記画像2つ目の For Each スコープ内で、 payload.instanceId で取得できる。
その他の I/F 定義の詳細はリンク先をご参照ください。
/v2/applications/{domain}/instances/{instanceId}/log-file をコールすると、下記のような payload が返却されます。
[2015-12-14 17:52:33.412] INFO org.mule.module.launcher.application.DefaultMuleApplication [qtp18605202-31]: (t:null) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Initializing app 'test-test' + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [2015-12-14 17:52:34.065] INFO com.mulesoft.ch.monitoring.MonitoringCoreExtension [qtp18605202-31]: (t:null) Monitoring enabled: true [2015-12-14 17:52:34.066] INFO com.mulesoft.ch.monitoring.MonitoringCoreExtension [qtp18605202-31]: (t:null) Registering ping flow injector... [2015-12-14 17:52:34.083] INFO com.mulesoft.ch.queue.boot.PersistentQueueCoreExtension [qtp18605202-31]: (t:null) The PersistentQueueManager is NOT configured. The normal VM queue manager will be used (以下略) ...
これでログデータそのものが取得できました。
payload as String
上記 DataWeave スクリプトを Set Variable コンポーネントに定義し、最新のログを変数で保持しておきます。
いかがでしょうか。少し長くなってしまいましたが、本記事では Platform API を利用してログを取得するまでの流れを紹介しました。それなりに複雑な実装になっているので、文章では概要しかお伝えできませんが、大まかな流れと実装のポイントは掴めたでしょうか。後半では、前日のログとの差分のみを取得して、Box へアップロードする実装部分に関してご説明します。
[MuleSoft入門シリーズ]
MuleSoft入門(1)MuleSoft による API-led なアプリケーションネットワーク
MuleSoft入門(2)ようこそ Anypoint Platform へ
MuleSoft入門(3)Anypoint Studio による API の実装
MuleSoft入門(4)DataWeave によるデータ変換
MuleSoft入門(5)Flow Designer で Mule アプリケーションを開発
MuleSoft入門(6)MUnit による単体テスト
MuleSoft入門(7)API 開発におけるテストの考え方
MuleSoft入門(8)ポリシーと SLA
MuleSoft入門(9)カスタムポリシーの開発
MuleSoft入門(10)Mule API のバージョン管理
著者について
Minoru Nakanishi のコンテンツをもっと見る