Backstage OpenTelemtry
こんにちは。ACS事業部 亀崎です。
みなさんはBackstageにはOpenTelemetryを用いたmonitring機能が利用できることをご存知でしょうか。
こちらを導入すれば簡単に以下のような情報を得られるようになります。
Backstageは様々なモジュールを組み合わせて機能します。このため、どこで問題が起きているのか、どこの処理に時間がかかっているのかなどを特定するのに苦労します。OpenTelemetry、特にTracingが可能なことはそうした特定に役立ちます。
今回はBackstage OpenTelemetry機能を利用してAzure Application Insightsにデータを送信してみましょう。
Application InsightsでBackstageをmonitor
実はBackstage x Application Insightsの方法はMicrosoft Seveloper Community Blogでも紹介されています。 今回はこちらの内容を参考に実装しました。
こちらのページで紹介されているコードは次のようなものでした。
const { NodeSDK } = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { AzureMonitorTraceExporter } = require("@azure/monitor-opentelemetry-exporter"); const { AzureMonitorMetricExporter } = require("@azure/monitor-opentelemetry-exporter"); // Create an exporter instance const azTraceExporter = new AzureMonitorTraceExporter({ connectionString: process.env["APPLICATIONINSIGHTS_CONNECTION_STRING"] || "<YourAppInsightsConnectionString>" }); const sdk = new NodeSDK({ traceExporter: azTraceExporter, instrumentations: [getNodeAutoInstrumentations()], }); sdk.start();
さらにこの内容をもとに少し内容を変えました。
手元で実装した最終形がこちらになります。
packages/backend/src/ai-exporter.ts
import { NodeSDK } from '@opentelemetry/sdk-node'; import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { Resource } from '@opentelemetry/resources'; import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions';import { ApplicationInsightsSampler, AzureMonitorMetricExporter, AzureMonitorTraceExporter } from '@azure/monitor-opentelemetry-exporter' export type ApplicationInsightsTelemetoryOptions = { appName: string; appVersion: string; connectionString: string; sampling?: number; }; export const startAppInsightsTelemetry = (opts: ApplicationInsightsTelemetoryOptions) => { const { appName, appVersion, connectionString } = opts; const sampling = (opts.sampling ?? 1.0) < 1.0 ? opts.sampling : 1.0; const azTraceExporter = new AzureMonitorTraceExporter({ connectionString }); const azMetricExporter = new AzureMonitorMetricExporter({ connectionString }); const sdk = new NodeSDK({ resource: new Resource({ [ATTR_SERVICE_NAME]: appName, [ATTR_SERVICE_VERSION]: appVersion, }), sampler: new ApplicationInsightsSampler(sampling), traceExporter: azTraceExporter, metricReader: new PeriodicExportingMetricReader({ exporter: azMetricExporter, }), instrumentations: [getNodeAutoInstrumentations()], }); sdk.start(); }
packages/backend/src/instrumentation.js
const { startAppInsightsTelemetry} = require('./ai-exporter'); if (process.env.APPINSIGHTS_CONNECTION_STRING) { startAppInsightsTelemetry({ appName: process.env.APP_NAME || 'backstage', appVersion: process.env.npm_package_version || '0.0.0', connectionString: process.env.APPINSIGHTS_CONNECTION_STRING || '', sampling: Number(process.env.APPINSIGHTS_TRACE_SAMPLING || '1'), }); };
APPINSIGHTS_CONNECTION_STRING にはApplication InsightsのConnection Stringを、APPINSIGHTS_TRACE_SAMPLINGにはトレース取得時のサンプリングレートを設定します。サンプリングレートを設定しない場合100%のデータを収集します。すべて収集する意図があるならそれでもよいのですが、多量のデータが送信され、それなりのコストになってしまいます(それほど利用が多くないサイトですが、1日程度動かした段階の試算で月額1万円以上はかかりそうな雰囲気でした)。 このため、私の手元の環境ではサンプリングレートを0.1(つまり10%)に設定しています。
あとは起動時にinstrument.jsを指定するだけ。
ローカル開発時でデータ送信する場合
package.json
"scripts": { "start": "backstage-cli package start --require ./src/instrumentation.js", ...
Dockerfileで指定する場合
CMD ["node", "--require", "./instrumentation.js", "packages/backend", "--config", "app-config.yaml"]
あとは実際に少し動かしてみるとApplication Insightsでデータを見ることができるようになります。
Azure Portal > Application Insights > 名称選択
実際のデータは最初にご覧いただいたようなものになります。
いかがでしょうか。Azure環境でBackstageをご利用の際はぜひご活用ください。
さいごに
弊社ではPlatform Engineering、Backstageに関するご支援をさせていただいております。ご興味のある方ぜひご連絡ください。