【大阪 / 横浜 / 徳島】インフラ / サーバーサイドエンジニア募集中!

【大阪 / 横浜 / 徳島】インフラ / サーバーサイドエンジニア募集中!

【導入実績 500社以上】AWS 構築・運用保守・監視サービス

【導入実績 500社以上】AWS 構築・運用保守・監視サービス

【CentOS 後継】AlmaLinux OS サーバー構築・移行サービス

【CentOS 後継】AlmaLinux OS サーバー構築・移行サービス

【WordPress 専用】クラウドサーバー『ウェブスピード』

【WordPress 専用】クラウドサーバー『ウェブスピード』

Google Chromeのヘッドレスモードで外形監視が細かくできそうなのでやってみた

こんにちは。
開発チームのワイルド担当、まんだいです。

株式会社ビヨンドは、MSPなので、お客様のオーダーによって、色々な監視をしています。

その中で外形監視という監視があり、これはユーザーがサイトにアクセスするのと同じ(もしくは近しい)方法でサイトにアクセスし、ページが正常に表示できているかをチェックするものです。

サイトにアクセスし、正常にデータが取れているかは何なりとツールもありますし、自前でcurlなどでやれなくもないですが、これらの方法では、各種モニタリングツールからのアラートを受けた人がサイトにアクセスして初めて原因を探ることができます。

それでもいいんですが、今回はGoogle Chromeのヘッドレスモードを使えば、DevToolsを経由して、どのコンテンツの取得に時間が掛かっているのかまで細かく取得が可能なので、サイトを見ずとも原因究明が可能になるかも知れないよという可能性を探ってみたいと思います。

準備編

まずは一通り試すのに必要なものを揃えます。
後の方にコピペで動くサンプルもあります。

 

Google Chrome

まずは、ヘッドレスモードで動くGoogle Chrome(バージョン59以上)をインストールします。
このバージョンのGoogle Chromeは既に安定版ですので、通常通りインストーラーを使ってインストールします。
また、自動更新が有効だと、既に導入されていると思います。

 

Node.js

今回は、最新版の8.0.0を利用しましたが、そこそこ古くても大丈夫なのではないかと思います。

以下のモジュールをnpmでインストールしています。

  • chrome-launcher
  • chrome-remote-interface

chrome-launcherは、Node.jsからGoogle Chromeを起動する際に利用しています。
chrome-remote-interfaceは、Node.jsからGoogle ChromeのDevToolsにアクセスする際に利用しています。

1
npm install chrome-launcher chrome-remote-interface

 

サンプルスクリプトでは、起動時に毎回Google Chromeを起動し、終了時に停止する処理が入っていますが、本格的に利用するのであれば、Google Chromeは起動しっぱなしでもいいような気もします(メモリ使用量がどんどん膨らんでいきそうな気もするので、定期的なリスタートは必要かもしれません)。

以上の2つを導入すれば、準備は完了です。

Google Chromeのヘッドレスモードに関する基本的な使い方については、Google Chrome 59でヘッドレスモードが標準搭載されたのでいじってみるを参考にしていただけると思います。
Node.jsからGoogle Chromeのヘッドレスモードを利用する基本的な方法については、Node.jsからヘッドレスGoogle Chromeを使ってみるをどうぞ。

 

サンプルスクリプト

以下のサンプルを用意しましたので、ご利用はご自由に!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const ChromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
 
function launchChrome(headless = true) {
    ChromeLauncher.launch({
        port: 9222,
        autoSelectChrome: true,
        chromeFlags: [
            '--disable-gpu',
            headless ? '--headless' : '',
            '--no-sandbox',
        ],
    }).then(launcher => {
        CDP(protocol => {
            setTimeout(() => {
                protocol.close();
                launcher.kill();
                process.exit();
            }, 10000);
            const {Page, Network} = protocol;
            Promise.all([
                Page.enable(),
                Network.enable(),
            ]).then(() => {
                Page.navigate({url : 'https://beyondjapan.com/blog/2017/07/headless-chrome-networks'});
                Network.responseReceived(res => {
                    console.log(r)
                })
            })
        })
    })
}
 
launchChrome();

 

勝手に終了するわけではないので、setTimeoutを使って10秒後に終了するようにしています。
1ページ内に発生する通信が多いサイトだと出力も多いですが、1つ抜き出してみると

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{ requestId: '30371.7375',
  frameId: '30371.1',
  loaderId: '30371.190',
  timestamp: 1197407.412915,
  type: 'Document',
  response:
   { url: 'https://beyondjapan.com/',
     status: 200,
     statusText: 'OK',
     headers:
      { Date: 'Tue, 18 Jul 2017 04:16:02 GMT',
        'Transfer-Encoding': 'chunked',
        Server: 'nginx',
        Connection: 'keep-alive',
        Link: '<https://beyondjapan.com/cms-json/>; rel="https://api.w.org/"',
        Vary: 'Accept-Encoding',
        'Content-Type': 'text/html; charset=UTF-8' },
     mimeType: 'text/html',
     connectionReused: false,
     connectionId: 5394,
     remoteIPAddress: '122.218.102.93',
     remotePort: 80,
     fromDiskCache: false,
     fromServiceWorker: false,
     encodedDataLength: 253,
     timing:
      { requestTime: 1197406.917743,
        proxyStart: -1,
        proxyEnd: -1,
        dnsStart: 0.944999977946281,
        dnsEnd: 2.30200006626546,
        connectStart: 2.30200006626546,
        connectEnd: 7.89500004611909,
        sslStart: -1,
        sslEnd: -1,
        workerStart: -1,
        workerReady: -1,
        sendStart: 7.98300001770258,
        sendEnd: 8.11700010672212,
        pushStart: 0,
        pushEnd: 0,
        receiveHeadersEnd: 494.426999939606 },
     protocol: 'http/1.1',
     securityState: 'neutral' } }

 

DevToolsのNetworkタブで取れる情報は概ね取得できているようです。
タイムスタンプ周りの単位は全てミリ秒となっているようです。

他にもcookieの削除や追加(これはセッションを使ったサイトの監視に便利かも)、キャッシュのクリアユーザーエージェントの書き換えなど、DevToolsでできることは一通りできるようです。
D3.jsあたりで取得したデータを表示するUIを作るのも楽しそうですね!

 

まとめ

Google Chromeのヘッドレスモードでやる外形監視、いかがでしたか?

監視ツールを使うほうがコストが掛からないとは思いますが、読み込むコンテンツのレスポンスが全て取れるので、CDNでなんかあったのかとか、APIからのレスポンスが激しく遅いとか、そういった切り分けが即座にできるようになりそうで使い道はありそうです。

以上です。

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
0
読み込み中...
0 票, 平均: 0.00 / 10
2,059
X facebook はてなブックマーク pocket
【2026.6.30 Amazon Linux 2 サポート終了】Amazon Linux サーバー移行ソリューション

【2026.6.30 Amazon Linux 2 サポート終了】Amazon Linux サーバー移行ソリューション

この記事をかいた人

About the author

萬代陽一

ソーシャルゲームのウェブ API などの開発がメイン業務ですが、ありがたいことにマーケティングなどいろんな仕事をさせてもらえています。
なおビヨンド内での私の肖像権は CC0 扱いになっています。