Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

AzureサービスでホストしているAngularアプリをElastic APMで監視してみる

みなさんこんにちは、最近Azure Developer Associate(AZ-204)に無事合格したハヤトです。
これも良い機会ということで、実際にAzureのサービスでアプリをホストしてみるとともに、
Elastic on AzureでAPM環境も手軽に用意してモニタリングも試してみよう、というのが今回の記事の内容になります。

概要

今回はAngular+FastAPIで作った超シンプルなアプリをサンプルとして使用しました。

構成図
f:id:acro_h_nomura:20210627192253p:plain

トップ画面
f:id:acro_h_nomura:20210618025204p:plain

「go to Time」をクリックするとrouterLinkでTime画面に遷移し、現在時刻を取得する「now」APIを呼び出して画面に時刻を表示します。
f:id:acro_h_nomura:20210626002415p:plain

クライアント画面はAngularで実装したアプリをビルドして、Azure Storageで静的Webサイトとしてホスティングしています。
docs.microsoft.com

APIはFastAPIで実装したものをAzure App Serviceとしてデプロイしています。
docs.microsoft.com

※この記事ではアプリの実装およびデプロイ手順の詳細については説明しませんが、上記ページを参考に作成しています。

それでは、作成したアプリをElastic APMでモニタリングするために行った手順を紹介していきます。

Elastic APMの準備

今回はAzure Portalからデプロイを行いました。手順(2021/06現在)をステップバイステップで紹介します。

1. Azure Portalの検索フォームからMarketplaceの「Elastic Cloud (Elasticsearch managed service) 」を検索。
f:id:acro_h_nomura:20210615004901p:plain
今回はキャプチャ内右側の「Marketplace」にあるElastic Cloudを使用していますが、左側の「サービス」にある方ではAzureポータル内でElasticsearchデプロイメントの管理などができる、より統合されたサービスが利用可能です。
※2021/06現在ではパブリックプレビューで、一部のリージョンのみ対応しています。
www.elastic.co


2. 必要情報を入力してリソースを作成。
f:id:acro_h_nomura:20210615005433p:plain

3. リソース作成完了したら「アカウントを今すぐ構成」を選択。
f:id:acro_h_nomura:20210615005628p:plain

4. Elastic Cloudの登録画面が開くので、必要情報を入力して登録。
f:id:acro_h_nomura:20210615005807p:plain

5. 登録完了したらElastic Cloudにログインして「Create deployment」を選択。
f:id:acro_h_nomura:20210615010728p:plain

6. APMを試すので「Observability」を選択。
f:id:acro_h_nomura:20210615010136p:plain

7. 「Customize」を選択すると詳細な構成を設定できます。
f:id:acro_h_nomura:20210627230109p:plain
今回のようなお試しであれば、ミニマムの構成にしてコストを抑えるのが良いでしょう。もちろん後からスケールさせることも可能です。

8. デプロイ完了したらクレデンシャルを忘れず保存。
f:id:acro_h_nomura:20210629094737p:plain

これでElastic APMが利用可能な状態になりました。

f:id:acro_h_nomura:20210629094948p:plain
APMのエンドポイントはデプロイメント画面のコチラから確認できます。後で使用するので手元にコピーしておきましょう。

Angularアプリ側の設定

f:id:acro_h_nomura:20210627193433p:plain
Elastic APMエージェントは様々な言語・フレームワークに対応しており、今回適用対象となるAngularにもパッケージが用意されています。
必要なパッケージをインストールし、ソースコードに数行の設定を追記するだけでAPMが可能になります。
www.elastic.co

公式ドキュメントに従い、以下のように設定を行いました。

パッケージのインストール

npm install @elastic/apm-rum-angular --save

AppModule

import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ApmModule, ApmService } from '@elastic/apm-rum-angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AboutPageComponent } from './page/about-page/about-page.component';
import { TimePageComponent } from './page/time-page/time-page.component';
import { TopPageComponent } from './page/top-page/top-page.component';


@NgModule({
  declarations: [
    AppComponent,
    TopPageComponent,
    AboutPageComponent,
    TimePageComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ApmModule,
    HttpClientModule,
  ],
  providers: [ApmService],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(service: ApmService) {
    // Agent API is exposed through this apm instance
    const apm = service.init({
      serviceName: 'elastic-apm-test-client', // Elastic APM側での表示名。
      serverUrl: 'https://example.com/', // APMのエンドポイントを指定。
      distributedTracingOrigins: ['https://example.net'],  // バックエンドAPIのURLを指定。
    });

    apm.setUserContext({
      'username': 'foo',
      'id': 'bar'
    });
  }
}

ApmModuleとApmServiceをimportして、コンストラクタ内でapmの設定を行います。
serverUrlには先程デプロイしたAPMのエンドポイントを指定します。
これによってAngularのルーターイベントがキャプチャされるようになります。
また、distributedTracingOriginsにElastic APMを適用したバックエンドAPIのURLを指定することで、異なるオリジンへのリクエストも分散トレーシングに含めることができます。
www.elastic.co

FastAPI側の設定

f:id:acro_h_nomura:20210627193707p:plain
API側も同様に、公式ドキュメントに従って設定を行いました。
https://www.elastic.co/guide/en/apm/agent/python/master/starlette-support.html

from datetime import datetime

from elasticapm.contrib.starlette import ElasticAPM, make_apm_client
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

apm = make_apm_client(
    {
        "SERVICE_NAME": "elastic-apm-test-api",
        "SERVER_URL": "https://example.com",
        "SECRET_TOKEN": "SECRET_TOKEN",
    }
)
app = FastAPI()
app.add_middleware(ElasticAPM, client=apm)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.org"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/api/now")
def get_now():
    return {"now": datetime.now()}

今回はクライアントアプリとAPIが別オリジンなので、CORSの設定が必要になります。
CORSMiddlewareのallow_originsにクライアントアプリのオリジンを追加してあげましょう。
fastapi.tiangolo.com


secret tokenは「APM & Fleet」から確認できます。
f:id:acro_h_nomura:20210629095124p:plain

APMでモニタリング

Elastic APMを適用したアプリを操作するとリアルタイムで情報が蓄積されていきます。
デプロイしたAPMを開くと先程設定した名称でデータが蓄積されていることがわかります。
f:id:acro_h_nomura:20210626015111p:plain

サービスマップもこのような感じで見られます(クライアントとAPIだけなので寂しい…)。
f:id:acro_h_nomura:20210627195447p:plain

クライアント側の「elastic-apm-test-client」を選択すると、router-changeとして/timeのトランザクションがキャプチャされていることがわかります。
f:id:acro_h_nomura:20210626015417p:plain

/timeをクリックするとトランザクションの詳細が確認できます。
Servicesのところにclientとapi両方があるところからわかると通り、先程の簡単な設定だけで分散トレーシングも構成できています。
f:id:acro_h_nomura:20210629095237p:plain

また、API側は「Metrics」からシステムリソースの状態なども確認できます。
Cloud providerとしてazureが表示されており、このあたりの統合もしっかりされていることが伺えます。
f:id:acro_h_nomura:20210627200608p:plain

まとめ

以上、AzureサービスでホストしているAngularアプリをElastic APMで監視してみた際の手順を紹介しました。
実は上記のようなことをやるとなると結局ハマりどころが多いのではないか、ということで検証の目的もあったのですが、公式の情報に基づいてあっさり出来てしまいました。
APMの適用はサクッとできて、本質的な品質の向上に集中できる、というのが良いですね。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com