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


Вывод трассировок User-Code

Помимо включения трассировки в конфигурации для сбора данных инструментирования, созданных Windows Communication Foundation (WCF), можно также программным образом выдавать трассировки в пользовательском коде. Таким образом, можно заранее создать данные инструментирования, которые можно использовать позже для диагностики. В этом разделе описывается, как это сделать.

Кроме того, пример Расширение трассировки содержит весь код, представленный в следующих разделах.

Создание источника трассировки

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

TraceSource ts = new TraceSource("myUserTraceSource");

Создание мероприятий

Действия — это логическая единица обработки. Вы можете создать одно действие для каждой основной единицы обработки, в которой необходимо сгруппировать трассировки. Например, можно создать одно действие для каждого запроса к службе. Для этого выполните следующие действия.

  1. Сохраните идентификатор действия в контексте области.

  2. Создайте новый идентификатор действия.

  3. Передайте активность из текущей области в новую, установите в фокусе новую активность и создайте начальную трассировку для этой активности.

В следующем коде показано, как это сделать.

Guid oldID = Trace.CorrelationManager.ActivityId;
Guid traceID = Guid.NewGuid();
ts.TraceTransfer(0, "transfer", traceID);
Trace.CorrelationManager.ActivityId = traceID; // Trace is static
ts.TraceEvent(TraceEventType.Start, 0, "Add request");

Создание трассировок в рамках действия пользователя

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

double value1 = 100.00D;
double value2 = 15.99D;
ts.TraceInformation("Client sends message to Add " + value1 + ", " + value2);
double result = client.Add(value1, value2);
ts.TraceInformation("Client receives Add response '" + result + "'");

Остановка действий

Чтобы остановить действия, вернитесь к старой активности, остановите текущий идентификатор активности и сбросьте старый идентификатор активности в области действия.

В следующем коде показано, как это сделать.

ts.TraceTransfer(0, "transfer", oldID);
ts.TraceEvent(TraceEventType.Stop, 0, "Add request");
Trace.CorrelationManager.ActivityId = oldID;

Распространение идентификатора активности в сервис

Если вы установите атрибут propagateActivity в значение true для источника трассировки System.ServiceModel и в файлах конфигурации клиента, и службы, обработка запроса Add службой происходит в той же активности, что и определённая в клиенте. Если служба сама определяет свои действия и методы их передачи, то трассировки службы не появляются в активности, распространяемой клиентом. Вместо этого они появляются в активности, связанной с помощью трассировок передачи с той активностью, идентификатор которой распространяется клиентом.

Замечание

propagateActivity Если атрибут установлен true и в клиенте, и в службе, то WCF задает контекстную активность в области операций службы.

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

// Check if an activity was set in scope by WCF, if it was
// propagated from the client. If not, ( ambient activity is
// equal to Guid.Empty), create a new one.
if(Trace.CorrelationManager.ActivityId == Guid.Empty)
{
    Guid newGuid = Guid.NewGuid();
    Trace.CorrelationManager.ActivityId = newGuid;
}
// Emit your Start trace.
ts.TraceEvent(TraceEventType.Start, 0, "Add Activity");

// Emit the processing traces for that request.
serviceTs.TraceInformation("Service receives Add "
                            + n1 + ", " + n2);
// double result = n1 + n2;
serviceTs.TraceInformation("Service sends Add result" + result);

// Emit the Stop trace and exit the method scope.
ts.TraceEvent(TraceEventType.Stop, 0, "Add Activity");
// return result;

Трассировка исключений, создаваемых в коде

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

ts.TraceEvent(TraceEventType.Warning, 0, "Throwing exception " + "exceptionMessage");

Просмотр пользовательских трассировок с помощью инструмента просмотра трассировок службы

В этом разделе содержатся снимки экрана трассировок, созданные в ходе выполнения примера Расширение трассировки, при просмотре через Средство просмотра трассировок службы (SvcTraceViewer.exe).

На следующей диаграмме на левой панели выбрано ранее созданное действие «Добавить запрос». Он указан с тремя другими операциями математических действий (деление, вычитание, умножение), которые составляют программу клиента приложения. Пользовательский код определил одну новую активность для каждой операции, чтобы изолировать потенциальные проявления ошибок в разных запросах.

Чтобы продемонстрировать использование передачи данных в примере Расширение трассировки, также создается действие калькулятора, которое инкапсулирует четыре запроса операций. Для каждого запроса происходит передача туда-обратно от действия калькулятора к действию запроса (трассировка выделена на правой верхней панели рисунка).

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

Это действие показывает следующий порядок обработки:

  1. Клиент отправляет сообщение в Add.

  2. Служба получает сообщение о добавлении запроса.

  3. Сервис отправляет ответ на добавление.

  4. Клиент получает ответ о добавлении.

Все эти следы были созданы на информационном уровне. Кликнув на след в правой верхней панели, вы увидите подробности этого следа на нижней правой панели.

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

Средство просмотра трассировки: создание трассировок пользовательского кода Список действий по времени создания (левая панель) и вложенные действия (верхняя правая панель)

Если код службы вызывает исключение, которое приводит к тому, что клиент также создает исключение (например, если клиент не получил ответ на запрос), сообщения об ошибке службы и клиента возникают в одном действии для прямой корреляции. На следующем изображении служба создает исключение, которое утверждает, что служба отказывается обрабатывать этот запрос в пользовательском коде. Клиент также создает исключение, которое указывает, что сервер не смог обработать запрос из-за внутренней ошибки.

Следующие изображения показывают, что ошибки в конечных точках для данного запроса отображаются в той же активности, если идентификатор действия запроса был передан.

Снимок экрана, показывающий ошибки на конечных точках для данного запроса.

При двойном щелчке на действии "Умножение" в левой панели отображается следующий график с трассировками для каждого процесса, связанного с действием "Умножение". Сначала в службе было выброшено исключение, за которыми следуют предупреждения и ошибки на стороне клиента, поскольку запрос не удалось обработать. Таким образом, мы можем предполагать причинно-следственную связь между конечными элементами и выявить основную причину ошибки.

На следующем рисунке показано представление графа корреляции ошибок:

Снимок экрана: представление графа корреляции ошибок.

Чтобы получить предыдущие трассировки, мы устанавливаем ActivityTracing для источников трассировки пользователей и propagateActivity=true источника System.ServiceModel трассировки. Мы не установили ActivityTracing для источника System.ServiceModel трассировки, чтобы обеспечить распространение активности пользовательского кода. (Если трассировка действий ServiceModel включена, идентификатор действия, определенный в клиенте, не распространяется до пользовательского кода службы. Однако переносы сопоставляют действия клиента и пользователя службы с промежуточными действиями WCF.)

Определение действий и распространение идентификатора действия позволяет нам выполнять прямую корреляцию ошибок между конечными точками. Таким образом, мы можем быстро найти первопричину ошибки.

См. также