Диагностика и устранение неполадок в Устойчивые функции

Устойчивые функции предоставляют несколько средств диагностики для отладки оркестраций. В этой статье описывается, как настроить отслеживание и ведение журнала, писать код, безопасный для воспроизведения, анализировать распределенные трассировки и производить локальную отладку.

В этой статье вы узнаете, как:

Настройка отслеживания в Application Insights

Application Insights — это рекомендуемый способ мониторинга устойчивых функций. Расширение Durable выдает события отслеживания, которые позволяют вам отслеживать сквозное выполнение оркестрации. Эти события отслеживания можно найти и запросить с помощью средства Application Insights Analytics на портале Azure.

Настройка уровня логирования

Настройте детализацию данных отслеживания, создаваемых Application Insights в файле host.json

{
    "logging": {
        "logLevel": {
            "Host.Triggers.DurableTask": "Information",
        },
    }
}

По умолчанию генерируются все события отслеживания, не связанные с воспроизведением. Вы можете уменьшить объем данных, установив Host.Triggers.DurableTask в "Warning" или "Error", что означает, что события отслеживания отправляются только для исключительных ситуаций. Чтобы включить выдачу подробных событий воспроизведения оркестрации, задайте значение logReplayEventstrue в файле конфигурации host.json .

Замечание

По умолчанию среда выполнения Функции Azure выборочно собирает данные телеметрии Application Insights, чтобы избежать их слишком частого отправления. Выборка может привести к потере данных отслеживания, когда много событий жизненного цикла происходит в течение короткого периода времени. В статье "Мониторинг функций Azure " объясняется, как настроить это поведение.

Ведение журнала входных и выходных данных

По умолчанию входные значения и выходные значения функции оркестратора, действия и сущности не регистрируются. Этот подход рекомендуется, поскольку журналирование входных и выходных данных может увеличить затраты на использование Application Insights. Входная и выходная нагрузка функции также могут содержать конфиденциальную информацию. Вместо этого регистрируется количество байтов для входных и выходных данных функции. Если вы хотите, чтобы расширение Устойчивые функции регистрировало всю полезную нагрузку входных и выходных данных, установите значение traceInputsAndOutputs для свойства true в файле конфигурации host.json.

Экземпляры оркестрации запросов

Используйте следующие запросы Kusto в Application Insights Analytics для проверки экземпляров оркестрации процессов.

Запрос одного экземпляра

В следующем запросе показаны исторические данные отслеживания для одного экземпляра управления функцией Hello Sequence. Он фильтрует выполнение воспроизведения таким образом, чтобы отображалось только логический путь выполнения. События можно упорядочить, отсортируя по timestampsequenceNumber и как показано в следующем запросе:

let targetInstanceId = "ddd1aaa685034059b545eb004b15d4eb";
let start = datetime(2018-03-25T09:20:00);
traces
| where timestamp > start and timestamp < start + 30m
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = customDimensions["prop__functionName"]
| extend instanceId = customDimensions["prop__instanceId"]
| extend state = customDimensions["prop__state"]
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend sequenceNumber = tolong(customDimensions["prop__sequenceNumber"])
| where isReplay != true
| where instanceId == targetInstanceId
| sort by timestamp asc, sequenceNumber asc
| project timestamp, functionName, state, instanceId, sequenceNumber, appName = cloud_RoleName

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

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

Сводный запрос экземпляра

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

let start = datetime(2017-09-30T04:30:00);
traces
| where timestamp > start and timestamp < start + 1h
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = tostring(customDimensions["prop__functionName"])
| extend instanceId = tostring(customDimensions["prop__instanceId"])
| extend state = tostring(customDimensions["prop__state"])
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend output = tostring(customDimensions["prop__output"])
| where isReplay != true
| summarize arg_max(timestamp, *) by instanceId
| project timestamp, instanceId, functionName, state, output, appName = cloud_RoleName
| order by timestamp asc

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

Снимок экрана: Application Insights с результатами сводного запроса одного экземпляра с идентификаторами экземпляров и состоянием.

Справочник по данным отслеживания

Каждый экземпляр оркестрации создает события отслеживания по мере прохождения своего жизненного цикла. Каждое событие жизненного цикла содержит полезную нагрузку customDimensions с несколькими полями. Названия полей начинаются с prop__.

