Exemples pour la surveillance synthétique

Ce document décrit les modèles et les exemples de code disponibles pour vous aider à créer des moniteurs synthétiques. Les exemples de fonctions sont disponibles dans le dépôt GitHub Google Cloud/synthetics-sdk-nodjs.

Si vous écrivez des tests sans vous appuyer sur un modèle, assurez-vous passe à moins qu'une erreur Error ne soit générée. Nous vous recommandons d'utiliser la bibliothèque Assert pour vous assurer que, en cas d'échec, ils sont attribués à la ligne de code appropriée.

Modèles génériques

Les modèles génériques sont configurés pour collecter les données de trace et de journal les requêtes HTTP sortantes. La solution s'appuie sur le module auto-instrumentation-node d'OpenTelemetry et le journal Winston. En raison de la dépendance aux produits Open Source, vous devez vous attendre à des changements la structure des données de trace et de journal. Par conséquent, les données de trace et de journal collectées ne doivent être utilisées qu'à des fins de débogage.

Vous pouvez implémenter votre propre approche pour collecter des données de trace et de journalisation pour les requêtes HTTP sortantes. Pour obtenir un exemple d'approche personnalisée, consultez la classe SyntheticAutoInstrumentation.

Exemple de code Node.js générique

L'exemple generic-synthetic-nodejs illustre comment interroger une URL. Cet exemple contient la même fonction que la fonction par défaut affichées par la console Google Cloud. Pour afficher l'exemple complet, cliquez sur More (Plus). puis sélectionnez Afficher sur 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));
}));

Exemple TypeScript

L'exemple generic-synthetic-typescript montre comment interroger une URL. Pour afficher l'exemple complet, cliquez sur More (Plus). puis sélectionnez Afficher sur 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));
}));

Modèle Puppeteer

Si vous utilisez Puppeteer, envisagez de commencer par la Exemple de generic-puppeteer-nodejs.

Configuration Puppeteer requise

Pour utiliser Puppeteer, assurez-vous de suivre les étapes suivantes :

  1. Incluez .puppeteerrc.cjs dans le répertoire source de votre Fonction Cloud Run:

    const { join } = require('path');
    
    /**
     * @type {import("puppeteer").Configuration}
     */
    module.exports = {
      cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
    };
  2. Ajoutez le script suivant au fichier package.json de votre Fonction Cloud Run:

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

Exemple Puppeteer

L'exemple generic-puppeteer-nodejs montre comment utiliser Puppeteer avec votre fonction Cloud Run. Pour afficher l'exemple complet, cliquez sur More (Plus). puis sélectionnez Afficher sur 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();
}));

Modèle WebDriver pour Selenium

Si vous utilisez Selenium WebDriver, envisagez de commencer par l'exemple generic-selenium-nodejs. L'échantillon, qui est disponible sur GitHub, inclut un fichier index.js et un fichier package.json.

Pour afficher l'exemple complet, cliquez sur  Plus, puis sélectionnez Afficher sur 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();
  })
);

Modèle Mocha

Si vous écrivez des tests qui reposent sur le modèle Mocha, réfléchissez à la question de savoir si une séquence de tests doit se poursuivre ou s'arrêter en cas d'échec. Pour arrêter une séquence de tests après un échec, vous devez définir le paramètre bail.

Pour un exemple de bout en bout incluant le déploiement d'une API, un exemple de suite de test Mocha pour les points de terminaison de l'API et la configuration du moniteur synthétique, consultez le blog Tutoriel sur la surveillance synthétique Google Cloud.

L'exemple mocha-url-ok montre comment une fonction Cloud Run peut appeler Mocha et fournit un exemple de suite de tests. Pour afficher l'exemple complet, cliquez sur More (Plus). puis sélectionnez Afficher sur 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;
});

L'exemple broken-links-ok montre comment configurer un vérificateur de liens brisés. Pour ce modèle, vous ne spécifiez que les valeurs de l'objet options. Cet objet spécifie l'URI à tester et les paramètres du test.

Si vous utilisez Puppeteer, veillez à remplir les Étapes de configuration de Puppeteer.

Pour afficher l'exemple complet, cliquez sur  Plus, puis sélectionnez Afficher sur 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));

Étape suivante