Przesłonięcia próbkowania — usługa Azure Monitor Application Insights dla języka Java
Uwaga
Funkcja przesłonięcia próbkowania jest dostępna w wersji ogólnodostępnej, począwszy od wersji 3.5.0.
Przesłonięcia próbkowania umożliwiają zastąpienie domyślnej wartości procentowej próbkowania, na przykład:
- Ustaw wartość procentową próbkowania na 0 (lub niewielką wartość) dla hałaśliwych testów kondycji.
- Ustaw wartość procentową próbkowania na 0 (lub niewielką wartość) dla hałaśliwych wywołań zależności.
- Ustaw wartość procentową próbkowania na 100 dla ważnego typu żądania (na przykład
/login
), mimo że masz domyślne próbkowanie skonfigurowane na wartość niższą.
Terminologia
Zanim dowiesz się więcej na temat przesłonięć próbkowania, należy zrozumieć zakres terminów. Zakres jest ogólnym terminem dla:
- Żądanie przychodzące.
- Zależność wychodząca (na przykład zdalne wywołanie do innej usługi).
- Zależność w procesie (na przykład praca wykonywana przez podskładniki usługi).
W przypadku przesłonięć próbkowania te składniki zakresu są ważne:
- Atrybuty
Atrybuty zakresu reprezentują zarówno właściwości standardowe, jak i niestandardowe danego żądania lub zależności.
Wprowadzenie
Aby rozpocząć, utwórz plik konfiguracji o nazwie applicationinsights.json. Zapisz go w tym samym katalogu co applicationinsights-agent-*.jar. Użyj następującego szablonu.
{
"connectionString": "...",
"sampling": {
"percentage": 10,
"overrides": [
{
"telemetryType": "request",
"attributes": [
...
],
"percentage": 0
},
{
"telemetryType": "request",
"attributes": [
...
],
"percentage": 100
}
]
}
}
Jak to działa
telemetryType
(telemetryKind
w usłudze Application Insights 3.4.0) musi być jednym z request
elementów , dependency
, trace
(log) lub exception
.
Po uruchomieniu zakresu typ zakresu i atrybuty obecne w nim w tym czasie są używane do sprawdzania, czy którykolwiek z przesłonięć próbkowania jest zgodny.
Dopasowania mogą mieć strict
wartość lub regexp
. Dopasowania wyrażeń regularnych są wykonywane względem całej wartości atrybutu, więc jeśli chcesz dopasować wartość zawierającą abc
ją w dowolnym miejscu, musisz użyć polecenia .*abc.*
.
Przesłonięcia próbkowania mogą określać wiele kryteriów atrybutów, w tym przypadku wszystkie muszą być zgodne z przesłonięć próbkowania, aby były zgodne.
Jeśli jedno z przesłonięć próbkowania jest zgodne, jego procent próbkowania jest używany do decydowania, czy próbkować zakres, czy nie.
Używane jest tylko pierwsze przesłonięcia próbkowania, które pasuje.
Jeśli żadne przesłonięcia próbkowania nie są zgodne:
- Jeśli jest to pierwszy zakres śledzenia, zostanie użyta konfiguracja próbkowania najwyższego poziomu.
- Jeśli nie jest to pierwszy zakres w śladzie, zostanie użyta decyzja o próbkowaniu nadrzędnym.
Atrybuty zakresu dostępne do próbkowania
Atrybuty zakresu OpenTelemetry są zbierane automatycznie i oparte na konwencjach semantycznych OpenTelemetry.
Można również programowo dodawać atrybuty zakresu i używać ich do próbkowania.
Uwaga
Aby wyświetlić dokładny zestaw atrybutów przechwyconych przez środowisko Java usługi Application Insights dla aplikacji, ustaw poziom samodzielnej diagnostyki na debugowanie i poszukaj komunikatów debugowania rozpoczynających się od tekstu "export span".
Uwaga
Tylko atrybuty ustawione na początku zakresu są dostępne do próbkowania, więc atrybuty, takie jak http.response.status_code
czas trwania żądania lub przechwycone później, można filtrować za pomocą rozszerzeń Języka Java OpenTelemetry. Oto przykładowe rozszerzenie, które filtruje zakresy na podstawie czasu trwania żądania.
Uwaga
Atrybuty dodane za pomocą procesora telemetrii nie są dostępne do próbkowania.
Przypadki użycia
Pomijanie zbierania danych telemetrycznych na potrzeby kontroli kondycji
W tym przykładzie pomija się zbieranie danych telemetrycznych dla wszystkich żądań do /health-checks
usługi .
W tym przykładzie pomija się również zbieranie wszystkich zakresów podrzędnych (zależności), które normalnie byłyby zbierane w obszarze /health-checks
.
{
"connectionString": "...",
"sampling": {
"overrides": [
{
"telemetryType": "request",
"attributes": [
{
"key": "url.path",
"value": "/health-check",
"matchType": "strict"
}
],
"percentage": 0
}
]
}
}
Pomijanie zbierania danych telemetrycznych dla hałaśliwego wywołania zależności
W tym przykładzie pomija się zbieranie danych telemetrycznych dla wszystkich GET my-noisy-key
wywołań usługi 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
}
]
}
}
Zbieranie 100% danych telemetrycznych dla ważnego typu żądania
W tym przykładzie zebrano 100% danych telemetrycznych dla elementu /login
.
Ponieważ zakresy podrzędne (zależności) są zgodne z decyzją o próbkowaniu elementu nadrzędnego (bez przesłonięcia próbkowania dla tego zakresu podrzędnego), są one również zbierane dla wszystkich żądań "/login".
{
"connectionString": "...",
"sampling": {
"percentage": 10
},
"sampling": {
"overrides": [
{
"telemetryType": "request",
"attributes": [
{
"key": "url.path",
"value": "/login",
"matchType": "strict"
}
],
"percentage": 100
}
]
}
}
Uwidacznianie atrybutów zakresu w celu pomijania wywołań zależności SQL
W tym przykładzie przedstawiono środowisko znajdowania dostępnych atrybutów w celu pomijania hałaśliwych wywołań SQL. Poniższe zapytanie przedstawia różne wywołania SQL i skojarzone liczby rekordów w ciągu ostatnich 30 dni:
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
Z powyższych wyników można zauważyć, że wszystkie operacje współdzielą tę samą wartość w data
polu: DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;
. Powszechność między wszystkimi tymi rekordami sprawia, że jest dobrym kandydatem do zastąpienia próbkowania.
Po ustawieniu samodzielnej diagnostyki w celu debugowania następujące wpisy dziennika staną się widoczne w danych wyjściowych:
2023-10-26 15:48:25.407-04:00 DEBUG c.m.a.a.i.exporter.AgentSpanExporter - exporting span: SpanData{spanContext=ImmutableSpanContext...
Obszarem zainteresowania tych dzienników jest sekcja "atrybuty":
{
"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
}
}
}
Korzystając z tych danych wyjściowych, można skonfigurować przesłonięcia próbkowania podobne do poniższego, które przefiltrują nasze hałaśliwe wywołania SQL:
{
"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
}
]
}
}
}
Po zastosowaniu zmian następujące zapytanie pozwala nam określić, kiedy ostatnio te zależności zostały pozyskane do usługi 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
Pomijanie zbierania danych telemetrycznych dla dziennika
Za pomocą programu SL4J można dodawać atrybuty dziennika:
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
}
}
}
Następnie można usunąć dziennik z dodanym atrybutem:
{
"sampling": {
"overrides": [
{
"telemetryType": "trace",
"percentage": 0,
"attributes": [
{
"key": "key",
"value": "value",
"matchType": "strict"
}
]
}
]
}
}
Pomijanie zbierania danych telemetrycznych dla metody Java
Dodamy zakres do metody Języka Java i usuniemy ten zakres z przesłonięcia próbkowania.
Najpierw dodajmy opentelemetry-instrumentation-annotations
zależność:
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-annotations</artifactId>
</dependency>
Teraz można dodać adnotację WithSpan
do metody Java wykonującej żądania 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
}
Następująca konfiguracja przesłonięcia próbkowania umożliwia usunięcie zakresu dodanego przez adnotację WithSpan
:
"sampling": {
"overrides": [
{
"telemetryType": "dependency",
"attributes": [
{
"key": "code.function",
"value": "findPaginated",
"matchType": "strict"
}
],
"percentage": 0
}
]
}
Wartość atrybutu to nazwa metody Java.
Ta konfiguracja spowoduje usunięcie wszystkich danych telemetrycznych utworzonych findPaginated
z metody . Zależności SQL nie zostaną utworzone dla wykonań SQL pochodzących z findPaginated
metody .
Następująca konfiguracja spowoduje usunięcie wszystkich danych telemetrycznych emitowanych z metod VetController
klasy o adnotacji WithSpan
:
"sampling": {
"overrides": [
{
"telemetryType": "dependency",
"attributes": [
{
"key": "code.namespace",
"value": "org.springframework.samples.petclinic.vet.VetController",
"matchType": "strict"
}
],
"percentage": 0
}
]
}
Rozwiązywanie problemów
Jeśli używasz polecenia regexp
, a przesłonięcia próbkowania nie działają, spróbuj użyć wyrażenia regularnego .*
. Jeśli próbkowanie działa teraz, oznacza to, że masz problem z pierwszym wyrażeniem regularnym i przeczytaj tę dokumentację wyrażeń regularnych.
Jeśli nie działa z programem , może wystąpić problem ze .*
składnią w pliku application-insights.json file
. Przyjrzyj się dziennikom usługi Application Insights i sprawdź, czy widzisz komunikaty ostrzegawcze.