다음을 통해 공유


샘플링 재정의 - Java용 Azure Monitor Application Insights

메모

샘플링 재정의 기능은 3.5.0부터 GA로 제공됩니다.

샘플링 재정의를 사용하면 기본 샘플링 백분율을 재정의할 수 있습니다. 예를 들면 다음과 같습니다.

  • 잡음 상태 검사에 대한 샘플링 백분율을 0이나 작은 값으로 설정합니다.
  • 잡음 종속성 호출에 대한 샘플링 백분율을 0이나 작은 값으로 설정합니다.
  • 기본 샘플링이 더 낮은 것으로 구성된 경우에도 중요한 요청 형식(예: /login)에 대해 샘플링 백분율을 100으로 설정합니다.

용어

샘플링 재정의에 관해 알아보기 전에 범위라는 용어를 이해해야 합니다. 범위는 다음에 대한 일반적인 용어입니다.

  • 들어오는 요청.
  • 나가는 종속성(예: 다른 서비스에 대한 원격 호출).
  • 현재 진행 중인 의존성(예: 서비스의 하위 구성 요소가 수행하는 작업).

샘플링 재정의의 경우 다음 범위 구성 요소가 중요합니다.

  • 특성

범위 특성은 지정된 요청 또는 종속성의 표준 및 사용자 지정 속성을 둘 다 나타냅니다.

시작하기

시작하려면 applicationinsights.json이라는 구성 파일을 만듭니다. 이를 동일한 디렉터리에 applicationinsights-agent-*.jar로 저장합니다. 다음 템플릿을 사용합니다.

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

작동 방식

telemetryType(Application Insights 3.4.0의 경우 telemetryKind)은 request, dependency, trace(로그) 또는 exception 중 하나여야 합니다.

범위가 시작될 때 해당 시간에 범위에 있는 범위 형식 및 특성을 사용하여 샘플링 재정의가 일치하는지 확인합니다.

일치 항목은 strict 또는 regexp 중 하나일 수 있습니다. 정규식 일치는 전체 특성 값에 대해 수행되므로 abc를 포함한 값을 일치시키려면 .*abc.*를 사용해야 합니다. 샘플링 재정의는 여러 특성 조건을 지정할 수 있습니다. 샘플링 재정의가 적용되려면 모든 조건이 일치해야 합니다.

샘플링 재정의 중 하나가 일치하는 경우 해당 샘플링 백분율을 사용하여 범위를 샘플링할지 여부를 결정합니다.

일치하는 첫 번째 샘플링 재정의만 사용됩니다.

샘플링 재정의가 일치하지 않는 경우:

  • 추적의 첫 번째 범위인 경우 최상위 샘플링 구성이 사용됩니다.
  • 추적의 첫 번째 범위가 아닌 경우 부모 샘플링 결정이 사용됩니다.

샘플링에 사용할 수 있는 범위 특성

OpenTelemetry 범위 특성은 OpenTelemetry 의미 체계 규칙을 기반으로 자동 수집됩니다.

또한 프로그래밍 방식으로 범위 특성을 추가하고 샘플링에 사용할 수 있습니다.

메모

Application Insights Java에서 애플리케이션용으로 캡처한 정확한 특성 집합을 보려면 자체 진단 수준을 디버그로 설정하고 "내보내기 범위" 텍스트로 시작하는 디버그 메시지를 찾습니다.

메모

범위의 시작 부분에 설정된 특성만 샘플링에 사용할 수 있으므로 나중에 캡처되는 http.response.status_code 같은 특성 또는 요청 기간은 OpenTelemetry Java 확장을 통해 필터링할 수 있습니다. 다음은 요청 기간에 따라 범위를 필터링하는샘플 확장입니다.

메모

원격 분석 프로세서와 함께 추가된 특성은 샘플링에 사용할 수 없습니다.

사용 사례

상태 검사를 위한 원격 분석 수집 안 함

이 예제는 /health-checks에 대한 모든 요청의 원격 분석 수집을 중단합니다.

이 예제는 또한 일반적으로 /health-checks에서 수집되는 다운스트림 범위(종속성)도 수집하지 않습니다.

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

노이즈가 있는 종속성 호출에 대한 원격 분석 수집 안 함

이 예제는 모든 GET my-noisy-key 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
      }
    ]
  }
}

중요한 요청 형식에 대한 원격 분석 데이터를 100% 수집합니다.

이 예제에서는 /login에 대한 원격 분석의 100%를 수집합니다.

다운스트림 범위(종속성)는 부모의 샘플링 결정(해당 다운스트림 범위에 대한 샘플링 재정의 제외)을 준수하므로 모든 ‘/login’ 요청에 대해서도 수집됩니다.

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

SQL 종속성 호출을 억제하기 위한 범위 속성 공개

이 예제에서는 SQL 호출의 소음을 억제할 수 있는 속성을 찾는 과정을 설명합니다. 다음 쿼리는 지난 30일 동안의 다양한 SQL 호출 및 관련 레코드 수를 보여 줍니다.

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

결과를 보면 모든 작업이 data 필드에서 DECLARE @MyVar varbinary(20); SET @MyVar = CONVERT(VARBINARY(20), 'Hello World');SET CONTEXT_INFO @MyVar; 동일한 값을 공유하는 것을 관찰할 수 있습니다. 이러한 모든 레코드 간의 공통성은 샘플링 오버라이드에 적합한 후보입니다.

자체 진단을 디버그하도록 설정하면 다음 로그 항목이 출력에 표시됩니다.

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

이러한 로그의 관심 영역은 "특성" 섹션입니다.

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

이 출력을 사용하여 시끄러운 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
        }
      ]
    }
  }
}

변경 내용이 적용되면 다음 쿼리를 통해 이러한 종속성이 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 

로그에 대한 원격 분석 수집 안 함

SL4J를 사용하면 로그 특성을 추가할 수 있습니다.

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

그런 다음, 추가된 특성이 있는 로그를 제거할 수 있습니다.

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

Java 메서드에 대한 원격 분석 수집 중단

Java 메서드에 범위를 추가하고 샘플링 재정의를 사용하여 이 범위를 제거합니다.

먼저 종속성을 추가 opentelemetry-instrumentation-annotations 해 보겠습니다.

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

이제 SQL 요청을 실행하는 Java 메서드에 주석을 추가할 WithSpan 수 있습니다.

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
	}

다음 샘플링 재정의 구성을 사용하면 주석에 의해 추가된 WithSpan 범위를 제거할 수 있습니다.

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

특성 값은 Java 메서드의 이름입니다.

이 구성은 findPaginated 메서드에서 생성된 모든 원격 분석 데이터를 제거합니다. SQL 종속성은 메서드에서 findPaginated 오는 SQL 실행에 대해 만들어지지 않습니다.

다음 구성은 주석이 있는 VetController 클래스의 WithSpan 메서드에서 내보낸 모든 원격 분석 데이터를 제거합니다.

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

문제 해결

regexp을(를) 사용하여 샘플링 재정의가 작동하지 않는 경우 .* 정규식을 사용해 보세요. 이제 샘플링이 작동하면 첫 번째 정규식에 문제가 있다는 것을 의미하며, 이 정규식 설명서를 읽어보세요.

.*이(가) 작동하지 않는 경우 application-insights.json file에 구문 문제가 있을 수 있습니다. Application Insights 로그를 살펴보고 경고 메시지가 표시되는지 확인하세요.

다음 단계