Имя поля Описание
hubName Имя концентратора задач, в котором выполняются ваши оркестрации.
appName Имя приложения-функции. Это поле полезно, когда у вас есть несколько функциональных приложений, использующих один экземпляр Application Insights.
slotName Слот развертывания, в котором запущено текущее приложение-функция. Это поле полезно при использовании слотов развертывания для управления версиями оркестраций.
functionName Имя функции оркестратора или действия.
functionType Тип функции, например Orchestrator или Activity.
instanceId Уникальный идентификатор экземпляра оркестрации.
state Состояние выполнения жизненного цикла экземпляра.
state.Scheduled Функция была запланирована для выполнения, но еще не запущена.
state.Started Функция запущена, но еще не ожидалась или завершена.
state.Awaited Оркестратор запланировал некоторую работу и ожидает завершения.
state.Listening Оркестратор прослушивает уведомление о внешних событиях.
state.Completed Функция успешно завершена.
state.Failed Функция завершилась с ошибкой.
reason Дополнительные данные, связанные с событием отслеживания. Например, если экземпляр ожидает уведомления о внешнем событии, это поле указывает имя события, которого он ожидает. Если функция завершается ошибкой, это поле содержит сведения об ошибке.
isReplay Логическое значение, указывающее, является ли событие отслеживания для повторного выполнения.
extensionVersion Версия расширения устойчивых задач. Информация о версии особенно важна при создании отчетов о потенциальных ошибках в расширении. Длительно работающие экземпляры могут сообщать о нескольких версиях, если обновление происходит во время их работы.
sequenceNumber Порядковый номер выполнения для события. В сочетании с меткой времени это помогает упорядочить события по времени выполнения. Обратите внимание, что это число сбрасывается до нуля, если хост перезапускается во время выполнения экземпляра, поэтому важно всегда сначала сортировать по метке времени, а затем по номеру последовательности.

Ведение журнала платформы устойчивых задач (DTFx)

Журналы расширений Durable полезны для понимания поведения логики оркестрации. Однако эти журналы не всегда содержат достаточно сведений для отладки проблем с производительностью и надежностью платформы. Начиная с версии 2.3.0 расширения Durable, журналы, создаваемые базовой платформой Durable Task (DTFx), также доступны для сбора.

При просмотре журналов, создаваемых DTFx, важно понимать, что подсистема DTFx имеет два компонента: ядро диспетчера (DurableTask.Core) и один из многих поддерживаемых поставщиков хранилища.

Компонент Описание
DurableTask.Core Основное выполнение функций оркестрации и журналы низкоуровневого планирования и данные телеметрии.
DurableTask.DurableTaskScheduler Внутренние журналы, относящиеся к планировщику долговременных задач.
DurableTask.AzureStorage Внутренние журналы, относящиеся к поставщику состояния служба хранилища Azure. Эти журналы включают подробное взаимодействие с внутренними блобами, таблицами хранения и очередями, используемыми для хранения и извлечения внутреннего состояния оркестрации.
DurableTask.Netherite Серверные журналы, относящиеся к поставщику хранилища Netherite, если он включен.
DurableTask.SqlServer Серверные журналы, относящиеся к поставщику хранилища Microsoft SQL (MSSQL), если они включены.

Эти журналы можно включить, обновив logging/logLevel раздел host.json файла приложения-функции. В следующем примере показано, как включить журналы предупреждений и ошибок из обоих DurableTask.Core и DurableTask.AzureStorage:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  }
}

Если вы включили Application Insights, эти журналы автоматически добавляются в коллекцию trace . Вы можете искать их так же, как и другие журналы, с помощью запросов Kusto.

Замечание

Для рабочих приложений рекомендуется включить DurableTask.Core и соответствующие журналы поставщика хранилища (например, DurableTask.AzureStorage) с помощью "Warning" фильтра. Более подробные фильтры, такие как "Information", полезны для отладки проблем с производительностью. Однако эти события журнала могут быть большим объемом и могут значительно увеличить затраты на хранение данных Application Insights.

В следующем запросе Kusto показано, как запрашивать журналы DTFx. Наиболее важной частью запроса является where customerDimensions.Category startswith "DurableTask", поскольку именно она фильтрует результаты для журналов в категориях DurableTask.Core и DurableTask.AzureStorage.

traces
| where customDimensions.Category startswith "DurableTask"
| project
    timestamp,
    severityLevel,
    Category = customDimensions.Category,
    EventId = customDimensions.EventId,
    message,
    customDimensions
| order by timestamp asc 

Результатом является набор журналов, написанных поставщиками журналов Устойчивой платформы задач.

Снимок экрана Application Insights, показывающий результаты запроса DTFx с журналами Durable Task Framework.

