Dela via


Åsidosättning av sampling – Azure Monitor Application Insights för Java

Anteckning

Funktionen för samplings åsidosättningar är i GA, från och med 3.5.0.

Med samplingsöverskridningar kan du ändra standardsamplingsprocenten, till exempel:

  • Ange samplingsprocenten till 0 (eller något litet värde) för hälsokontroller med brus.
  • Sätt samplingsprocenten till 0 (eller något litet värde) för brusiga beroendeanrop.
  • Ange samplingsprocenten till 100 för en viktig typ av begäran (till exempel /login) även om standardsampling har konfigurerats till något lägre.

Terminologi

Innan du lär dig mer om åsidokopplingar för sampling bör du förstå termen span. Ett spann är en allmän term för:

  • En inkommande begäran.
  • Ett utgående beroende (till exempel ett fjärranrop till en annan tjänst).
  • Ett pågående beroende (till exempel arbete som utförs av underkomponenter i tjänsten).

För samplingsåsidosättningar är dessa span-komponenter viktiga.

  • Attribut

Span-attributen representerar både standard- och anpassade egenskaper för en viss begäran eller ett visst beroende.

Komma igång

Börja med att skapa en konfigurationsfil med namnet applicationinsights.json. Spara den i samma katalog som applicationinsights-agent-*.jar. Använd följande mall.

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

Hur det fungerar

telemetryType (telemetryKind i Application Insights 3.4.0) måste vara en av request, dependency, trace (logg) eller exception.

När ett spann startas används typen av spann och attributen som finns på den vid den tidpunkten, för att kontrollera om någon av sampling-åtgärderna matchar.

Matchningar kan vara antingen strict eller regexp. Reguljära uttrycksmatchningar utförs mot hela attributvärdet, så om du vill matcha ett värde som innehåller abc var som helst i det måste du använda .*abc.*. En samplingsåsidoläggning kan ange flera attributvillkor, och i så fall måste alla villkor matcha för att samplingsåsidoläggningen ska gälla.

Om ett av samplingsundantagen matchar används dess samplingsprocent för att avgöra om spännvidden ska samplas eller inte.

Endast den första urvalsändringen som matchar används.

Om inga urvalsåsidosättningar matchar:

  • Om det är det första intervallet i spårningen används konfigurationen för toppnivåsampling.
  • Om det inte är det första intervallet i spårningen används förälderns samplingsbeslut.

Tillgängliga spanattribut för sampling

OpenTelemetry span-attribut samlas in automatiskt och baseras på OpenTelemetry-semantiska konventioner.

Du kan också programmatiskt lägga till span-attribut och använda dem för sampling.

Anteckning

Om du vill se den exakta uppsättningen attribut som hämtats av Application Insights Java för ditt program anger du självdiagnostiknivån för felsökning och letar efter felsökningsmeddelanden som börjar med texten "exportintervall".

Anteckning

Endast attribut som anges i början av intervallet är tillgängliga för sampling, så attribut som http.response.status_code och varaktigheten för begäranden, vilka samlas in senare, kan filtreras genom OpenTelemetry Java-tillägg. Här är ett exempeltillägg som filtrerar tidsintervall beroende på varaktigheten för begäran.

Anteckning

Attributen som läggs till med en telemetriprocessor är inte tillgängliga för sampling.

Användningsfall

Förhindra insamling av telemetri för hälsokontroller

Det här exemplet förhindrar insamling av telemetri för alla begäranden till /health-checks.

Det här exemplet förhindrar också insamling av underordnade intervall (beroenden) som normalt samlas in under /health-checks.

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

Förhindra insamling av telemetri för ett störande beroendeanrop

Det här exemplet förhindrar insamling av telemetri för alla GET my-noisy-key redis-anrop.

{
  "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
      }
    ]
  }
}

Samla in 100 % telemetri för en viktig typ av begäran

I det här exemplet samlas 100 % av telemetrin in för /login.

Eftersom underordnade intervall (beroenden) respekterar det överordnade samplingsbeslutet (utan någon samplings åsidosättning för det nedströmsintervallet) samlas de också in för alla "/login"-begäranden.

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

Exponera span-attribut för att förhindra SQL-beroendeanrop

I det här exemplet går vi igenom hur du hittar tillgängliga attribut för att förhindra störande SQL-anrop. Följande fråga visar de olika SQL-anropen och antalet associerade poster under de senaste 30 dagarna:

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

Från resultaten kan det observeras att alla åtgärder har samma värde i fältet data : DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar;. Likheten mellan alla dessa poster gör det till en bra kandidat för ett åsidosättande av urval.

Genom att ställa in självdiagnostik för felsökning visas följande loggposter i utdata:

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

Intresseområdet från dessa loggar är avsnittet "attribut":

{
  "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
    }
  }
}

Med hjälp av dessa utdata kan du konfigurera en samplings åsidosättning som liknar följande exempel som filtrerar brusande SQL-anrop:

{
  "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
        }
      ]
    }
  }
}

När ändringarna har tillämpats kan vi med följande fråga avgöra när dessa beroenden senast matades in i 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 

Utelämna insamling av telemetri för logg

Med SL4J kan du lägga till loggattribut:

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
    }
	
  }
  
}

Du kan sedan ta bort loggen med det tillagda attributet:

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

Förhindra insamling av telemetri för en Java-metod

Vi ska lägga till ett span till en Java-metod och ta bort det här spanet med överskrivning av sampling.

Vi lägger först till beroendet opentelemetry-instrumentation-annotations :

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

Nu kan vi lägga till anteckningen WithSpan i en Java-metod som kör SQL-begäranden:

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
	}

Den följande sampling-åsidosättningskonfigurationen gör att du kan ta bort det område som läggs till av kommentaren WithSpan:

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

Attributvärdet är namnet på Java-metoden.

Den här konfigurationen tar bort alla telemetridata som skapats från metoden findPaginated. SQL-beroenden skapas inte för SQL-körningar som kommer från findPaginated metoden.

Följande konfiguration tar bort alla telemetridata som genereras från metoder för klassen VetController med anteckningen WithSpan :

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

Felsökning

Om du använder regexp och samplingsåsidosättning inte fungerar kan du prova med den .* regex. Om samplingen nu fungerar innebär det att du har problem med den första regexen och läser den här regex-dokumentationen.

Om det inte fungerar med .*kan du ha ett syntaxproblem i .application-insights.json file Titta på Application Insights-loggarna och se om du märker varningsmeddelanden.

Nästa steg