合成モニターのサンプル

このドキュメントでは、合成モニターの作成に役立つテンプレートとサンプルコードについて説明します。サンプル関数は Google Cloud/synthetics-sdk-nodjs GitHub リポジトリで入手できます。

テンプレートに依存せずにテストを作成する場合、Error がスローされない限り、テストに必ず合格するようにします。Assert ライブラリを使用して、失敗した場合は、コードの適切な行に必ず戻るようにすることをおすすめします。

汎用テンプレート

汎用テンプレートは、送信 HTTP リクエストのトレースデータとログデータを収集するように構成されています。このソリューションでは、OpenTelemetry auto-instrumentation-node モジュールと winston ロガーを利用します。オープンソース プロダクトに依存するため、トレースデータとログデータの構造の変化が予想されます。したがって、収集されたトレースデータとログデータは、デバッグ目的でのみ使用してください。

独自のアプローチを実装して、送信 HTTP リクエストのトレースデータとログデータを収集できます。カスタム アプローチの例については、SyntheticAutoInstrumentation クラスをご覧ください。

汎用 Node.js のサンプル

generic-synthetic-nodejs のサンプルは、URL をクエリする方法を示しています。このサンプルには、Google Cloud コンソールに表示されるデフォルトの関数と同じものが含まれています。 サンプル全体を表示するには、 [その他] をクリックして、[GitHub で表示] を選択します。

const { instantiateAutoInstrumentation, runSyntheticHandler } = require('@google-cloud/synthetics-sdk-api');
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
const functions = require('@google-cloud/functions-framework');
const axios = require('axios');
const assert = require('node:assert');

functions.http('SyntheticFunction', runSyntheticHandler(async ({logger, executionId}) => {
  /*
   * This function executes the synthetic code for testing purposes.
   * If the code runs without errors, the synthetic test is considered successful.
   * If an error is thrown during execution, the synthetic test is considered failed.
   */
  logger.info('Making an http request using synthetics, with execution id: ' + executionId);
  const url = 'https://www.google.com/'; // URL to send the request to
  return await assert.doesNotReject(axios.get(url));
}));

TypeScript のサンプル

generic-synthetic-typescript のサンプルは、URL をクエリする方法を示しています。サンプル全体を表示するには、 [その他] をクリックして、[GitHub で表示] を選択します。

import {runSyntheticHandler, instantiateAutoInstrumentation} from '@google-cloud/synthetics-sdk-api'
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
import * as ff from '@google-cloud/functions-framework';
import axios from 'axios';
import assert from 'node:assert';
import {Logger} from 'winston';

ff.http('SyntheticFunction', runSyntheticHandler(async ({logger, executionId}: {logger: Logger, executionId: string|undefined}) => {
  /*
   * This function executes the synthetic code for testing purposes.
   * If the code runs without errors, the synthetic test is considered successful.
   * If an error is thrown during execution, the synthetic test is considered failed.
   */
  logger.info('Making an http request using synthetics, with execution id: ' + executionId);
  const url = 'https://www.google.com/'; // URL to send the request to
  return await assert.doesNotReject(axios.get(url));
}));

Puppeteer テンプレート

Puppeteer を使用する場合は、generic-puppeteer-nodejs サンプルから始めることを検討してください。

Puppeteer の必須の設定

Puppeteer を使用するには、次の手順を実行してください。

  1. Cloud Run 関数のソース ディレクトリに .puppeteerrc.cjs を配置します。

    const { join } = require('path');
    
    /**
     * @type {import("puppeteer").Configuration}
     */
    module.exports = {
      cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
    };
  2. Cloud Run 関数の package.json ファイルに次のスクリプトを追加します。

    "scripts": {
         "gcp-build": "node node_modules/puppeteer/install.mjs"
    },
    

Puppeteer のサンプル

generic-puppeteer-nodejs サンプルは、Cloud Run 関数で Puppeteer を使用する方法を示しています。サンプル全体を表示するには、 [その他] をクリックして、[GitHub で表示] を選択します。

const { instantiateAutoInstrumentation, runSyntheticHandler } = require('@google-cloud/synthetics-sdk-api');
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
const functions = require('@google-cloud/functions-framework');
const axios = require('axios');
const assert = require('node:assert');
const puppeteer = require('puppeteer');


functions.http('CustomPuppeteerSynthetic', runSyntheticHandler(async ({logger, executionId}) => {
 /*
  * This function executes the synthetic code for testing purposes.
  * If the code runs without errors, the synthetic test is considered successful.
  * If an error is thrown during execution, the synthetic test is considered failed.
  */

 // Launch a headless Chrome browser and open a new page
 const browser = await puppeteer.launch({ headless: 'new', timeout: 0});
 const page = await browser.newPage();

 // Navigate to the target URL
 const result = await page.goto('https://www.example.com', {waitUntil: 'load'});

 // Confirm successful navigation
 await assert.equal(result.status(), 200);

 // Print the page title to the console
 const title = await page.title();
 logger.info(`My Page title: ${title} ` + executionId);

 // Close the browser
 await browser.close();
}));

Selenium WebDriver のテンプレート

