Partilhar via


Personalizações de Amostragem - Azure Monitor Application Insights para Java

Nota

O recurso de substituições de amostragem está em GA, a partir da versão 3.5.0.

As substituições de amostragem permitem substituir a porcentagem de amostragem padrão, por exemplo:

  • Defina a percentagem de amostragem como 0 (ou algum valor pequeno) para verificações de saúde ruidosas.
  • Defina a porcentagem de amostragem como 0 (ou algum valor pequeno) para chamadas de dependência barulhentas.
  • Defina a porcentagem de amostragem como 100 para um tipo de solicitação importante (por exemplo, /login) mesmo que você tenha a amostragem padrão configurada para algo menor.

Terminologia

Antes de aprenderes sobre alterações de amostragem, deves compreender o termo span. Um intervalo é uma designação geral para:

  • Uma solicitação de entrada.
  • Uma dependência de saída (por exemplo, uma chamada remota para outro serviço).
  • Uma dependência em processo (por exemplo, trabalho sendo feito por subcomponentes do serviço).

Para substituições de amostragem, estes componentes de intervalo são importantes.

  • Atributos

Os atributos span representam propriedades padrão e personalizadas de uma determinada solicitação ou dependência.

Iniciar

Para começar, crie um arquivo de configuração chamado applicationinsights.json. Salve-o no mesmo diretório que applicationinsights-agent-*.jar. Utilize o modelo seguinte.

{
  "connectionString": "...",
  "sampling": {
    "percentage": 10,
    "overrides": [
      {
        "telemetryType": "request",
        "attributes": [
          ...
        ],
        "percentage": 0
      },
      {
        "telemetryType": "request",
        "attributes": [
          ...
        ],
        "percentage": 100
      }
    ]
  }
}

Como funciona

telemetryType (telemetryKind no Application Insights 3.4.0) deve ser um dos request, dependency, trace (log) ou exception.

Quando uma extensão é iniciada, o tipo de extensão e os atributos presentes nela naquele momento são usados para verificar se alguma das substituições de amostragem corresponde.

As partidas podem ser strict ou regexp. As correspondências de expressão regular são realizadas em relação ao valor inteiro do atributo. Portanto, se quiser corresponder a um valor que contenha abc em qualquer parte, precisará usar .*abc.*. Uma substituição de amostragem pode especificar vários critérios de atributo, caso em que todos eles devem corresponder para que a substituição de amostragem seja eficaz.

Se uma das prioridades de amostragem corresponder, a sua percentagem de amostragem é utilizada para decidir se a amostragem deve ou não ser realizada.

Apenas a primeira substituição de amostragem que corresponde é usada.

Se nenhuma substituição de amostragem corresponder:

  • Se for o primeiro segmento no rastreamento, a configuração de amostragem de topo será usada.
  • Se não for o primeiro segmento no rastreamento, a decisão de amostragem do segmento pai será usada.

Atributos de intervalos disponíveis para amostragem

Os atributos de extensão OpenTelemetry são coletados automaticamente e baseados nas convenções semânticas OpenTelemetry .

Você também pode adicionar atributos span de forma programática e usá-los para amostragem.

Nota

Para ver o conjunto exato de atributos capturados pelo Application Insights Java para seu aplicativo, defina o nível de autodiagnóstico para depurar e procure mensagens de depuração começando com o texto "export span".

Nota

Somente os atributos definidos no início da extensão estão disponíveis para amostragem, portanto, atributos como http.response.status_code ou duração da solicitação que são capturados posteriormente podem ser filtrados por meio das extensões OpenTelemetry Java. Aqui está uma extensão de exemplo que filtra intervalos com base na duração do pedido.

Nota

Os atributos adicionados com um processador de telemetria não estão disponíveis para amostragem.

Casos de utilização

Suprimir a coleta de telemetria para verificações de integridade

Este exemplo suprime a coleta de telemetria para todas as solicitações para /health-checks.

Este exemplo também suprime a recolha de quaisquer intervalos a jusante (dependências) que normalmente seriam recolhidos em /health-checks.

{
  "connectionString": "...",
  "sampling": {
    "overrides": [
      {
        "telemetryType": "request",
        "attributes": [
          {
            "key": "url.path",
            "value": "/health-check",
            "matchType": "strict"
          }
        ],
        "percentage": 0
      }
    ]
  }
}

Suprimir a coleta de telemetria para uma chamada de dependência ruidosa

Este exemplo suprime a coleta de telemetria para todas as GET my-noisy-key chamadas redis.

{
  "connectionString": "...",
  "sampling": {
    "overrides": [
      {
        "telemetryType": "dependency",
        "attributes": [
          {
            "key": "db.system",
            "value": "redis",
            "matchType": "strict"
          },
          {
            "key": "db.statement",
            "value": "GET my-noisy-key",
            "matchType": "strict"
          }
        ],
        "percentage": 0
      }
    ]
  }
}

Coletar 100% da telemetria para um tipo de solicitação importante

Este exemplo coleta 100% da telemetria para /login.

Como as extensões a jusante (dependências) respeitam a decisão de amostragem do pai (na ausência de qualquer substituição de amostragem para essa extensão a jusante), elas também são coletadas para todas as solicitações '/login'.

{
  "connectionString": "...",
  "sampling": {
    "percentage": 10
  },
  "sampling": {
    "overrides": [
      {
        "telemetryType": "request",
        "attributes": [
          {
            "key": "url.path",
            "value": "/login",
            "matchType": "strict"
          }
        ],
        "percentage": 100
      }
    ]
  }
}

