今回のテーマ
前回の投稿から2週間が経過しました、早いですね~。今回のテーマは、DynatraceのSynthetic(外形監視)を使う話です。Syntheticは、オブザーバビリティツールの代表的なものは大体装備されていると思います。24時間365日、自動的にWebサイトやAPIにアクセスし、速度計測や正常性確認を行ってくれる優れものです。Dynatraceにも、当然その機能はあります。が、Synetheticの特長のひとつに、アクションとして、JavaScriptをそのまま記述でき、活用出来るという点があります。「あるページのページロードを発生させる」、「ボタンをクリックする」、「Text入力する」といった組み込まれたユーザアクションの他に、JavaScriptコードを直接使うことができます。そのため、あるページのCSSやJavaScript variableの値を読み込み、それをあるAPI経由でデータをIngestするといった作業が登録できます。今日は、DynatraceのSyntheticが持つ、そのJavaScriptイベントを使ったお話です。
やろうと思ったきっかけ
QiitaのBlogのテーマを何にするか考えていた際、ユナイテッド航空のキャンペーンメールが届きました。「ユナイテッド航空のマイルを使って、米国シカゴに行って、シカゴ・ホワイトソックスとロサンゼルス・ドジャースの試合を見よう!」という内容のものでした(下図参照)。このキャンペーンでは、ユナイテッド航空のマイルをつかったオークションプログラムで、エノコミークラス、プレミアムプラス(プレミアムエコノミーのこと)、ビジネスクラスの3つが用意されていました。ユナイテッド航空のマイルホルダーの私としては、ぜひ参加したいと思い!ましたが、毎回 bid price をクラス毎にWebサイトへアクセスして調べるのは面倒だなと思い、DynatraceのSyntheticを使って可視化できるようにしようと思い立ったわけです。
このユナイテッド航空のキャンペーンは、既に終了しています。
でも、どうやってBidプライスをメトリクス化する?
冒頭でお話ししたとおり、DynatraceはSyntheticのアクションにJavaScriptが使えるため、この機能を活用していきます。Bidプライスをメトリクス化(可視化)するまでのステップは、以下の4つです。
- オークションページにアクセス Synethtic を作成する
- Webページに表示されている BidプライスのHTMLエレメントを確認し、プライス情報をJavaScriptで抜き取る
- 一旦、Dynatraceのホームページにアクセスする
- 抜き取ったBidプライスをメトリクス化するため、DynatraceのMetric Ingest APIにデータをPOSTする
- DashboardsやNotebooksで、可視化する
以降、順番に詳しく見ていきましょう。
1. オークションサイトにアクセスするSyntheticを作成する
まずは、Syntheticを作成します。今回のキャンペーンでは、3つのフライトクラスが用意されており、そのフライトクラス毎にWebページのアクセス先が異なるため、3つの Synthetic を作成します。エコノミー用、プレミアムクラス用、ビジネスクラス用の3つです。作り方は、こちらのヘルプをご参照下さい。
最初のSyntheticイベントは、該当のキャンペーンページにアクセスすることなので、クラス毎に提供されるWebページのURLを「Navigate」アクションのURLに登録するだけで完了です。
2. Webページに表示されている BidプライスのHTMLエレメントを確認し、プライス情報をJavaScriptで抜き取る
ここから Dynatrace の Synthetic の特長である、JavaSciptイベントの登場です。Webページに表示される現在のBidプライスをどうやって特定できるか見ていきます。ブログを書いている時点(2024年6月6日)では、すでにオークションサイトがクローズしているので、実際のBidプライスのHTMLがどのように表現されているかここでかくことはできませんが、オークションが実行されている期間に、私が調べると currentprice.Bidding_Current_Price
という span エレメントで、一意にその情報を特定出来たので、下記のようにしてWebページにアクセスした際に、BidプラスをGrabするJavaScriptを定義します。「¥」記号や、カンマ「,」の表示を取り除く作業も、ここで対処します。
var bidding_current_price;
bidding_current_price = document.querySelector('span.currentprice.Bidding_Current_Price').textContent;
var price_value = bidding_current_price.split(' ')[0];
var final_value = price_value.replace(/\,/g, '');
api.setValue('final_value', final_value);
api.info(final_value); <<< Bidプライスが取れているかを確認するために使用(Debug目的)
3. 一旦、Dynatraceのホームページにアクセスする
ステップ2で抜き取ったBidプライスをDynatraceで可視化できるよう、Metric Ingest APIにそれをPOSTするまえに、ひとつ大切なアクションを追加します。というのは、このステップを介さずに、JavaScriptイベントを追加して、データをPOSTしようとしても、エラーになるためです。
理由は、このJavaScriptはSynthetic上で動作する(ブラウザ上のDev toolのConsoleで実行しているのと同じ)ため、ブラウザがアクセスしているドメイン united.com
とは異なるドメイン xxxx.live.dynatrace.com
へ、JavaScriptを実行しようとするため、CORSエラーが発生するためです。
この制約を解除するため、一旦 www.dynatrace.com
へアクセスします。イベントとしては、Navigateイベントをここに追加します。
なお、www.dynatrace.com
へアクセスした際、Dev toolで Response-header を見ると、Content-Security-Policy
に *.dynatrace.com
が含まれているため、このサイトにアクセすると、xxx.live.dynatrace.com
にJavaScriptが実行できることが分かります。
4. 抜き取ったBidプライスをメトリクス化するため、DynatraceのMetric Ingest APIにデータをPOSTする
ここもDynatraceの特長のひとつではないでしょうか?DynatraceはいろいろなメトリクスをDynatraceに取り込めるよう Metric Ingest API なる機能を持っています。このAPIにHTTP POSTで、ステップ2で抜き取ったBidプライスをフライトクラス毎に分割(Dimension)し、JavaScriptを使って送信します。以下、実際に使用したパラメータとJavaScriptです。
- Metric Ingest API
- https://.live.dynatrace.com/api/v2/metrics/ingest
- 付与するHTTP Header
- Authorization: Api-Token
- Content-Type: text/plain
- メトリクス名
- united.bidding_price
- Dimension
- class=economy
- class=premium
- class=business
- Metrics value
- final_value = step2 で取得しbid price
var api_token = '<my_token>';
currentPrice = function() {
url = 'https://<my_tenant>.live.dynatrace.com/api/v2/metrics/ingest';
pdata = 'united.bidding_price';
pdata += ',class=economy ';
pdata += api.getValue('final_value');
fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Api-Token ' + api_token,
'Content-Type': 'text/plain'
},
body: pdata
}).then(
reply => reply.json()).then(obj => {
api.info('Fetch response: ' + JSON.stringify(obj));
api.finish();
}).catch(
e => {
api.info('Oops! ' + e);
api.finish();
});
};
api.startAsyncSyntheticEvent();
try {
currentPrice();
} catch (err) {
api.error('Problem parsing resources: ' + err);
api.finish();
}
DynatraceのJavaScriptイベントの強力なひとつの特長として、同じSynethicのシナリオの中であれば、変数を参照出来ることがあげられます。今回の場合であれば、Bidプラスはステップ2で収集して、final_value
という変数に格納しました。その変数をステップ4のJavaScript内から呼び出せます。下記の部分が該当します。そのため、やろうと思えば何でもできる拡張性を備えています。
pdata += api.getValue('final_value');
5.DashboardsやNotebooksで、可視化する
Syntheticで取れたBidプライスが、無事にDynatraceに取り込まれているか確認してみましょう。今回はNotebooksを使いました。DQL(Dynatrace Query Language)で、timeseries コマンドから united.bidding_price メトリクスを呼び出し、表示してみましょう。いいですね、いい感じで可視化できました!パチパチパチ👏👏👏
まとめ
いかがでしたか?今回は、私の個人的な一通のメールをきっかけに Syntehtic + Metrics Ingest を実際に使ったブログを紹介しました。この記事でも何度も触れていますが、DynatraceのSyntheticの大きな特長として、JavaScriptのコードをイベントとして登録できるので、やりたいことの幅が大きく広がるのではないでしょうか?
最後のグラフを見ると分かりますが、結局このオークションではどのクラスもBidプライスが高騰し、エコノミープラスでも40万マイル以上必要になりました(ビジネスクラスに至っては、80万マイルまで高騰😭😭)。大谷翔平君の人気はすごいのと、みんなそんなユナイテッド航空のマイルを持っているんだという、2つの事実を改めて学んだ瞬間でした。
まだ、Dynatraceを触ったことがない方、このブログを見てやってみたいと思われた方は、下記フリートライアルにてお試し下さい。↓↓↓
Dynatraceフリートライアル → https://www.dynatrace.com/ja/trial/