Selenium WebDriver を使用する場合は、generic-selenium-nodejs サンプルから始めることを検討してください。GitHub から入手できるサンプルには、index.jspackage.json のファイルが含まれています。

サンプル全体を表示するには、 [その他] をクリックして、[GitHub で表示] を選択します。

const {
  instantiateAutoInstrumentation,
  runSyntheticHandler,
} = require('@google-cloud/synthetics-sdk-api');
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
const functions = require('@google-cloud/functions-framework');
const assert = require('node:assert');

const { Builder, Browser, By } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

/*
 * This function executes the synthetic code for testing purposes.
 * If the code runs without errors, the synthetic test is considered successful.
 * If an error is thrown during execution, the synthetic test is considered failed.
 */
functions.http(
  'CustomSeleniumSynthetic',
  runSyntheticHandler(async ({ logger, executionId }) => {
    /*
     * Construct chrome options
     * Note: `setChromeBinaryPath` must be set to '/srv/bin/chromium' when running in
     *   GCF (but will need to be changed if running on local machine).
     */
    const options = new chrome.Options();
    options.setChromeBinaryPath('/srv/bin/chromium');
    options.addArguments('--headless', '--disable-gpu', '--no-sandbox');

    // Launch headless chrome webdriver with options
    const driver = await new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .build();

    // Navigate to the target URL
    await driver.get('https://example.com');

    // Retrieve title and `a` tag of page
    const title = await driver.getTitle();
    const aTag = await driver.findElement(By.css('a')).getText();

    // assert title is as expected and print to console
    await assert.equal(title, 'Example Domain');
    logger.info(`My URL title is: ${title} ` + executionId);

    await driver.quit();
  })
);

Mocha テンプレート

Mocha テンプレートに依存するテストを作成する場合は、失敗したときに一連のテストを続行するか中止するかを検討します。失敗の後に一連のテストを中止するには、bail フラグを設定する必要があります。

API のデプロイ、API エンドポイント用のサンプル Mocha テストスイート、合成モニターの構成方法など、エンドツーエンドの例については、Google Cloud 合成モニタリングのチュートリアルのブログをご覧ください。

mocha-url-ok サンプルは、Cloud Run 関数が Mocha テストスイートを呼び出す方法を示し、サンプル テストスイートを提供します。サンプル全体を表示するには、 [その他] をクリックして、[GitHub で表示] を選択します。


const functions = require('@google-cloud/functions-framework');
const GcmSynthetics = require('@google-cloud/synthetics-sdk-mocha');

/*
 * This is the server template that is required to run a synthetic monitor in
 * Google Cloud Functions.
 */

functions.http('SyntheticMochaSuite', GcmSynthetics.runMochaHandler({
  spec: `${__dirname}/mocha_tests.spec.js`
}));

/*
 * This is the file may be interacted with to author mocha tests. To interact
 * with other GCP products or services, users should add dependencies to the
 * package.json file, and require those dependencies here A few examples:
 *  - @google-cloud/secret-manager:
 *        https://www.npmjs.com/package/@google-cloud/secret-manager
 *  - @google-cloud/spanner: https://www.npmjs.com/package/@google-cloud/spanner
 *  - Supertest: https://www.npmjs.com/package/supertest
 */

const {expect} = require('chai');
const fetch = require('node-fetch');

it('pings my website', async () => {
  const url = 'https://google.com/'; // URL to send the request to
  const externalRes = await fetch(url);
  expect(externalRes.ok).to.be.true;
});

broken-links-ok サンプルは、無効なリンクのチェッカーの構成方法を示しています。このテンプレートでは、options オブジェクトの値のみを指定します。このオブジェクトは、テストする URI とテストのパラメータを指定します。

Puppeteer を使用している場合は、Puppeteer 必須の設定の手順を実行してください。

サンプル全体を表示するには、 [その他] をクリックして、[GitHub で表示] を選択します。


const functions = require('@google-cloud/functions-framework');
const GcmSynthetics = require('@google-cloud/synthetics-sdk-broken-links');

const options = {
  origin_uri: "https://example.com",
  // link_limit: 10,
  // query_selector_all: "a", // https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
  // get_attributes: ['href'], // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
  // link_order: "FIRST_N", // "FIRST_N" or "RANDOM"
  // link_timeout_millis: 30000, // timeout per link
  // max_retries: 0, // number of retries per link if it failed for any reason
  // wait_for_selector: '', // https://pptr.dev/api/puppeteer.page.waitforselector
  // per_link_options: {},
    /*
    // example:
      per_link_options: {
        'http://fake-link1': { expected_status_code: "STATUS_CLASS_4XX" },
        'http://fake-link2': { expected_status_code: 304 },
        'http://fake-link3': { link_timeout_millis: 10000 },
        'http://fake-link4': {
          expected_status_code: "STATUS_CLASS_3XX",
          link_timeout_millis: 10,
        },
      },
    */
  // total_synthetic_timeout_millis: 60000 // Timeout set for the entire Synthetic Monitor
  // screenshot_options: { capture_condition: 'FAILING', storage_location: '' }
};

functions.http('BrokenLinkChecker', GcmSynthetics.runBrokenLinksHandler(options));

次のステップ