Expondo atributos de span para suprimir chamadas de dependência SQL

Este exemplo mostra a experiência de localizar atributos disponíveis para suprimir chamadas SQL barulhentas. A consulta a seguir descreve as diferentes chamadas SQL e contagens de registros associadas nos últimos 30 dias:

dependencies
| where timestamp > ago(30d)
| where name == 'SQL: DB Query'
| summarize count() by name, operation_Name, data
| sort by count_ desc
SQL: DB Query    POST /Order             DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;    36712549    
SQL: DB Query    POST /Receipt           DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;    2220248    
SQL: DB Query    POST /CheckOutForm      DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;    554074    
SQL: DB Query    GET /ClientInfo         DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;    37064

A partir dos resultados, pode-se observar que todas as operações compartilham o mesmo valor no data campo: DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;. A similaridade entre todos estes registos torna-o um bom candidato para um ajuste de amostragem.

Ao definir o autodiagnóstico para depuração, as seguintes entradas de log tornam-se visíveis na saída:

2023-10-26 15:48:25.407-04:00 DEBUG c.m.a.a.i.exporter.AgentSpanExporter - exporting span: SpanData{spanContext=ImmutableSpanContext...

A área de interesse desses logs é a seção "atributos":

{
  "attributes": {
    "data": {
      "thread.name": "DefaultDatabaseBroadcastTransport: MessageReader thread",
      "thread.id": 96,
      "db.connection_string": "apache:",
      "db.statement": "DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;",
      "db.system": "other_sql",
      "applicationinsights.internal.item_count": 1
    }
  }
}

Usando essa saída, você pode configurar uma substituição de amostragem semelhante ao exemplo a seguir que filtra chamadas SQL barulhentas:

{
  "connectionString": "...",
  "preview": {
    "sampling": {
      "overrides": [
        {
          "telemetryType": "dependency",
          "attributes": [
            {
              "key": "db.statement",
              "value": "DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;",
              "matchType": "strict"
            }
          ],
          "percentage": 0
        }
      ]
    }
  }
}

Depois que as alterações são aplicadas, a consulta a seguir nos permite determinar a última vez que essas dependências foram ingeridas no Application Insights:

dependencies
| where timestamp > ago(30d)
| where data contains 'DECLARE @MyVar'
| summarize max(timestamp) by data
| sort by max_timestamp desc
DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;    11/13/2023 8:52:41 PM 

Suprimir a recolha de telemetria para registo

Com SL4J, você pode adicionar atributos de log:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class MdcClass {

  private static final Logger logger = LoggerFactory.getLogger(MdcClass.class);

  void method {
	
    MDC.put("key", "value");
    try {
       logger.info(...); // Application log to remove
    finally {
       MDC.remove("key"); // In a finally block in case an exception happens with logger.info
    }
	
  }
  
}

Em seguida, você pode remover o log com o atributo adicionado:

{
  "sampling": {
    "overrides": [
      {
        "telemetryType": "trace",
        "percentage": 0,
        "attributes": [
          {
            "key": "key",
            "value": "value",
            "matchType": "strict"
          }
        ]
      }
    ]
  }
}

Impedir a coleta de telemetria para um método Java

Vamos adicionar um span a um método Java e remover esse span com substituição de amostra.

Vamos primeiro adicionar a opentelemetry-instrumentation-annotations dependência:

    <dependency>
      <groupId>io.opentelemetry.instrumentation</groupId>
      <artifactId>opentelemetry-instrumentation-annotations</artifactId>
    </dependency>

Agora podemos adicionar a WithSpan anotação a um método Java que executa solicitações SQL:

package org.springframework.samples.petclinic.vet;

@Controller
class VetController {

	private final VetRepository vetRepository;

	public VetController(VetRepository vetRepository) {
		this.vetRepository = vetRepository;
	}

	@GetMapping("/vets.html")
	public String showVetList(@RequestParam(defaultValue = "1") int page, Model model) {
		Vets vets = new Vets();
		Page<Vet> paginated = findPaginated(page);
		vets.getVetList().addAll(paginated.toList());
		return addPaginationModel(page, paginated, model);
	}

	@WithSpan
	private Page<Vet> findPaginated(int page) {
		int pageSize = 5;
		Pageable pageable = PageRequest.of(page - 1, pageSize);
		return vetRepository.findAll(pageable);  // Execution of SQL requests
	}

A seguinte configuração de substituição de amostra permite remover o intervalo adicionado pela anotação WithSpan:

  "sampling": {
    "overrides": [
      {
        "telemetryType": "dependency",
        "attributes": [
          {
            "key": "code.function",
            "value": "findPaginated",
            "matchType": "strict"
          }
        ],
        "percentage": 0
      }
    ]
  }

O valor do atributo é o nome do método Java.

Essa configuração remove todos os dados de telemetria criados do findPaginated método. As dependências SQL não são criadas para as execuções SQL provenientes do findPaginated método.

A configuração a seguir remove todos os dados de telemetria emitidos dos métodos da classe VetController que têm a(s) anotação(ões) WithSpan:

 "sampling": {
    "overrides": [
      {
        "telemetryType": "dependency",
        "attributes": [
          {
            "key": "code.namespace",
            "value": "org.springframework.samples.petclinic.vet.VetController",
            "matchType": "strict"
          }
        ],
        "percentage": 0
      }
    ]
  }

Resolução de Problemas

Consulte o artigo dedicado à resolução de problemas.

Próximos passos