Дополнительные сведения о доступных событиях журнала см. в документации по структурированному ведению журнала Durable Task Framework на GitHub.

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

Распределенная трассировка отслеживает запросы и показывает, как разные службы взаимодействуют друг с другом. В Устойчивые функции она сопоставляет оркестрации, сущности и действия вместе. Распределенная трассировка показывает время выполнения для каждого шага оркестрации в контексте всей оркестрации и определяет, где возникают проблемы или исключения. Эта функция поддерживается в Application Insights для всех языков и поставщиков хранилища.

Необходимые условия

Для распределенной трассировки требуются определенные минимальные версии расширений:

Настройка распределенной трассировки

Чтобы настроить распределенную трассировку, обновите host.json и настройте ресурс Application Insights.

host.json

{
   "extensions": {
     "durableTask": {
       "tracing": {
         "distributedTracingEnabled": true,
         "version": "V2"
       }
     }
   }
 }

Аналитика приложений

Настройте приложение-функцию с помощью ресурса Application Insights.

Проверка трассировок

В ресурсе Application Insights перейдите к поиску транзакций. В результатах найдите Request и Dependency события, начинающиеся с префиксов, специфичных для Durable (например, orchestration:, activity:, и т. д.). При выборе одного из этих событий откроется диаграмма Ганта, показывающая сквозную распределенную трассировку. На диаграмме каждый шаг оркестрации отображается в виде горизонтальной полосы, с вызовами действий и подоркестраций, вложенными в свои родительские оркестрации. Длина полосы представляет фактическую продолжительность по времени каждого шага, что позволяет легко определить блокирующие точки или неожиданно замедленные процессы.

Снимок экрана диаграммы Ганта, показывающий распределённую трассировку Application Insights с временными шкалами оркестрации и активности.

Замечание

Не отображается трассировка в Application Insights? Подождите около пяти минут после запуска приложения, чтобы убедиться, что все данные распространяются на ресурс Application Insights.

Устойчивое к повторным атакам ведение журнала в функциях оркестратора

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

Calling F1.
Calling F1.
Calling F2.
Calling F1.
Calling F2.
Calling F3.
Calling F1.
Calling F2.
Calling F3.
Done!

Чтобы предотвратить повторяющиеся строки журнала, проверьте флаг "повторное выполнение", чтобы записи в журнале происходили только на первом (неповторяющемся) проходе. В следующих примерах показано защищённое от воспроизведения журналирование на каждом языке.

Начиная с Устойчивые функции 2.0, используйте CreateReplaySafeLogger для автоматической фильтрации журнальных записей во время воспроизведения.

[FunctionName("FunctionChain")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context,
    ILogger log)
{
    log = context.CreateReplaySafeLogger(log);
    log.LogInformation("Calling F1.");
    await context.CallActivityAsync("F1");
    log.LogInformation("Calling F2.");
    await context.CallActivityAsync("F2");
    log.LogInformation("Calling F3");
    await context.CallActivityAsync("F3");
    log.LogInformation("Done!");
}

При использовании безопасного для воспроизведения журнала выходные данные журнала:

Calling F1.
Calling F2.
Calling F3.
Done!

Состояние настраиваемой оркестрации

Используйте состояние настраиваемой оркестрации, чтобы сообщить о ходе выполнения рабочего процесса внешним клиентам. Распространенные шаблоны включают проценты завершения, описания шагов и сводки ошибок. Внешние клиенты могут просматривать настраиваемое состояние с помощью API запросов состояния HTTP или вызовов API для конкретного языка.

В следующем коде показано, как задать настраиваемое значение состояния в функции оркестратора:

