Поделиться через


Переопределения выборки — Azure Monitor Application Insights для Java

Примечание.

Функция переопределения выборки находится в общедоступной версии, начиная с 3.5.0.

Функция переопределения выборки позволяет переопределить Процент выборки по умолчанию, например:

  • Установите процент выборки на 0 (или на какое-то небольшое значение) для проверки работоспособности при шумах.
  • Установите процент выборки на 0 (или на какое-то небольшое значение) для вызовов "шумных" зависимостей.
  • Задайте процент выборки 100 для важного типа запроса (например, /loginдаже если выборка по умолчанию настроена на что-то меньшее).

Терминология

Прежде чем приступить к изучению переопределений выборки, вы должны понимать такой термин как диапазон. Под диапазоном в общем понимается следующее:

  • Входящий запрос.
  • Исходящая зависимость (например, удаленный вызов другой службы).
  • Внутрипроцессный набор зависимостей (например, работа, выполняемая подкомпонентами службы).

Для функции переопределения выборки важными являются следующие компоненты:

  • Атрибуты

Атрибуты диапазона представляют стандартные и пользовательские свойства выданного запроса или зависимости.

Начало работы

Для начала создайте файл конфигурации с именем applicationinsights.json. Сохраните его в том же каталоге, что и applicationinsights-agent-*.jar. Используйте следующий шаблон.

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

Принцип работы

telemetryType (telemetryKind в Application Insights 3.4.0) должен быть одним из request, dependency( trace log) или exception.

При запуске диапазона тип диапазона и атрибуты, находящиеся в нем в это время, используются для проверки совпадения переопределений выборки.

Совпадения могут иметь тип strict или regexp. Сопоставление регулярных выражений выполняется для всего значения атрибута, поэтому, если нужно сопоставить значение, содержащееся abc в любом месте, необходимо использовать маску .*abc.*. Переопределение выборки может определять несколько критериев атрибутов, и в этом случае все они должны совпадать, чтобы переопределение выборки совпадало.

Если одно из переопределений выборки совпадает, для определения того, следует ли выбирать диапазон, задействуется соответствующий процент выборки.

Используется только первое совпавшее переопределение выборки.

Если ни одно переопределение выборки не совпадет:

  • Если это первый диапазон трассировки, используется конфигурация выборки верхнего уровня.
  • Если это не первый диапазон трассировки, то используется родительское решение выборки.

Атрибуты диапазона, доступные для выборки

Атрибуты диапазона OpenTelemetry собираются автоматически и основаны на семантических соглашениях OpenTelemetry.

Вы также можете программно добавлять атрибуты диапазона и использовать их для выборки.

Примечание.

Чтобы просмотреть точный набор атрибутов, захваченных Приложением Application Insights Java для приложения, задайте для самостоятельного диагностика уровня отладки и найдите сообщения отладки, начиная с текста "экспорт диапазона".

Примечание.

Только атрибуты, заданные в начале диапазона, доступны для выборки, поэтому такие атрибуты, как http.response.status_code или длительность запроса, которые записываются позже, можно фильтровать с помощью расширений Java OpenTelemetry. Ниже приведен пример расширения, который фильтрует диапазоны на основе длительности запроса.

Примечание.

Атрибуты, добавленные с обработчиком телеметрии, недоступны для выборки.

Случаи использования

Подавление сбора данных телеметрии для проверок работоспособности

Этот пример запрещает сбор данных телеметрии для всех запросов /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 % телеметрии для важного типа запроса

В этом примере собирается 100 % данных телеметрии./login

Поскольку подчиненные диапазоны (зависимости) учитывают решение выборки родителя (отсутствует переопределение выборки для этого нижнего диапазона), они также собираются для всех запросов "/login".

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

Предоставление атрибутов диапазона для подавления вызовов зависимостей SQL

В этом примере показано, как найти доступные атрибуты для подавления шумных вызовов SQL. В приведенном ниже запросе показаны различные вызовы SQL и связанные записи за последние 30 дней:

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>

Теперь можно добавить заметку в WithSpan метод Java, выполняющий 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
	}

Следующая конфигурация переопределения выборки позволяет удалить диапазон, добавленный заметкой WithSpan :

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

Значение атрибута — это имя метода Java.

Эта конфигурация удаляет все данные телеметрии, созданные findPaginated из метода. Зависимости SQL не будут созданы для выполнения SQL, поступающих из findPaginated метода.

Следующая конфигурация удаляет все данные телеметрии, созданные из методов VetController класса с WithSpan заметкой:

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

Устранение неполадок

Если используется regexp и переопределение выборки не работает, попробуйте использовать .* regex. Если выборка работает, это означает, что у вас возникла проблема с первой регулярной и ознакомьтесь с этой документацией по regex.

Если он не работает.*, может возникнуть проблема с синтаксисом.application-insights.json file Просмотрите журналы Application Insights и убедитесь, что вы заметили предупреждающие сообщения.