Dela via


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

Kommentar

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

Med samplings åsidosättningar kan du åsidosätta standardsamplingsprocenten, till exempel:

  • Ange samplingsprocenten till 0 (eller något litet värde) för hälsokontroller med brus.
  • Ange samplingsprocenten till 0 (eller något litet värde) för anrop med brusberoende.
  • 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 samplings åsidosättningar bör du förstå termintervallet. 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 samplings åsidosättningarna 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 åsidosättning kan ange flera attributvillkor, i vilket fall alla måste matcha för att samplings åsidosättningen ska matcha.

Om en av samplings åsidosättningarna matchar används dess samplingsprocent för att avgöra om intervallet ska samplas eller inte.

Endast den första samplings åsidosättningen som matchar används.

Om inga samplings å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 det överordnade samplingsbeslutet.

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.

Kommentar

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".

Kommentar

Endast attribut som anges i början av intervallet är tillgängliga för sampling, så attribut som eller varaktighet för begäranden som http.response.status_code samlas in senare kan filtreras via OpenTelemetry Java-tillägg. Här är ett exempeltillägg som filtrerar sträcker sig över baserat på varaktigheten för begäran.

Kommentar

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. Frågan nedan 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 ovan 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 en samplings åsidosättning.

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 den nedan som filtrerar våra störande 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 spann till en Java-metod och ta bort det här intervallet med samplingsidosättning.

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
	}

Med följande konfiguration av åsidosättning av sampling kan du ta bort det intervall 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 findPaginated från metoden. 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ättningen inte fungerar kan du prova med 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.