[FunctionName("SetStatusTest")]
public static async Task SetStatusTest([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    // ...do work...

    // update the status of the orchestration with some arbitrary data
    var customStatus = new { completionPercentage = 90.0, status = "Updating database records" };
    context.SetCustomStatus(customStatus);

    // ...do more work...
}

Замечание

Предыдущий пример C# предназначен для Устойчивые функции 2.x. Для Устойчивые функции 1.x необходимо использовать DurableOrchestrationContext вместо IDurableOrchestrationContext. Дополнительные сведения о различиях между версиями см. в статье о версиях устойчивых функций .

Во время выполнения оркестрации внешние клиенты могут получить это настраиваемое состояние:

GET /runtime/webhooks/durabletask/instances/instance123?code=XYZ

Клиенты получают следующий ответ:

{
  "runtimeStatus": "Running",
  "input": null,
  "customStatus": { "completionPercentage": 90.0, "status": "Updating database records" },
  "output": null,
  "createdTime": "2017-10-06T18:30:24Z",
  "lastUpdatedTime": "2017-10-06T19:40:30Z"
}

Предупреждение

Пользовательский статус ограничен 16 КБ текста JSON UTF-16, так как он должен помещаться в столбец Azure Table Storage. Вы можете использовать внешнее хранилище, если требуется большая полезная нагрузка.

Отладка

Функции Azure поддерживают отладку кода функции напрямую, и эта же поддержка распространяется на Устойчивые функции, независимо от того, выполняются ли они в Azure или локально. Используйте следующий рабочий процесс для оптимальной отладки:

  1. Запустите новый сеанс отладки с помощью нового концентратора задач или снимите содержимое концентратора задач между сеансами. Оставшиеся сообщения из предыдущих запусков могут привести к неожиданному повторному выполнению.

  2. Задайте точки останова в функциях оркестратора или активности. Для функций оркестратора используйте условную точку останова, которая срабатывает только в случае, если значение "повторно выполняется" равно false, чтобы избежать остановок на той же точке несколько раз во время воспроизведения.

  3. Просмотрите ваш код как обычно. Имейте в виду следующее поведение:

    • Повтор:
      Функции оркестратора регулярно повторяются при получении новых входных данных. Одно логическое выполнение функции оркестратора может привести к попаданию в одну и ту же точку останова несколько раз, особенно если она установлена в начале кода функции.

    • Ждут:
      Всякий раз, когда встречается await в функции оркестратора, она передает управление обратно диспетчеру Durable Task Framework. Если это первый случай, когда встречается конкретный await, связанная с ним задача никогда не возобновляется. Поскольку задача никогда не возобновляется, выполнить шаг over ожидания (F10 в Visual Studio) невозможно. Переход выполняется только при повторном воспроизведении задачи.

    • Время ожидания обмена сообщениями:
      Устойчивые функции внутренне используют сообщения очереди для выполнения оркестратора, действия и функций сущностей. В среде с несколькими виртуальными машинами расширенные сеансы отладки могут привести к обработке сообщения другой виртуальной машины, что приведет к дублированию выполнения. Хотя это поведение также существует для обычных функций триггера очереди, важно выделить этот контекст, поскольку очереди являются частью реализации.

    • Остановка и запуск:
      Сообщения в устойчивых функциях сохраняются между сеансами отладки. При остановке отладки и прекращении процесса локального узла во время выполнения устойчивой функции эта функция может повторно выполняться автоматически в будущем сеансе отладки.

Дополнительные инструменты

Проверка состояния хранилища

По умолчанию Устойчивые функции сохраняет состояние в служба хранилища Azure. Вы можете проверить состояние оркестрации и сообщения с помощью таких средств, как Обозреватель службы хранилища Microsoft Azure.

Скриншот Обозреватель службы хранилища Azure с состоянием оркестрации Устойчивые функции в таблицах и очередях.

Предупреждение

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

Замечание

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

инструмент мониторинга Устойчивые функции

Устойчивые функции Monitor — это графическое средство, предназначенное для мониторинга, управления и отладки оркестраций и экземпляров сущностей. Он доступен как расширение Visual Studio Code или автономное приложение. Инструкции по настройке и список функций см. в разделе Устойчивые функции Monitor Wiki.

Диагностика на портале Azure

Портал Azure предоставляет встроенные средства диагностики для функциональных приложений.

Диагностика и решение проблем: Диагностика приложений-функций Azure — это полезный ресурс для мониторинга и диагностики потенциальных проблем в приложении. Он также предоставляет рекомендации по устранению проблем на основе диагноза. Дополнительные сведения см. в разделе Диагностика приложений Azure Functions.

Трассировки оркестрации: Портал Azure предоставляет сведения о трассировках, помогающие понять состояние каждого экземпляра оркестрации и сквозное отслеживание выполнения. При просмотре списка функций в приложении Функции Azure отображается столбец Monitor, содержащий ссылки на трассировки. Для доступа к этой информации приложению необходимо включить Application Insights.

Анализатор Roslyn

Анализатор Устойчивые функции Roslyn — это анализатор динамического кода, который позволяет разработчикам C# следовать Устойчивые функции определенным ограничениям кода. См. инструкцию по включению в Visual Studio и Visual Studio Code в разделе Устойчивые функции Roslyn Analyzer.

Troubleshooting

Чтобы устранить распространенные проблемы, такие как зависание оркестрации, сбой запуска или медленное выполнение, см. руководство по устранению неполадок Устойчивые функции.

Дальнейшие действия