

# Escrever um script do canário
<a name="CloudWatch_Synthetics_Canaries_WritingCanary"></a>

As seções a seguir explicam como escrever um script de canário e como integrar um canário a outros serviços da AWS e com dependências e bibliotecas externas.

**Topics**
+ [Elaboração de um script para o canário usando o runtime do Java](Synthetics_WritingCanary_Java.md)
+ [Gravar um script de canário Node.js usando o runtime do Playwright](Synthetics_WritingCanary_Nodejs_Playwright.md)
+ [Gravar um script de canário Node.js usando o runtime do Puppeteer](CloudWatch_Synthetics_Canaries_WritingCanary_Nodejs_Pup.md)
+ [Escrever um script o canário do Python](CloudWatch_Synthetics_Canaries_WritingCanary_Python.md)
+ [Escrever uma configuração JSON para o esquema de múltiplas verificações do Node.js](CloudWatch_Synthetics_WritingCanary_Multichecks.md)

# Elaboração de um script para o canário usando o runtime do Java
<a name="Synthetics_WritingCanary_Java"></a>

**Topics**
+ [Estrutura de um projeto em Java para um canário](#Synthetics_canary_Java_package)
+ [Empacotamento do projeto para um canário](#Synthetics_canary_Java_package_canary)
+ [Nome do manipulador](#Synthetics_canary_Java_handler)
+ [Configurações do CloudWatch Synthetics](#Synthetics_canary_Java_config)
+ [Variáveis de ambiente do CloudWatch Synthetics](#Synthetics_canary_Java_variables)

## Estrutura de um projeto em Java para um canário
<a name="Synthetics_canary_Java_package"></a>

Para criar um canário em Java, você deve desenvolver o código, compilá-lo e implantar os artefatos compilados para o Synthetics. Você pode inicializar um projeto Java Lambda de várias maneiras. Por exemplo, você pode usar uma configuração padrão de projeto em Java no IDE de sua preferência, como IntelliJ IDEA ou Visual Studio Code. Você também pode criar a estrutura de arquivos necessária manualmente.

A estrutura geral de um projeto em Java para o Synthetics é a seguinte:

```
/project-root
    └ src
        └ main
            └ java
                └ canarypackage // name of package
                |    └ ExampleCanary.java // Canary code file
                |    └ other_supporting_classes
                - resources
                     └ synthetics.json // Synthetics configuration file    
     └ build.gradle OR pom.xml
```

Você pode usar o Maven ou o Gradle para criar seu projeto e gerenciar dependências.

Na estrutura apresentada acima, a classe `ExampleCanary` atua como ponto de entrada ou manipulador do canário.

 **Exemplo de classe de canário em Java** 

Este exemplo ilustra um canário que realiza uma solicitação get para um URL armazenado na variável de ambiente *TESTING\$1URL* do Lambda. O canário não usa nenhum dos métodos fornecidos pelo runtime do Synthetics.

```
package canarypackage;

import java.net.HttpURLConnection;
import java.net.URL;

// Handler value: canary.ExampleCanary::canaryCode
public class ExampleCanary { 
  public void canaryCode() throws Exception{ 
      URL url = new URL(System.getenv("TESTING_URL"));
      HttpURLConnection con=(HttpURLConnection)url.openConnection();
      con.setRequestMethod("GET");
      con.setConnectTimeout(5000);
      con.setReadTimeout(5000);
      int status=con.getResponseCode();
      if(status!=200){
        throw new Exception("Failed to load " + url + ", status code: " + status);
      }
  }
}
```

Recomenda-se fortemente modularizar seus canários usando a função `executeStep` da biblioteca fornecida pelo Synthetics. O canário realiza chamadas `get` para dois URLs distintos, que foram obtidos das variáveis de ambiente URL1 e URL2.

**nota**  
Para usar a funcionalidade `executeStep`, o método manipulador para o canário deve receber um parâmetro do tipo Synthetics, conforme mostrado abaixo. 

```
package canarypackage;

import com.amazonaws.synthetics.Synthetics;
import java.net.HttpURLConnection;
import java.net.URL;

// Handler value: canary.ExampleCanary::canaryCode
public class ExampleCanary {
  public void canaryCode(Synthetics synthetics) throws Exception {
    createStep("Step1", synthetics, System.getenv("URL1"));
    createStep("Step2", synthetics, System.getenv("URL2"));
    return;
  }
  
  private void createStep(String stepName, Synthetics synthetics, String url) throws Exception{
    synthetics.executeStep(stepName,()->{
      URL obj=new URL(url);
      HttpURLConnection con=(HttpURLConnection)obj.openConnection();
      con.setRequestMethod("GET");
      con.setConnectTimeout(5000);
      con.setReadTimeout(5000);
      int status=con.getResponseCode();
      if(status!=200){
        throw new Exception("Failed to load" + url + "status code:" + status);
      }
      return null;
    }).get();
  }
}
```

## Empacotamento do projeto para um canário
<a name="Synthetics_canary_Java_package_canary"></a>

O Synthetics aceita que o código do canário em Java seja fornecido em um arquivo *zip*. O arquivo .zip consiste nos arquivos de classe do código para o canário, nos JARs de dependências de entidades externas e no arquivo de configuração do Synthetics.

A estrutura geral de um arquivo .zip do Java compatível com o Synthetics é a seguinte:

```
example-canary
    └ lib
    |  └ //third party dependency jars
       └ java-canary.jar
    └ synthetics.json
```

Para gerar esse arquivo .zip usando a estrutura de projeto apresentada acima, é possível usar o Gradle (build.gradle) ou o Maven (pom.xml). Aqui está um exemplo.

Para obter informações sobre as dependências de tempo de compilação ou as interfaces para a biblioteca do Synthetics, consulte o arquivo README em [aws-cloudwatch-synthetics-sdk-java](https://github.com/aws/aws-cloudwatch-synthetics-sdk-java/tree/main).

```
plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    // Third party dependencies 
    // example: implementation 'software.amazon.awssdk:s3:2.31.9'
    
    // Declares dependency on Synthetics interfaces for compiling only
    // Refer https://github.com/aws/aws-cloudwatch-synthetics-sdk-java for building from source.
    compileOnly 'software.amazon.synthetics:aws-cloudwatch-synthetics-sdk-java:1.0.0'}

test {
    useJUnitPlatform()
}

// Build the zip to be used as Canary code.
task buildZip(type: Zip) {

    archiveFileName.set("example-canary.zip")
    destinationDirectory.set(file("$buildDir"))
    
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
        from(tasks.named("jar"))
    }
    from "src/main/java/resources/synthetics.json"
    
    doLast {
        println "Artifact written to: ${archiveFile.get().asFile.absolutePath}"
    }
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.named("build") {
    dependsOn "buildZip"
}
```

## Nome do manipulador
<a name="Synthetics_canary_Java_handler"></a>

O nome do manipulador é o ponto de entrada para o canário. Para o runtime em Java, o manipulador deve seguir o formato apresentado a seguir.

```
<<full qualified name for canary class>>::<<name of the method to start the execution from>>
// for above code: canarypackage.ExampleCanary::canaryCode
```

## Configurações do CloudWatch Synthetics
<a name="Synthetics_canary_Java_config"></a>

É possível configurar o comportamento do runtime em Java do Synthetics ao fornecer um arquivo de configuração em JSON opcional chamado `synthetics.json`. Esse arquivo deve ser empacotado no diretório raiz do pacote em .zip. Embora seja opcional, caso o arquivo de configuração não seja fornecido ou alguma chave de configuração esteja ausente, o CloudWatch usará os valores padrão.

Veja abaixo os valores de configuração compatíveis e seus padrões.

```
{
    "step": {
        "stepSuccessMetric": true,
        "stepDurationMetric": true,
        "continueOnStepFailure": false,
        "stepsReport": true
    },
    "logging": {
        "logRequest": false,
        "logResponse": false
    },
    "httpMetrics": {
        "metric_2xx": true,
        "metric_4xx": true,
        "metric_5xx": true,
        "aggregated2xxMetric": true,
        "aggregated4xxMetric": true,
        "aggregated5xxMetric": true
    },
    "canaryMetrics": {
        "failedCanaryMetric": true,
        "aggregatedFailedCanaryMetric": true
    }
}
```

 **Configurações das etapas** 
+ *continueOnStepFailure*: determina se um script deve continuar mesmo após a falha de uma etapa. O padrão é falso.
+ *stepSuccessMetric*: determina se a métrica ` SuccessPercent` de uma etapa deve ser emitida. A métrica `SuccessPercent` para uma etapa será *100* se ela for bem-sucedida na execução do canário, e *0* se falhar. O padrão é *true*.
+ *stepDurationMetric*: determina se a métrica *Duration* de uma etapa será gerada. A métrica *Duration* representa a duração da execução da etapa, em milissegundos. O padrão é *true*.

 **Configurações de registros em log** 

Aplica-se aos logs gerados pelo CloudWatch Synthetics. Controla o detalhamento dos logs de solicitações e respostas.
+ *logRequest*: especifica se todas as solicitações devem ser registradas em log nos logs do canário. O padrão é falso.
+ *logResponse*: especifica se todas as respostas devem ser registradas em log nos logs do canário. O padrão é falso.

 **Configurações de métricas HTTP** 

Configurações de métricas relacionadas à contagem de solicitações de rede com diferentes códigos de status HTTP, emitidos pelo CloudWatch Synthetics para o canário.
+ *metric\$12xx*: especifica se a métrica *2xx* (com a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.
+ *metric\$14xx*: especifica se a métrica *4xx* (com a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.
+ *metric\$15xx*: especifica se a métrica *5xx* (com a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.
+ *aggregated2xxMetric*: especifica se a métrica *2xx* (sem a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.
+ *aggregated4xxMetric*: especifica se a métrica *4xx* (sem a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.
+ *aggregated5xxMetric*: especifica se a métrica *5xx* (sem a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.

 **Configurações de métricas do canário** 

Configurações de outras métricas emitidas pelo CloudWatch Synthetics.
+ *failedCanaryMetric* do Analisador de Acesso à Rede: especifica se a métrica *Failed* (com a dimensão CanaryName) será gerada para esse canário. O padrão é *true*.
+ *aggregatedFailedCanaryMetric*: especifica se a métrica *Failed* (sem a dimensão CanaryName) deve ser emitida para este canário. O padrão é *true*.

## Variáveis de ambiente do CloudWatch Synthetics
<a name="Synthetics_canary_Java_variables"></a>

Você pode configurar o nível e o formato de log ao usar variáveis de ambiente.

 **Formato do log** 

O runtime em Java do CloudWatch Synthetics cria logs no CloudWatch para cada execução do canário. Os logs são gravados no formato JSON para facilitar a consulta. Opcionalmente, é possível alterar o formato do log para *TEXT*.
+ *Nome da variável de ambiente*: CW\$1SYNTHETICS\$1LOG\$1FORMAT
+ *Valores com suporte*: JSON e TEXT
+ *Padrão*: JSON

 **Níveis de logs** 
+ *Nome da variável de ambiente*: CW\$1SYNTHETICS\$1LOG\$1LEVEL
+ *Valores com suporte*: TRACE, DEBUG, INFO, WARN, ERROR e FATAL
+ *Padrão*: INFO

Além das variáveis de ambiente mencionadas acima, existe uma variável de ambiente padrão adicionada para o runtime em Java, chamada `AWS_LAMBDA-EXEC_WRAPPER`, que deve ser configurada na sua função com o valor `/opt/synthetics-otel-instrument`. Essa variável de ambiente modifica o comportamento de inicialização da função para telemetria. Caso essa variável de ambiente já exista, assegure-se de que esteja configurada com o valor necessário.

# Gravar um script de canário Node.js usando o runtime do Playwright
<a name="Synthetics_WritingCanary_Nodejs_Playwright"></a>

**Topics**
+ [Empacotar arquivos de canário Node.js para o runtime do Playwright](#Synthetics_canary_Nodejs_Playwright_package)
+ [Alterar um script existente do Playwright para ser usado como um canário do Synthetics](#CloudWatch_Synthetics_canary_edit_Playwright_script)
+ [Configurações do CloudWatch Synthetics](#Synthetics_canary_configure_Playwright_script)

## Empacotar arquivos de canário Node.js para o runtime do Playwright
<a name="Synthetics_canary_Nodejs_Playwright_package"></a>

 O script do canário compreende um arquivo `.js` (sintaxe CommonJS) ou `.mjs` (sintaxe ES) contendo o código do manipulador do Synthetics, em conjunto com quaisquer pacotes e módulos adicionais dos quais o código dependa. Os scripts criados no formato ES (ECMAScript) devem usar .mjs como extensão ou incluir um arquivo package.json com o conjunto de campos “type”: “module”. Ao contrário de outros runtimes, como o Node.js Puppeteer, você não precisa salvar os scripts em uma estrutura de pastas específica. Você pode empacotar os scripts diretamente. Use seu utilitário `zip` preferencial para criar um arquivo `.zip` com o arquivo manipulador na raiz. Se o script do canário depender de pacotes ou módulos adicionais que não estejam inclusos no runtime do Synthetics, é possível adicionar essas dependências ao arquivo `.zip`. Para fazer isso, você pode instalar as bibliotecas necessárias para a função no diretório `node_modules` executando o comando `npm install`. Os comandos de exemplo da CLI a seguir criam um arquivo `.zip` denominado `my_deployment_package.zip` contendo o arquivo `index.js` ou `index.mjs` (manipulador do Synthetics) e suas dependências. No exemplo, você instala as dependências usando o manipulador de pacotes `npm`.

```
~/my_function
├── index.mjs
├── synthetics.json
├── myhelper-util.mjs    
└── node_modules
    ├── mydependency
```

Crie um arquivo `.zip` que contenha o conteúdo da pasta do seu projeto na raiz. Use a opção `r` (recursiva), conforme mostrado no exemplo a seguir, para garantir que `zip` compacte as subpastas.

```
zip -r my_deployment_package.zip .
```

Adicione um arquivo de configuração do Synthetics para configurar o comportamento do CloudWatch Synthetics. Você pode criar um arquivo `synthetics.json` e salvá-lo no mesmo caminho do seu ponto de entrada ou arquivo manipulador.

Opcionalmente, você também pode armazenar o arquivo de ponto de entrada em uma estrutura de pastas de sua escolha. No entanto, certifique-se de que o caminho da pasta esteja especificado no nome do manipulador.

 **Nome do manipulador** 

Defina o ponto de entrada do script do canário (manipulador) como ` myCanaryFilename.functionName` para corresponder ao nome do arquivo do ponto de entrada do script. Opcionalmente, você também pode armazenar o canário em uma pasta separada, como ` myFolder/my_canary_filename.mjs`. Se você armazenar em uma pasta separada, especifique esse caminho no ponto de entrada do script, como ` myFolder/my_canary_filename.functionName`.

## Alterar um script existente do Playwright para ser usado como um canário do Synthetics
<a name="CloudWatch_Synthetics_canary_edit_Playwright_script"></a>

Você pode editar um script existente do Node.js e Playwright para ser usado como canário. Para obter mais informações sobre o Playwright, consulte a documentação da [biblioteca do Playwright](https://playwright.dev/docs/api/class-playwright). 

Você pode usar o script do Playwright a seguir, que está salvo no arquivo ` exampleCanary.mjs`.

```
import { chromium } from 'playwright';
import { expect } from '@playwright/test';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', {timeout: 30000});
await page.screenshot({path: 'example-home.png'});

const title = await page.title();
expect(title).toEqual("Example Domain");
 
await browser.close();
```

Converta o script executando as seguintes etapas:

1. Crie e exporte uma função `handler`. O manipulador é a função de ponto de entrada para o script. Você pode escolher qualquer nome para a função do manipulador, mas a função usada no script deve ser a mesma do manipulador do canário. Se o nome do script for `exampleCanary.mjs`, e o nome da função do manipulador for `myhandler`, o manipulador do canário será denominado `exampleCanary.myhandler`. No exemplo a seguir, o nome da função do manipulador é `handler`.

   ```
   exports.handler = async () => {
     // Your script here
     };
   ```

1. Importe o `Synthetics Playwright module` como uma dependência.

   ```
   import { synthetics } from '@aws/synthetics-playwright';
   ```

1. Inicie um navegador usando a função `Launch` do Synthetics.

   ```
   const browser = await synthetics.launch();
   ```

1. Crie uma página do Playwright usando a função `newPage` do Synthetics.

   ```
   const page = await synthetics.newPage();
   ```

O script agora está pronto para ser executado como um canário do Synthetics. Veja abaixo o script atualizado:

 **Atualizado o script no formato ES6** 

O arquivo de script salvo com uma extensão `.mjs`.

```
import { synthetics } from '@aws/synthetics-playwright';
import { expect } from '@playwright/test';

export const handler = async (event, context) => {
  try {
        // Launch a browser
        const browser = await synthetics.launch();
        
        // Create a new page
        const page = await synthetics.newPage(browser);
        
        // Navigate to a website
        await page.goto('https://www.example.com', {timeout: 30000});
        
        // Take screenshot
        await page.screenshot({ path: '/tmp/example.png' });
        
        // Verify the page title
        const title = await page.title();
        expect(title).toEqual("Example Domain");
    } finally {
        // Ensure browser is closed
        await synthetics.close();
    }
};
```

 **Script atualizado no formato CommonJS** 

O arquivo de script salvo com uma extensão `.js`.

```
const { synthetics } = require('@aws/synthetics-playwright');
const { expect } = require('@playwright/test');

exports.handler = async (event) => {
  try {
    const browser = await synthetics.launch();
    const page = await synthetics.newPage(browser);
    await page.goto('https://www.example.com', {timeout: 30000});
    await page.screenshot({ path: '/tmp/example.png' });
    const title = await page.title();
    expect(title).toEqual("Example Domain");
  } finally {
    await synthetics.close();
  }
};
```

## Configurações do CloudWatch Synthetics
<a name="Synthetics_canary_configure_Playwright_script"></a>

Você pode configurar o comportamento do runtime do Synthetics Playwright fornecendo um arquivo de configuração JSON opcional denominado `synthetics.json`. Esse arquivo deve ser empacotado no mesmo local do arquivo do manipulador. Embora um arquivo de configuração seja opcional, se você não fornecer um arquivo de configuração, ou se não houver uma chave de configuração, o CloudWatch assumirá os padrões.

 **Empacotar o arquivo de configuração** 

Veja abaixo os valores de configuração compatíveis e seus padrões.

```
{
    "step": {
        "screenshotOnStepStart": false,
        "screenshotOnStepSuccess": false,
        "screenshotOnStepFailure": false,
        "stepSuccessMetric": true,
        "stepDurationMetric": true,
        "continueOnStepFailure": true,
        "stepsReport": true
    },
    "report": {
        "includeRequestHeaders": true,
        "includeResponseHeaders": true,
        "includeUrlPassword": false,
        "includeRequestBody": true,
        "includeResponseBody": true,
        "restrictedHeaders": ['x-amz-security-token', 'Authorization'], // Value of these headers is redacted from logs and reports
        "restrictedUrlParameters": ['Session', 'SigninToken'] // Values of these url parameters are redacted from logs and reports
    },
    "logging": {
        "logRequest": false,
        "logResponse": false,
        "logResponseBody": false,
        "logRequestBody": false,
        "logRequestHeaders": false,
        "logResponseHeaders": false
    },
    "httpMetrics": {
        "metric_2xx": true,
        "metric_4xx": true,
        "metric_5xx": true,
        "failedRequestsMetric": true,
        "aggregatedFailedRequestsMetric": true,
        "aggregated2xxMetric": true,
        "aggregated4xxMetric": true,
        "aggregated5xxMetric": true
    },
    "canaryMetrics": {
        "failedCanaryMetric": true,
        "aggregatedFailedCanaryMetric": true
    },
    "userAgent": "",
    "har": true
}
```

 **Configurações das etapas** 
+ `screenshotOnStepStart`: determina se o Synthetics deve obter uma captura de tela antes do início da etapa. O padrão é `true`. 
+ `screenshotOnStepSuccess`: determina se o Synthetics deve obter uma captura de tela após a conclusão de uma etapa. O padrão é `true`. 
+ `screenshotOnStepFailure`: determina se o Synthetics deve obter uma captura de tela após uma etapa falhar. O padrão é `true`. 
+ `continueOnStepFailure`: determina se um script deve continuar mesmo após uma etapa falhar. O padrão é `false`. 
+ `stepSuccessMetric`: determina se a métrica ` SuccessPercent` de uma etapa é emitida. A métrica `SuccessPercent` de uma etapa será `100` para a execução do canário se a etapa tiver êxito, e `0` se a etapa falhar. O padrão é `true`. 
+ `stepDurationMetric`: determina se a métrica `Duration` de uma etapa é emitida. A métrica `Duration` é emitida como a duração, em milissegundos, da execução da etapa. O padrão é `true`.

 **Configurações de relatórios** 

Inclui todos os relatórios gerados pelo CloudWatch Synthetics, como um arquivo HAR e um relatório de etapas do Synthetics. Os campos `restrictedHeaders` e `restrictedUrlParameters` de ocultação de dados sigilosos também se aplicam aos logs gerados pelo Synthetics. 
+ `includeRequestHeaders`: se deve incluir ou não cabeçalhos de solicitação no relatório. O padrão é `false`. 
+ `includeResponseHeaders`: se deve incluir ou não cabeçalhos de resposta no relatório. O padrão é `false`.
+ `includeUrlPassword`: se deve ou não incluir uma senha que apareça no URL. Por padrão, as senhas que aparecem em URLs são ocultadas de logs e relatórios, para evitar a divulgação de dados sigilosos. O padrão é `false` . 
+ `includeRequestBody`: se deve incluir ou não o corpo da solicitação no relatório. O padrão é `false`. 
+ `includeResponseBody`: se deve incluir ou não o corpo da resposta no relatório. O padrão é `false`. 
+ `restrictedHeaders`: uma lista de valores de cabeçalho a serem ignorados, se os cabeçalhos forem incluídos. Isso se aplica aos cabeçalhos de solicitação e de resposta. Por exemplo, você pode ocultar suas credenciais passando `includeRequestHeaders` como true e `restrictedHeaders` como `['Authorization']`. 
+ `restrictedUrlParameters`: uma lista de parâmetros de consulta ou caminho de URL a serem ocultados. Aplica-se a URLs que aparecem em logs, relatórios e erros. O parâmetro faz distinção entre maiúsculas e minúsculas. É possível passar um asterisco (`*`) como um valor para ocultar todos os valores de parâmetros de consulta e caminho de URL. O padrão é uma matriz vazia. 
+ `har`: determina se um arquivo HTTP (HAR) deve ser gerado. O padrão é `true`.

Veja abaixo um exemplo de um arquivo de configurações de relatório.

```
"includeRequestHeaders": true,
"includeResponseHeaders": true,
"includeUrlPassword": false,
"includeRequestBody": true,
"includeResponseBody": true,
"restrictedHeaders": ['x-amz-security-token', 'Authorization'], // Value of these headers is redacted from logs and reports
"restrictedUrlParameters": ['Session', 'SigninToken'] // Values of these URL parameters are redacted from logs and reports
```

 **Configurações de registros em log** 

Aplica-se aos logs gerados pelo CloudWatch Synthetics. Controla o detalhamento dos logs de solicitações e respostas.
+ `logRequest`: se cada solicitação em logs do canário será registrada ou não. Para canaries de interface do usuário, isso registra cada solicitação enviada pelo navegador. O padrão é ` false`. 
+ `logResponse`: se cada resposta em logs do canário será registrada ou não. Para canaries de interface do usuário, registra todas as respostas recebidas pelo navegador. O padrão é ` false`. 
+ `logRequestBody`: se os corpos da solicitação serão registrados ou não junto com as solicitações em logs do canário. Essa configuração se aplicará somente se `logRequest` for true. O padrão é `false`. 
+ `logResponseBody`: se os corpos da resposta serão registrados ou não junto com as solicitações em logs do canário. Essa configuração se aplicará somente se `logResponse` for true. O padrão é `false`. 
+ `logRequestHeaders`: se os cabeçalhos da solicitação serão registrados ou não junto com as solicitações em logs do canário. Essa configuração se aplicará somente se ` logRequest` for true. O padrão é `false`. 
+ `logResponseHeaders`: se os cabeçalhos da resposta serão registrados ou não junto com as respostas em logs do canário. Essa configuração se aplicará somente se ` logResponse` for true. O padrão é `false`. 

 **Configurações de métricas HTTP** 

Configurações de métricas relacionadas à contagem de solicitações de rede com diferentes códigos de status HTTP, emitidos pelo CloudWatch Synthetics para o canário.
+ `metric_2xx`: se deve ou não emitir a métrica `2xx` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `metric_4xx`: se deve ou não emitir a métrica `4xx` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `metric_5xx`: se deve ou não emitir a métrica `5xx` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `failedRequestsMetric`: se deve ou não emitir a métrica ` failedRequests` (com a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregatedFailedRequestsMetric`: se deve ou não emitir a métrica ` failedRequests` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregated2xxMetric`: se deve ou não emitir a métrica `2xx` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregated4xxMetric`: se deve ou não emitir a métrica `4xx` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregated5xxMetric`: se deve ou não emitir a métrica `5xx` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 

 **Configurações de métricas do canário** 

Configurações de outras métricas emitidas pelo CloudWatch Synthetics.
+ `failedCanaryMetric`: se deve ou não emitir a métrica `Failed` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `aggregatedFailedCanaryMetric`: se deve ou não emitir a métrica ` Failed` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 

 **Outras configurações** 
+ `userAgent`: uma string para anexar ao agente do usuário. O agente do usuário é uma string incluída no cabeçalho da solicitação que identifica seu navegador nos sites que você visita ao usar o navegador sem cabeçalho. O CloudWatch Synthetics adiciona automaticamente `CloudWatchSynthetics/canary-arn to the user agent`. A configuração especificada é anexada ao agente de usuário gerado. O valor do agente de usuário padrão a ser anexado é uma string vazia (`""`).

### Variáveis de ambiente do CloudWatch Synthetics
<a name="Synthetics_canary_Nodejs_Playwright_script"></a>

Configure o formato e o nível do registro em log usando variáveis de ambiente.

 **Formato do log** 

O runtime do CloudWatch Synthetics Playwright cria logs do CloudWatch para cada execução de canário. Os logs são gravados no formato JSON para facilitar a consulta. Opcionalmente, você pode alterar o formato do log para `TEXT`.
+ `Environment variable name`: CW\$1SYNTHETICS\$1LOG\$1FORMAT 
+ `Supported values`: JSON, TEXT 
+ `Default`: JSON 

 **Níveis de logs** 

Embora a habilitação do modo `Debug` aumente o detalhamento, ele pode ser útil para solucionar problemas.
+ `Environment variable name`: CW\$1SYNTHETICS\$1LOG\$1LEVEL
+ `Supported values`: TRACE, DEBUG, INFO, WARN, ERROR, FATAL 
+ `Default`: INFO

# Gravar um script de canário Node.js usando o runtime do Puppeteer
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Nodejs_Pup"></a>

**Topics**
+ [Criar um canário do CloudWatch Synthetics do zero](#CloudWatch_Synthetics_Canaries_write_from_scratch)
+ [Empacotamento dos arquivos do canário para Node.js](#CloudWatch_Synthetics_Canaries_package)
+ [Alterar um script existente do Puppeteer para ser usado como canário do Synthetics](#CloudWatch_Synthetics_Canaries_modify_puppeteer_script)
+ [Variáveis de ambiente](#CloudWatch_Synthetics_Environment_Variables)
+ [Integrar o canário a outros produtos da AWS](#CloudWatch_Synthetics_Canaries_AWS_integrate)
+ [Forçar seu canário a usar um endereço IP estático](#CloudWatch_Synthetics_Canaries_staticIP)

## Criar um canário do CloudWatch Synthetics do zero
<a name="CloudWatch_Synthetics_Canaries_write_from_scratch"></a>

Veja a seguir um exemplo de script do canário mínimo do Synthetics. Esse script é executado com êxito e retorna uma string. Para ver como é um canário com falha, altere `let fail = false;` para `let fail = true;`. 

É necessário definir uma função de ponto de entrada para o script do canário. Para ver como os arquivos são carregados no local do Amazon S3 especificado como o `ArtifactS3Location` do canário, crie esses arquivos na pasta `/tmp`. Todos os artefatos do canário devem ser armazenados em `/tmp`, pois é o único diretório gravável. Certifique-se de que o caminho da captura de tela esteja definido como `/tmp` para todas as capturas de tela ou outros arquivos criados pelo script. O Synthetics faz upload automático dos arquivos em ` /tmp` para um bucket do S3.

```
/tmp/<name>
```

Após a execução do script, o status de sucesso/falha e as métricas de duração são publicados no CloudWatch, e os arquivos em `/tmp` são carregados em um bucket do S3.

```
const basicCustomEntryPoint = async function () {

    // Insert your code here

    // Perform multi-step pass/fail check

    // Log decisions made and results to /tmp

    // Be sure to wait for all your code paths to complete 
    // before returning control back to Synthetics.
    // In that way, your canary will not finish and report success
    // before your code has finished executing

    // Throw to fail, return to succeed
    let fail = false;
    if (fail) {
        throw "Failed basicCanary check.";
    }

    return "Successfully completed basicCanary checks.";
};

exports.handler = async () => {
    return await basicCustomEntryPoint();
};
```

Depois, expandiremos o script para usar o registro em log do Synthetics e fazer uma chamada usando o AWS SDK. Para fins de demonstração, esse script criará um cliente do Amazon DynamoDB e fará uma chamada para a API listTables do DynamoDB. Ele registra a resposta à solicitação e os logs são aprovados ou falham dependendo se a solicitação foi bem-sucedida.

```
const log = require('@aws/synthetics-logger');
const AWS = require('aws-sdk');
// Require any dependencies that your script needs
// Bundle additional files and dependencies into a .zip file with folder structure
// nodejs/node_modules/additional files and folders

const basicCustomEntryPoint = async function () {

    log.info("Starting DynamoDB:listTables canary.");
    
    let dynamodb = new AWS.DynamoDB();
    var params = {};
    let request = await dynamodb.listTables(params);
    try {
        let response = await request.promise();
        log.info("listTables response: " + JSON.stringify(response));
    } catch (err) {
        log.error("listTables error: " + JSON.stringify(err), err.stack);
        throw err;
    }

    return "Successfully completed DynamoDB:listTables canary.";
};

exports.handler = async () => {
    return await basicCustomEntryPoint();
};
```

## Empacotamento dos arquivos do canário para Node.js
<a name="CloudWatch_Synthetics_Canaries_package"></a>

 **Para syn-nodejs-puppeteer-11.0 e superior** 

 A estrutura de empacotamento mais antiga (para syn-nodejs-puppeteer-10.0 e versões anteriores) ainda tem suporte em versões mais recentes.

Crie um script usando uma das seguintes opções:
+ arquivo .js (sintaxe CommonJS)
+ arquivo. mjs (sintaxe dos módulos ES)

Para módulos ES, use uma destas opções:
+ arquivo .js (sintaxe CommonJS)
+ arquivo. mjs (sintaxe dos módulos ES)

A estrutura do pacote é definida abaixo:
+ Arquivo manipulador de nível raiz (index.js/index.mjs)
+ Arquivo de configuração opcional (synthetics.json)
+ Dependências adicionais em node\$1modules (se necessário)

Exemplo de estrutura de empacotamento:

```
  my_function/
├── index.mjs
├── synthetics.json
├── helper-utils.mjs
└── node_modules/
    └── dependencies
```

Para empacotar, siga as etapas abaixo:

1. Instale dependências (se houver).

   ```
   npm install
   ```

1. Crie um pacote .zip.

   ```
   zip -r my_deployment_package.zip
   ```

 **Para syn-nodejs-puppeteer-11.0 e inferior** 

A seguinte estrutura é necessária ao usar o Amazon S3:

```
  nodejs/
└── node_modules/
    └── myCanaryFilename.js
```

 **Para adicionar um suporte opcional para subpastas no syn-nodejs-puppeteer-3.4\$1:** 

```
nodejs/
└── node_modules/
    └── myFolder/
        └── myCanaryFilename.js
```

**nota**  
O caminho do manipulador na configuração deve corresponder ao local do arquivo.

 **Nome do manipulador** 

Defina o ponto de entrada do script do canário (manipulador) como ` myCanaryFilename.functionName` para corresponder ao nome do arquivo do ponto de entrada do script. Se estiver usando um runtime anterior a `syn-nodejs-puppeteer-3.4`, então `functionName`deverá ser `handler`. Se estiver usando ` syn-nodejs-puppeteer-3.4` ou posterior, você poderá escolher qualquer nome de função como manipulador. Se estiver usando `syn-nodejs-puppeteer-3.4` ou posterior, você também poderá armazenar o canário em uma pasta separada, como ` nodejs/node_modules/myFolder/my_canary_filename`. Se você armazenar em uma pasta separada, especifique esse caminho no ponto de entrada do script, como ` myFolder/my_canary_filename.functionName`.

## Alterar um script existente do Puppeteer para ser usado como canário do Synthetics
<a name="CloudWatch_Synthetics_Canaries_modify_puppeteer_script"></a>

Esta seção explica como modificar scripts do Puppeteer para executá-los como scripts do canário do Synthetics. Para obter mais informações sobre o Puppeteer, consulte [API do Puppeteer v1.14.0](https://github.com/puppeteer/puppeteer/blob/v1.14.0/docs/api.md). 

Vamos começar com este exemplo de script do Puppeteer:

```
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();
```

As etapas de conversão são as seguintes:
+ Crie e exporte uma função `handler`. O manipulador é a função de ponto de entrada para o script. Se estiver usando um runtime anterior a ` syn-nodejs-puppeteer-3.4`, a função do manipulador deverá ser nomeada `handler`. Se estiver usando `syn-nodejs-puppeteer-3.4` ou posterior, a função poderá ter qualquer nome, mas deverá ser o mesmo nome usado no script. Além disso, se você estiver usando `syn-nodejs-puppeteer-3.4` ou posterior, poderá armazenar scripts em qualquer pasta e especificar essa pasta como parte do nome do manipulador.

  ```
  const basicPuppeteerExample = async function () {};
  
  exports.handler = async () => {
      return await basicPuppeteerExample();
  };
  ```
+ Use a dependência `Synthetics`.

  ```
  var synthetics = require('@aws/synthetics-puppeteer');
  ```
+ Use a função `Synthetics.getPage` para obter um objeto `Page` do Puppeteer.

  ```
  const page = await synthetics.getPage();
  ```

  O objeto de página retornado pela função Synthetics.getPage tem os eventos **page.on** `request`, `response` e ` requestfailed` instrumentados para registro em log. O Synthetics também define a geração de arquivos HAR para solicitações e respostas na página e adiciona o ARN do canário aos cabeçalhos do atendente do usuário de solicitações de saída na página.

O script agora está pronto para ser executado como um canário do Synthetics. Veja a seguir o script atualizado:

```
var synthetics = require('@aws/synthetics-puppeteer');  // Synthetics dependency

const basicPuppeteerExample = async function () {
    const page = await synthetics.getPage(); // Get instrumented page from Synthetics
    await page.goto('https://example.com');
    await page.screenshot({path: '/tmp/example.png'}); // Write screenshot to /tmp folder
};

exports.handler = async () => {  // Exported handler function 
    return await basicPuppeteerExample();
};
```

## Variáveis de ambiente
<a name="CloudWatch_Synthetics_Environment_Variables"></a>

É possível usar variáveis de ambiente ao criar canaries. Isso permite escrever um único script o canário e usar esse script com valores diferentes para criar rapidamente vários canários que tenham uma tarefa semelhante.

Por exemplo, suponhamos que sua organização tenha endpoints como `prod`, ` dev` e `pre-release` para os diferentes estágios do desenvolvimento de seu software, e você necessite criar canaries para testar cada um desses endpoints. É possível escrever um único script do canário que testa seu software e especificar valores diferentes para a variável de ambiente do endpoint ao criar cada um dos três canários. Em seguida, ao criar um canário, especifique o script e os valores a serem usados para as variáveis de ambiente.

Os nomes das variáveis de ambiente podem conter letras, números e o caractere de sublinhado. Devem começar com uma letra e ter pelo menos dois caracteres. O tamanho total das variáveis de ambiente não pode exceder 4 KB. Você não pode especificar nenhuma variável de ambiente reservada do Lambda como os nomes de suas variáveis de ambiente. Para obter mais informações sobre variáveis de ambiente reservadas, consulte [ Variáveis de ambiente do runtime](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime).

**Importante**  
As chaves e os valores das variáveis de ambiente são criptografados em repouso usando chaves do AWS KMS de propriedade da AWS. No entanto, as variáveis de ambiente não são criptografadas no lado do cliente. Não armazene informações sigilosas neles.

O exemplo de script a seguir usa duas variáveis de ambiente. Esse script é para um canário que verifica se uma página da Web está disponível. Utiliza variáveis de ambiente para parametrizar tanto a URL que ele verifica como o nível de logs do CloudWatch Synthetics que ele usa. 

A função a seguir define `LogLevel` para o valor da variável de ambiente ` LOG_LEVEL`.

```
 synthetics.setLogLevel(process.env.LOG_LEVEL);
```

Essa função define `URL` para o valor da variável de ambiente `URL`.

```
const URL = process.env.URL;
```

Este é o script completo. Ao criar um canário usando esse script, especifique os valores a serem usados para as variáveis de ambiente `LOG_LEVEL` e `URL`.

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');

const pageLoadEnvironmentVariable = async function () {

    // Setting the log level (0-3)
    synthetics.setLogLevel(process.env.LOG_LEVEL);
    // INSERT URL here
    const URL = process.env.URL;

    let page = await synthetics.getPage();
    //You can customize the wait condition here. For instance,
    //using 'networkidle2' may be less restrictive.
    const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000});
    if (!response) {
        throw "Failed to load page!";
    }
    //Wait for page to render.
    //Increase or decrease wait time based on endpoint being monitored.
    await page.waitFor(15000);
    await synthetics.takeScreenshot('loaded', 'loaded');
    let pageTitle = await page.title();
    log.info('Page title: ' + pageTitle);
    log.debug('Environment variable:' + process.env.URL);

    //If the response status code is not a 2xx success code
    if (response.status() < 200 || response.status() > 299) {
        throw "Failed to load page!";
    }
};

exports.handler = async () => {
    return await pageLoadEnvironmentVariable();
};
```

### Aprovar variáveis de ambiente para seu script
<a name="CloudWatch_Synthetics_Canaries_pass_variables"></a>

Para transmitir variáveis de ambiente para o script ao criar um canário no console, especifique as chaves e os valores das variáveis de ambiente na seção **Environment variables** (Variáveis de ambiente) no console. Para obter mais informações, consulte [Criar um canário](CloudWatch_Synthetics_Canaries_Create.md).

Para transmitir variáveis de ambiente pela API ou pela AWS CLI, use o parâmetro ` EnvironmentVariables` na seção `RunConfig`. O exemplo a seguir é um comando AWS CLI que cria um canário que usa duas variáveis de ambiente com chaves de `Environment` e `Region`.

```
aws synthetics create-canary --cli-input-json '{
   "Name":"nameofCanary",
   "ExecutionRoleArn":"roleArn",
   "ArtifactS3Location":"s3://amzn-s3-demo-bucket-123456789012-us-west-2",
   "Schedule":{
      "Expression":"rate(0 minute)",
      "DurationInSeconds":604800
   },
   "Code":{
      "S3Bucket": "canarycreation",
      "S3Key": "cwsyn-mycanaryheartbeat-12345678-d1bd-1234-abcd-123456789012-12345678-6a1f-47c3-b291-123456789012.zip",
      "Handler":"pageLoadBlueprint.handler"
   },
   "RunConfig": {
      "TimeoutInSeconds":60,
      "EnvironmentVariables": {
         "Environment":"Production",
         "Region": "us-west-1"
      }
   },
   "SuccessRetentionPeriodInDays":13,
   "FailureRetentionPeriodInDays":13,
   "RuntimeVersion":"syn-nodejs-2.0"
}'
```

## Integrar o canário a outros produtos da AWS
<a name="CloudWatch_Synthetics_Canaries_AWS_integrate"></a>

Todos os canaries podem usar a biblioteca do AWS SDK. É possível usar essa biblioteca ao escrever o canário de forma a integrá-lo a outros serviços da AWS.

Para fazer isso, é necessário adicionar o código a seguir ao canário. Para estes exemplos, o AWS Secrets Manager é usado como o serviço ao qual o canário está se integrando.
+ Importe o AWS SDK.

  ```
  const AWS = require('aws-sdk');
  ```
+ Crie um cliente para o serviço da AWS ao qual você está realizando a integração.

  ```
  const secretsManager = new AWS.SecretsManager();
  ```
+ Use o cliente para fazer chamadas de API para esse serviço.

  ```
  var params = {
    SecretId: secretName
  };
  return await secretsManager.getSecretValue(params).promise();
  ```

O trecho de código de script do canário a seguir demonstra um exemplo de integração ao Secrets Manager com mais detalhes.

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');
 
const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager();
 
const getSecrets = async (secretName) => {
    var params = {
        SecretId: secretName
    };
    return await secretsManager.getSecretValue(params).promise();
}
 
const secretsExample = async function () {
    let URL = "<URL>";
    let page = await synthetics.getPage();
    
    log.info(`Navigating to URL: ${URL}`);
    const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000});
    
    // Fetch secrets
    let secrets = await getSecrets("secretname")
   
    /**
    * Use secrets to login. 
    *
    * Assuming secrets are stored in a JSON format like:
    * {
    *   "username": "<USERNAME>",
    *   "password": "<PASSWORD>"
    * }
    **/
    let secretsObj = JSON.parse(secrets.SecretString);
    await synthetics.executeStep('login', async function () {
        await page.type(">USERNAME-INPUT-SELECTOR<", secretsObj.username);
        await page.type(">PASSWORD-INPUT-SELECTOR<", secretsObj.password);
        
        await Promise.all([
          page.waitForNavigation({ timeout: 30000 }),
          await page.click(">SUBMIT-BUTTON-SELECTOR<")
        ]);
    });
   
    // Verify login was successful
    await synthetics.executeStep('verify', async function () {
        await page.waitForXPath(">SELECTOR<", { timeout: 30000 });
    });
};

exports.handler = async () => {
    return await secretsExample();
};
```

## Forçar seu canário a usar um endereço IP estático
<a name="CloudWatch_Synthetics_Canaries_staticIP"></a>

É possível configurar um canário para que ele use um endereço IP estático.

**Para forçar um canário a usar um endereço IP estático**

1. Crie uma nova VPC. Para obter mais informações, consulte [Using DNS with Your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html).

1. Crie um novo gateway da Internet. Para obter mais informações, consulte [Adicionar um gateway da Internet à VPC](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html#working-with-igw).

1. Crie uma sub-rede pública dentro de sua nova VPC.

1. Adicione uma nova tabela de rotas à VPC.

1. Adicione uma rota na nova tabela de rotas, que vai de `0.0.0.0/0` ao gateway da Internet.

1. Associe a nova tabela de rotas à sub-rede pública.

1. Crie um endereço de IP elástico. Para obter mais informações, consulte [Endereços de IP elásticos](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html).

1. Crie um novo gateway NAT e atribua-o à sub-rede pública e ao endereço de IP elástico.

1. Crie uma sub-rede privada dentro da VPC.

1. Adiciona uma rota à tabela de rotas padrão da VPC, que vai de `0.0.0.0/0` ao gateway NAT

1. Crie um canário. 

# Escrever um script o canário do Python
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Python"></a>

Esse script é executado com êxito e retorna uma string. Para ver como é um canário com falha, altere fail = False to fail = True

```
def basic_custom_script():
    # Insert your code here
    # Perform multi-step pass/fail check
    # Log decisions made and results to /tmp
    # Be sure to wait for all your code paths to complete 
    # before returning control back to Synthetics.
    # In that way, your canary will not finish and report success
    # before your code has finished executing
    fail = False
    if fail:
        raise Exception("Failed basicCanary check.")
    return "Successfully completed basicCanary checks."
def handler(event, context):
    return basic_custom_script()
```

## Empacotamento dos arquivos do canário para Python
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Python_package"></a>

Se você tiver mais de um arquivo .py ou se o script tiver uma dependência, será possível agrupá-los em um único arquivo ZIP. Se você usar o runtime `syn-python-selenium-1.1`, o arquivo ZIP deverá conter o arquivo .py canário principal dentro de uma pasta `python`, como `python/my_canary_filename.py`. Se você usar ` syn-python-selenium-1.1` ou posterior, poderá usar uma pasta diferente, como `python/myFolder/my_canary_filename.py`.

Este arquivo ZIP deverá conter todas as pastas e arquivos necessários, mas os outros arquivos não precisam estar na pasta `python`.

Defina o ponto de entrada do script o canário como ` my_canary_filename.functionName` para corresponder ao nome do arquivo e ao nome da função do ponto de entrada do script. Se você estiver usando o runtime `syn-python-selenium-1.0`, `functionName` deverá ser `handler`. Se estiver usando ` syn-python-selenium-1.1` ou posterior, essa restrição de nome do manipulador não se aplicará, e você também poderá, opcionalmente, armazenar o canário em uma pasta separada, como ` python/myFolder/my_canary_filename.py`. Se você armazenar em uma pasta separada, especifique esse caminho no ponto de entrada do script, como ` myFolder/my_canary_filename.functionName`. 

## Alterar um script existente do Selenium para ser usado como canário do Synthetics
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Python_Selenium"></a>

É possível modificar rapidamente um script existente para Python e Selenium a ser usado como canário. Para obter mais informações sobre o Selenium, consulte [www.selenium.dev/](https://www.selenium.dev/).

Neste exemplo, começaremos com o seguinte script Selenium:

```
from selenium import webdriver

def basic_selenium_script():
    browser = webdriver.Chrome()
    browser.get('https://example.com')
    browser.save_screenshot('loaded.png')

basic_selenium_script()
```

As etapas de conversão são as seguintes.

**Para converter um script Selenium para ser usado como canário**

1. Altere a instrução `import` para usar o Selenium a partir do módulo ` aws_synthetics`:

   ```
   from aws_synthetics.selenium import synthetics_webdriver as webdriver
   ```

   O módulo Selenium a partir de `aws_synthetics` garante que o canário poderá emitir métricas e logs, gerar um arquivo HAR e trabalhar com outros recursos do CloudWatch Synthetics.

1. Crie uma função de manipulador e chame seu método Selenium. O manipulador é a função de ponto de entrada para o script.

   Se estiver usando `syn-python-selenium-1.0`, a função do manipulador deverá ser nomeada `handler`. Se estiver usando `syn-python-selenium-1.1` ou posterior, a função poderá ter qualquer nome, mas deverá ser o mesmo nome usado no script. Além disso, se você estiver usando `syn-python-selenium-1.1` ou posterior, poderá armazenar scripts em qualquer pasta e especificar essa pasta como parte do nome do manipulador.

   ```
   def handler(event, context):
       basic_selenium_script()
   ```

Agora, o script é atualizado para ser um canário do CloudWatch Synthetics. Veja a seguir o script atualizado:

O `webdriver` é uma instância da classe [SyntheticsWebDriver](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library_Python.html#CloudWatch_Synthetics_Library_Python_SyntheticsWebDriver) e o navegador retornado por `webdriver.Chrome()` é uma instância de [SyntheticsBrowser](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library_Python.html#CloudWatch_Synthetics_Library_Python_SyntheticsBrowser).

```
from aws_synthetics.selenium import synthetics_webdriver as webdriver

def basic_selenium_script():
    browser = webdriver.Chrome()
    browser.get('https://example.com')
    browser.save_screenshot('loaded.png')

def handler(event, context):
    basic_selenium_script()
```

## Como alterar um script existente do Puppeteer Synthetics para autenticar certificados não padrão
<a name="Canaries_Non-Standard_Certificates"></a>

Um caso de uso importante dos canários Synthetics é monitorar seus próprios endpoints. Se você quiser monitorar um endpoint que não esteja pronto para tráfego externo, esse monitoramento poderá, às vezes, significar que você não tenha um certificado adequado assinado por uma autoridade de certificação terceirizada confiável.

Duas soluções possíveis para esse cenário são as seguintes:
+ Para autenticar um certificado de cliente, consulte [Como validar a autenticação usando o Amazon CloudWatch Synthetics – Parte 2](https://aws.amazon.com/blogs/mt/how-to-validate-authentication-using-amazon-cloudwatch-synthetics-part-2/).
+ Para autenticar um certificado autoassinado, consulte [Como validar a autenticação com certificados autoassinados no Amazon CloudWatch Synthetics](https://aws.amazon.com/blogs/mt/how-to-validate-authentication-with-self-signed-certificates-in-amazon-cloudwatch-synthetics/)

Você não está limitado a essas duas opções ao usar os canários CloudWatch Synthetics. Você pode estender esses recursos e adicionar sua lógica de negócios estendendo o código canário.

**nota**  
Os canários Synthetics executados em runtimes do Python têm o sinalizador ` --ignore-certificate-errors` habilitado de forma inata, portanto, esses canários não devem ter problemas para acessar sites com configurações de certificado não padrão.

# Escrever uma configuração JSON para o esquema de múltiplas verificações do Node.js
<a name="CloudWatch_Synthetics_WritingCanary_Multichecks"></a>

O esquema de múltiplas verificações do Node.js permite criar canários que realizam múltiplas verificações de validação em uma única execução de canário. Esse esquema é útil quando você deseja testar vários endpoints, validar diferentes aspectos da aplicação ou realizar uma série de verificações relacionadas em sequência. 

**Topics**
+ [Estrutura da configuração primária](#root-configuration-structure)
+ [Configurações globais](#global-settings)
+ [Gerenciamento de variáveis e dados](#variables-data-management)
+ [Definições de etapas](#step-definitions)
+ [Tipos de verificação](#check-types)
+ [Métodos de autenticação](#authentication-methods)
+ [Asserções e validação](#assertions-validation)
+ [Extração de dados](#data-extraction)

## Estrutura da configuração primária
<a name="root-configuration-structure"></a>

A configuração primária define a estrutura geral do canário do esquema de API avançado.


**Propriedades do esquema**  

| Propriedade | Tipo | Obrigatório | Descrição | 
| --- | --- | --- | --- | 
|  globalSettings  | Objeto | Não | Configurações padrão aplicadas a todas as etapas | 
|  variables  | Objeto | Não | Valores reutilizáveis em todas as etapas (máx. 10) | 
|  steps  | Objeto |  Sim  | Conjunto de etapas de monitoramento (1 a 10 etapas) | 

 **Exemplo** 

```
{
  "globalSettings": {
    "stepTimeout": 30000,
    "userAgent": "CloudWatch-Synthetics-Advanced/1.0"
  },
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiVersion": "v1"
  },
  "steps": {
    "1": {
      "stepName": "healthCheck",
      "checkerType": "HTTP",
      "url": "${baseUrl}/health",
      "httpMethod": "GET"
    }
  }
}
```

 **Regras de validação** 
+ Deve conter pelo menos uma etapa
+ Máximo permitido de 10 etapas
+ Não são permitidas outras propriedades além de `globalSettings`, ` variables` e `steps`

## Configurações globais
<a name="global-settings"></a>

As definições globais fornecem configurações padrão que se aplicam a todas as etapas, a menos que sejam substituídas no nível da etapa.

 **Propriedades** 


**Propriedades das configurações globais**  

| Propriedade | Tipo | Padrão | Intervalo | Descrição | 
| --- | --- | --- | --- | --- | 
|  stepTimeout  | integer | 30000 | 5.000 a 300.000 | Tempo limite padrão para todas as etapas (milissegundos) | 

 **Exemplo** 

```
{
  "globalSettings": {
    "stepTimeout": 60000,
            
  }
}
```

## Gerenciamento de variáveis e dados
<a name="variables-data-management"></a>

As variáveis permitem definir valores reutilizáveis que podem ser referenciados em toda a configuração usando a sintaxe `${variableName}`.

 **Propriedades variáveis** 


| Propriedade | Tipo | Descrição | 
| --- | --- | --- | 
| Nomes das variáveis | string | Deve corresponder ao padrão: . ^[a-zA-Z][a-zA-Z0-9\$1]\$1\$1 | 
| Valores das variáveis | string | Qualquer valor de string | 

 **Limitações** 
+ Máximo de 10 variáveis por configuração
+ Os nomes das variáveis devem começar com uma letra
+ Os nomes das variáveis podem apenas conter letras, números e sublinhados
+ Tamanho máximo não especificado no esquema

 **Exemplo** 

```
{
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiKey": "${AWS_SECRET:my-api-key}",
    "timeout": "30000",
    "userEmail": "test@example.com"
  }
}
```

 **Uso da configuração** 

```
{
  "steps": {
    "1": {
      "url": "${baseUrl}/users",
      "timeout": "${timeout}",
      "headers": {
        "Authorization": "Bearer ${apiKey}"
      }
    }
  }
}
```

## Definições de etapas
<a name="step-definitions"></a>

As etapas definem operações de monitoramento individuais. Cada etapa é numerada de 1 a 10 e contém um tipo específico de verificação.

 *Propriedades das etapas comuns* 


| Propriedade | Tipo | Obrigatório | Descrição | 
| --- | --- | --- | --- | 
|  stepName  | string |  Sim  | Identificador exclusivo da etapa | 
|  checkerType  | string |  Sim  | Tipo de verificação: HTTP, DNS, SSL,  TCP | 
|  extractors  | array | Não | Configuração de extração de dados | 

 *Validação de nome de etapa* 
+ Padrão: ^[a-zA-Z][a-zA-Z0-9\$1-]\$1\$1
+ Tamanho máximo: 64 caracteres
+ Deve começar com uma letra

 *Numeração das etapas* 
+ As etapas são numeradas como chaves de string: “1”, “2”,..., “10”
+ Padrão: ^([1-9]\$110)\$1
+ Mínimo obrigatório de 1 etapa
+ Máximo permitido de 10 etapas

 *Exemplo* 

```
{
  "steps": {
    "1": {
      "stepName": "loginAPI",
      "checkerType": "HTTP",
      "url": "https://api.example.com/login",
      "httpMethod": "POST"
    },
    "2": {
      "stepName": "dnsCheck",
      "checkerType": "DNS",
      "domain": "example.com"
    }
  }
}
```

## Tipos de verificação
<a name="check-types"></a>

### Verificações HTTP
<a name="http-types"></a>

Monitore endpoints e APIs Web com validação abrangente de solicitações e respostas.

 **Propriedades necessárias** 


| Propriedade | Tipo | Descrição | 
| --- | --- | --- | 
|  url  | string | URL de destino (deve ser um formato de URI válido) | 
|  httpMethod  | string | Método HTTP: GET, POST, PUT,  PATCH, DELETE, HEAD, OPTIONS | 

 **Propriedades opcionais** 


| Propriedade | Tipo | Padrão | Intervalo | Descrição | 
| --- | --- | --- | --- | --- | 
|  timeout  | integer | 30000 | 5.000 a 300.000 | Tempo limite (milissegundos) | 
|  waitTime  | integer | 0 | 0-60 | Demora antes da solicitação (segundos) | 
|  headers  | objeto | - | - | Cabeçalhos HTTP personalizados | 
|  body  | string | - | - | Corpo da solicitação para operações POST/PUT | 
|  authentication  | objeto | - | - | Configuração da autenticação | 
|  assertions  | array | - | - | Regras de validação de resposta | 

 **Exemplo** 

```
{
  "stepName": "createUser",
  "checkerType": "HTTP",
  "url": "https://api.example.com/users",
  "httpMethod": "POST",
  "timeout": 15000,
  "headers": {
    "Content-Type": "application/json",
    "X-API-Version": "v1"
  },
  "body": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}",
  "authentication": {
    "type": "API_KEY",
    "apiKey": "${AWS_SECRET:api-credentials}",
    "headerName": "X-API-Key"
  },
  "assertions": [
    {
      "type": "STATUS_CODE",
      "operator": "EQUALS",
      "value": 201
    }
  ]
}
```

### Verificações do DNS
<a name="dns-types"></a>

Valide a resolução do DNS e registre as informações.

 **Propriedades necessárias** 


| Propriedade | Tipo | Descrição | 
| --- | --- | --- | 
|  domain  | string | Nome de domínio a ser consultado (formato de nome de host) | 

 **Propriedades opcionais** 


| Propriedade | Tipo | Padrão | Descrição | 
| --- | --- | --- | --- | 
|  recordType  | string | “A” | Tipo de registro do DNS: A, CNAME, MX,  TXT, NS | 
|  nameserver  | string | - | Servidor do DNS específico a ser consultado | 
|  timeout  | integer | 30000 | Tempo limite de consulta (5.000 a 300.000 ms) | 
|  port  | integer | 53 | Porta do servidor DNS (1 a 65535) | 
|  protocol  | string | “UDP” | Protocolo: UDP ou TCP | 
|  assertions  | array | - | Regras de validação de resposta do DNS | 

 **Exemplo** 

```
{
  "stepName": "dnsResolution",
  "checkerType": "DNS",
  "domain": "example.com",
  "recordType": "A",
  "nameserver": "8.8.8.8",
  "timeout": 10000,
  "assertions": [
    {
      "type": "RECORD_VALUE",
      "operator": "CONTAINS",
      "value": "192.168"
    }
  ]
}
```

### Verificações SSL
<a name="ssl-types"></a>

Monitore a integridade e a configuração dos certificados SSL.

 **Propriedades necessárias** 


| Propriedade | Tipo | Descrição | 
| --- | --- | --- | 
|  hostname  | string | Nome do host de destino (formato do nome do host) | 

 **Propriedades opcionais** 


| Propriedade | Tipo | Padrão | Descrição | 
| --- | --- | --- | --- | 
|  port  | integer | 443 | Porta SSL (1 a 65.535) | 
|  timeout  | integer | 30000 | Tempo limite de conexão (5.000 a 300.000 ms) | 
|  sni  | booliano | TRUE | Indicação de nome do servidor | 
|  verifyHostname  | booliano | TRUE | Verificação de nome do servidor | 
|  allowSelfSigned  | booleano | FALSE | Aceitar certificados autoassinados | 
|  assertions  | array | - | Regras de validação de certificados | 

 **Exemplo** 

```
{
  "stepName": "sslCertCheck",
  "checkerType": "SSL",
  "hostname": "secure.example.com",
  "port": 443,
  "sni": true,
  "verifyHostname": true,
  "assertions": [
    {
      "type": "CERTIFICATE_EXPIRY",
      "operator": "GREATER_THAN",
      "value": 30,
      "unit": "DAYS"
    }
  ]
}
```

### Verificações TCP
<a name="tcp-types"></a>

Teste a conectividade e a validação de resposta da porta TCP.

 **Propriedades necessárias** 


| Propriedade | Tipo | Descrição | 
| --- | --- | --- | 
|  hostname  | string | Nome do host de destino (formato do nome do host) | 
|  port  | integer | Porta de destino (1 a 65.535) | 

 **Propriedades opcionais** 


| Propriedade | Tipo | Padrão | Descrição | 
| --- | --- | --- | --- | 
|  timeout  | integer | 30000 | Tempo limite em geral (5.000 a 300.000 ms) | 
|  connectionTimeout  | integer | 3000 | Tempo limite de conexão (5.000 a 300.000 ms) | 
|  readTimeout  | integer | 2000 | Tempo limite de leitura de dados (5.000 a 300.000 ms) | 
|  sendData  | string | - | Dados a serem enviados após a conexão | 
|  expectedResponse  | string | - | Dados de resposta esperados | 
|  encoding  | string | “UTF-8” | Codificação de dados: UTF-8, ASCII, HEX | 
|  assertions  | array | - | validação de conexão e resposta | 

 **Exemplo** 

```
{
  "stepName": "databaseConnection",
  "checkerType": "TCP",
  "hostname": "db.example.com",
  "port": 3306,
  "connectionTimeout": 5000,
  "sendData": "SELECT 1",
  "expectedResponse": "1",
  "assertions": [
    {
      "type": "CONNECTION_SUCCESSFUL",
      "value": true
    }
  ]
}
```

## Métodos de autenticação
<a name="authentication-methods"></a>

 **Sem autenticação** 

```
{
  "type": "NONE"
}
```

 **Autenticação básica** 


| Propriedade | Tipo | Obrigatório | Descrição | 
| --- | --- | --- | --- | 
|  type  | string |  Sim  | Deve ser "BASIC" | 
|  username  | string |  Sim  | Nome de usuário para autenticação | 
|  password  | string |  Sim  | Senha para autenticação | 

 **Exemplo** 

```
{
  "type": "BASIC",
  "username": "admin",
  "password": "${AWS_SECRET:basic-auth:password}"
}
```

 **Autenticação de chave de API** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "API\$1KEY" | 
|  apiKey  | string |  Sim  | - | Valor da chave de API | 
|  headerName  | string | Não | “X-API-Key” | Nome de cabeçalho para chave de API | 

 **Exemplo** 

```
{
  "type": "API_KEY",
  "apiKey": "${AWS_SECRET:api-credentials}",
  "headerName": "Authorization"
}
```

 **Credenciais de cliente OAuth** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "OAUTH\$1CLIENT\$1CREDENTIALS" | 
|  tokenUrl  | string |  Sim  | - | URL do endpoint do token OAuth | 
|  clientId  | string |  Sim  | - | ID do cliente OAuth | 
|  clientSecret  | string |  Sim  | - | Segredo do cliente OAuth | 
|  scope  | string | Não | - | Escopo do OAuth | 
|  audience  | string | Não | - | Público do OAuth | 
|  resource  | string | Não | - | Recurso do OAuth | 
|  tokenApiAuth  | array | Não | - | Métodos de autenticação de API de token: BASIC\$1AUTH\$1HEADER, REQUEST\$1BODY | 
|  tokenCacheTtl  | integer | Não | 3600 | TTL do cache de tokens (mínimo de 60 segundos) | 

 **Exemplo** 

```
{
  "type": "OAUTH_CLIENT_CREDENTIALS",
  "tokenUrl": "https://auth.example.com/oauth/token",
  "clientId": "${AWS_SECRET:oauth-creds:client_id}",
  "clientSecret": "${AWS_SECRET:oauth-creds:client_secret}",
  "scope": "read write",
  "tokenCacheTtl": 7200
}
```

 **AWS Signature (versão 4)** 


| Propriedade | Tipo | Obrigatório | Descrição | 
| --- | --- | --- | --- | 
|  type  | string |  Sim  | Deve ser "SIGV4" | 
|  service  | string |  Sim  | Nome do serviço da AWS (por exemplo, “execute-api”) | 
|  region  | string |  Sim  | AWS region | 
|  roleArn  | string |  Sim  | ARN do perfil do IAM para assinatura | 

 **Exemplo** 

```
{
  "type": "SIGV4",
  "service": "execute-api",
  "region": "us-east-1",
  "roleArn": "arn:aws:iam::123456789012:role/SyntheticsRole"
}
```

## Asserções e validação
<a name="assertions-validation"></a>

### Asserções HTTP
<a name="http-assertions"></a>

 **Asserções de código de status** 


| Propriedade | Tipo | Obrigatório | Descrição | 
| --- | --- | --- | --- | 
|  type  | string |  Sim  | Deve ser "STATUS\$1CODE" | 
|  operator  | string |  Sim  | EQUALS, NOT\$1EQUALS, GREATER\$1THAN,  LESS\$1THAN, IN\$1RANGE | 
|  value  | integer | Condicional | Código de status HTTP (100 a 599) | 
|  rangeMin  | integer | Condicional | Valor mínimo do intervalo (para IN\$1RANGE) | 
|  rangeMax  | integer | Condicional | Valor máximo do intervalo (para IN\$1RANGE) | 

```
{
  "type": "STATUS_CODE",
  "operator": "EQUALS",
  "value": 200
}
```

 **Asserções de tempo de resposta** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "RESPONSE\$1TIME" | 
|  operator  | string |  Sim  | - | LESS\$1THAN, GREATER\$1THAN, EQUALS | 
|  value  | número |  Sim  | - | Valor de tempo (mínimo 0) | 
|  unit  | string | Não | "MILLISSEGUNDOS" | Deve ser "MILLISECONDS" | 

```
{
  "type": "RESPONSE_TIME",
  "operator": "LESS_THAN",
  "value": 500,
  "unit": "MILLISECONDS"
}
```

 **Asserções de cabeçalho** 


| Propriedade | Tipo | Obrigatório | Descrição | 
| --- | --- | --- | --- | 
|  type  | string |  Sim  | Deve ser "HEADER" | 
|  headerName  | string |  Sim  | Nome do cabeçalho a ser validado | 
|  operator  | string |  Sim  | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH, EXIST | 
|  value  | String/booleano | Condicional | Valor esperado (booleano para o operador EXIST) | 

```
{
  "type": "HEADER",
  "headerName": "Content-Type",
  "operator": "CONTAINS",
  "value": "application/json"
}
```

 **Asserções de corpo** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "BODY" | 
|  target  | string | Não | “JSON” | JSON ou TEXT | 
|  path  | string | Condicional | - | JSONPath (obrigatório para destino JSON) | 
|  operator  | string |  Sim  | - | CONTAINS, NOT\$1CONTAINS, EQUALS,  NOT\$1EQUALS, EXISTS | 
|  value  | String/booleano |  Sim  | - | Valor esperado (booleano para o operador EXISTS) | 

```
{
  "type": "BODY",
  "target": "JSON",
  "path": "$.users[0].name",
  "operator": "EQUALS",
  "value": "John Doe"
}
```

### Asserções DNS
<a name="dns-assertions"></a>

 **Registrar asserções de valor** 


| Propriedade | Tipo | Obrigatório | Intervalo | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "RECORD\$1VALUE" | 
|  operator  | string |  Sim  | - | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH | 
|  value  | string |  Sim  | - | Valor do registro esperado | 

 **Asserções de contagem de registros** 


| Propriedade | Tipo | Obrigatório | Intervalo | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "RECORD\$1COUNT" | 
|  operator  | string |  Sim  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Sim  | ≥ 0 | Contagem esperada (mínimo 0) | 

 **Asserções autoritativas** 


| Propriedade | Tipo | Obrigatório | Intervalo | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "AUTHORITATIVE" | 
|  value  | booleano |  Sim  | - | Status autoritativo esperado | 

 **Asserções TTL** 


| Propriedade | Tipo | Obrigatório | Intervalo | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "TTL" | 
|  operator  | string |  Sim  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Sim  | ≥ 0 | TTL esperada (mínimo 0) | 

### Asserções SSL
<a name="ssl-assertions"></a>

 **Asserções de expiração do certificado** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "CERTIFICATE\$1EXPIRY" | 
|  operator  | string |  Sim  | - | GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Sim  | - | Valor de tempo (mínimo 0) | 
|  unit  | string | Não | “DIAS” | DAYS, HOURS | 

 **Asserções de assunto do certificado** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "CERTIFICATE\$1SUBJECT" | 
|  field  | string |  Sim  | - | Campo de assunto: CN, O, OU, C, ST, L | 
|  operator  | string |  Sim  | - | CONTAINS, EQUALS, REGEX\$1MATCH | 
|  value  | string |  Sim  | - | Valores de campo esperados | 

 **Asserções de emissor de certificado** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "CERTIFICATE\$1ISSUER" | 
|  field  | string |  Sim  | - | Campo do emissor: CN, O | 
|  operator  | string |  Sim  | - | CONTAINS, EQUALS | 
|  value  | string |  Sim  | - | Valores de campo esperados | 

### Asserções TCP
<a name="tcp-assertions"></a>

 **Asserções de sucesso de conexão** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "CONNECTION\$1SUCCESSFUL" | 
|  value  | booleano |  Sim  | - | Status de conexão esperado | 

 **Asserções de dados de resposta** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Sim  | - | Deve ser "RESPONSE\$1DATA" | 
|  operator  | string |  Sim  | - | CONTAINS, EQUALS, NOT\$1CONTAINS,  REGEX\$1MATCH, STARTS\$1WITH, ENDS\$1WITH | 
|  value  | string |  Sim  | - | Dados de resposta esperados | 
|  encoding  | string | Não | “UTF-8” | UTF-8, ASCII, HEX | 

## Extração de dados
<a name="data-extraction"></a>

Os extratores permitem que você capture dados das respostas para uso em etapas subsequentes ou para relatórios.

 **Propriedades de extração** 


| Propriedade | Tipo | Obrigatório | Padrão | Descrição | 
| --- | --- | --- | --- | --- | 
|  name  | string |  Sim  | - | Nome da variável para dados extraídos | 
|  type  | string |  Sim  | - | Tipo de extração: BODY | 
|  path  | string | Não | - | JSONPath para extração de corpo | 
|  regex  | string | Não | - | Padrão de expressão regular | 
|  regexGroup  | integer | Não | 0 | Grupo de captura de expressão regular (mínimo 0) | 

 **Validação de nome de extração** 
+ Número do padrão: `^[a-zA-Z][a-zA-Z0-9_]*$`
+ Deve começar com uma letra
+ Podem conter apenas letras, números e sublinhados

**Limitação**: a substituição não se aplica aos campos do esquema com valores ENUM específicos

 **Tipos de extração** 

```
{
  "name": "userId",
  "type": "BODY",
  "path": "$.user.id"
}
```

```
{
  "stepName": "loginAndExtract",
  "checkerType": "HTTP",
  "url": "https://api.example.com/login",
  "httpMethod": "POST",
  "body": "{\"username\":\"test\",\"password\":\"pass\"}",
  "extractors": [
    {
      "name": "textVariable",
      "type": "BODY",
      "path": "$.myvalue"
    }
  ]
},
{
  "stepName": "substituteVariable",
  "checkerType": "HTTP",
  "url": "https://api.example.com/get/${textVariable}",
  "httpMethod": "GET",
  "assertions": [
    {
    "type": "BODY",
    "target": "JSON",
    "path": "$.users[0].name",
    "operator": "EQUALS",
    "value": "${textVariable}"
    }
  ]
}
```