Sampling-onderdrukkingen - Azure Monitor Application Insights voor Java
Notitie
Vanaf 3.5.0 is de functie voor het overschrijven van steekproeven beschikbaar.
Met steekproeven kunt u het standaardsamplingspercentage overschrijven, bijvoorbeeld:
- Stel het steekproefpercentage in op 0 (of een kleine waarde) voor ruisstatuscontroles.
- Stel het steekproefpercentage in op 0 (of een kleine waarde) voor aanroepen van ruis.
- Stel het steekproefpercentage in op 100 voor een belangrijk aanvraagtype (bijvoorbeeld
/login
) hoewel u de standaardsampling hebt geconfigureerd voor iets lagers.
Terminologie
Voordat u meer te weten komt over steekproeven, moet u de termspanne begrijpen. Een periode is een algemene term voor:
- Een binnenkomende aanvraag.
- Een uitgaande afhankelijkheid (bijvoorbeeld een externe aanroep naar een andere service).
- Een in-process afhankelijkheid (bijvoorbeeld werk dat wordt uitgevoerd door subonderdelen van de service).
Voor steekproeven zijn deze spanonderdelen belangrijk:
- Kenmerken
De spankenmerken vertegenwoordigen zowel standaard- als aangepaste eigenschappen van een bepaalde aanvraag of afhankelijkheid.
Aan de slag
Maak eerst een configuratiebestand met de naam applicationinsights.json. Sla deze op in dezelfde map als applicationinsights-agent-*.jar. Gebruik de volgende sjabloon.
{
"connectionString": "...",
"sampling": {
"percentage": 10,
"overrides": [
{
"telemetryType": "request",
"attributes": [
...
],
"percentage": 0
},
{
"telemetryType": "request",
"attributes": [
...
],
"percentage": 100
}
]
}
}
Hoe het werkt
telemetryType
(telemetryKind
in Application Insights 3.4.0) moet een van request
, dependency
trace
(logboek) of exception
.
Wanneer een periode wordt gestart, worden het type span en de kenmerken die op dat moment aanwezig zijn, gebruikt om te controleren of een van de steekproeven overeenkomt.
Overeenkomsten kunnen een strict
of regexp
. Reguliere expressieovereenkomsten worden uitgevoerd op basis van de gehele kenmerkwaarde, dus als u een waarde wilt vergelijken die abc
ergens in de expressie staat, moet u deze gebruiken .*abc.*
.
Een steekproefoverschrijving kan meerdere kenmerkcriteria opgeven. In dat geval moeten ze allemaal overeenkomen met de steekproefoverschrijving.
Als een van de steekproeven overeenkomsten overschrijft, wordt het steekproefpercentage gebruikt om te bepalen of de spanwijdte moet worden genomen of niet.
Alleen de eerste steekproeven die overeenkomen, worden gebruikt.
Als er geen steekproeven worden overschreven, komt het volgende overeen:
- Als dit het eerste bereik in de trace is, wordt de configuratie van steekproeven op het hoogste niveau gebruikt.
- Als dit niet het eerste bereik in de trace is, wordt de beslissing over de bovenliggende steekproeven gebruikt.
Span-kenmerken die beschikbaar zijn voor steekproeven
OpenTelemetry spankenmerken worden automatisch verzameld en gebaseerd op de semantische openTelemetry-conventies.
U kunt ook programmatisch spankenmerken toevoegen en gebruiken voor steekproeven.
Notitie
Als u de exacte set kenmerken wilt zien die zijn vastgelegd door Application Insights Java voor uw toepassing, stelt u het niveau voor zelfdiagnose in op foutopsporing en zoekt u naar foutopsporingsberichten die beginnen met de tekst 'span exporteren'.
Notitie
Alleen kenmerken die aan het begin van het bereik zijn ingesteld, zijn beschikbaar voor steekproeven, zodat kenmerken zoals http.response.status_code
of aanvraagduur die later worden vastgelegd, kunnen worden gefilterd via OpenTelemetry Java-extensies. Hier volgt een voorbeeldextensie die filtert op basis van de duur van de aanvraag.
Notitie
De kenmerken die zijn toegevoegd met een telemetrieprocessor zijn niet beschikbaar voor steekproeven.
Gebruiksgevallen
Het verzamelen van telemetrie voor statuscontroles onderdrukken
In dit voorbeeld wordt het verzamelen van telemetrie voor alle aanvragen naar /health-checks
onderdrukt.
In dit voorbeeld wordt ook het verzamelen van downstream-spanten (afhankelijkheden) onderdrukt die normaal gesproken worden verzameld onder /health-checks
.
{
"connectionString": "...",
"sampling": {
"overrides": [
{
"telemetryType": "request",
"attributes": [
{
"key": "url.path",
"value": "/health-check",
"matchType": "strict"
}
],
"percentage": 0
}
]
}
}
Het verzamelen van telemetrie onderdrukken voor een aanroep van ruisafhankelijkheid
In dit voorbeeld wordt het verzamelen van telemetrie voor alle GET my-noisy-key
redis-aanroepen onderdrukt.
{
"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
}
]
}
}
100% van de telemetrie verzamelen voor een belangrijk aanvraagtype
In dit voorbeeld wordt 100% van de telemetrie voor /login
verzameld.
Omdat downstream-afhankelijkheden de beslissing van de bovenliggende steekproef respecteren (geen steekproeven overschrijven voor die downstream span), worden ze ook verzameld voor alle aanvragen voor '/login'.
{
"connectionString": "...",
"sampling": {
"percentage": 10
},
"sampling": {
"overrides": [
{
"telemetryType": "request",
"attributes": [
{
"key": "url.path",
"value": "/login",
"matchType": "strict"
}
],
"percentage": 100
}
]
}
}
Spankenmerken beschikbaar maken om SQL-afhankelijkheidsaanroepen te onderdrukken
In dit voorbeeld wordt uitgelegd hoe u beschikbare kenmerken kunt vinden om luidruchtige SQL-aanroepen te onderdrukken. In de onderstaande query ziet u de verschillende SQL-aanroepen en het bijbehorende aantal records in de afgelopen 30 dagen:
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
Uit de bovenstaande resultaten kan worden vastgesteld dat alle bewerkingen dezelfde waarde in het data
veld hebben: DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;
. De gemeenschappelijkheid tussen al deze records maakt het een goede kandidaat voor een steekproevenoverschrijven.
Door de zelfdiagnose in te stellen voor foutopsporing, worden de volgende logboekvermeldingen zichtbaar in de uitvoer:
2023-10-26 15:48:25.407-04:00 DEBUG c.m.a.a.i.exporter.AgentSpanExporter - exporting span: SpanData{spanContext=ImmutableSpanContext...
Het interessegebied van deze logboeken is de sectie Kenmerken:
{
"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
}
}
}
Met deze uitvoer kunt u een sampling-onderdrukking configureren die vergelijkbaar is met de onderstaande die onze luidruchtige SQL-aanroepen filtert:
{
"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
}
]
}
}
}
Zodra de wijzigingen zijn toegepast, kunnen we met de volgende query bepalen wanneer deze afhankelijkheden de laatste keer zijn opgenomen in 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
Het verzamelen van telemetrie voor logboek onderdrukken
Met SL4J kunt u logboekkenmerken toevoegen:
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
}
}
}
Vervolgens kunt u het logboek met het toegevoegde kenmerk verwijderen:
{
"sampling": {
"overrides": [
{
"telemetryType": "trace",
"percentage": 0,
"attributes": [
{
"key": "key",
"value": "value",
"matchType": "strict"
}
]
}
]
}
}
Het verzamelen van telemetrie voor een Java-methode onderdrukken
We gaan een spanwijdte toevoegen aan een Java-methode en deze periode verwijderen met steekproeven overschrijven.
Laten we eerst de opentelemetry-instrumentation-annotations
afhankelijkheid toevoegen:
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-annotations</artifactId>
</dependency>
We kunnen nu de aantekening toevoegen aan een Java-methode voor het WithSpan
uitvoeren van SQL-aanvragen:
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
}
Met de volgende configuratie voor het overschrijven van steekproeven kunt u de span die is toegevoegd door de WithSpan
aantekening verwijderen:
"sampling": {
"overrides": [
{
"telemetryType": "dependency",
"attributes": [
{
"key": "code.function",
"value": "findPaginated",
"matchType": "strict"
}
],
"percentage": 0
}
]
}
De kenmerkwaarde is de naam van de Java-methode.
Met deze configuratie worden alle telemetriegegevens verwijderd die zijn gemaakt op basis van de findPaginated
methode. SQL-afhankelijkheden worden niet gemaakt voor de SQL-uitvoeringen die afkomstig zijn van de findPaginated
methode.
Met de volgende configuratie worden alle telemetriegegevens verwijderd die worden verzonden uit methoden van de VetController
klasse met de WithSpan
aantekening:
"sampling": {
"overrides": [
{
"telemetryType": "dependency",
"attributes": [
{
"key": "code.namespace",
"value": "org.springframework.samples.petclinic.vet.VetController",
"matchType": "strict"
}
],
"percentage": 0
}
]
}
Probleemoplossing
Als u de regexp
steekproeven gebruikt en de steekproeven niet werken, kunt u het proberen met de .*
regex. Als de sampling nu werkt, betekent dit dat u een probleem hebt met de eerste regex en deze regex-documentatie leest.
Als het niet werkt .*
, kan het zijn dat u een syntaxisprobleem hebt in uw application-insights.json file
. Bekijk de Application Insights-logboeken en kijk of u waarschuwingsberichten ziet.