Monitorar funções do Azure e Hubs de Eventos

Azure Event Hubs
Azure Functions
Azure Monitor

O monitoramento fornece informações sobre o comportamento e a integridade de seus sistemas e ajuda a construir uma visão holística do ambiente, tendências históricas, correlacionar diversos fatores e medir mudanças no desempenho, consumo ou taxa de erro.

O Azure Functions oferece integração interna com o Application Insights. No Application Insights, você pode obter informações como o número de instâncias de aplicativo de função ou telemetria de solicitação e dependência de uma função. Ao trabalhar com Funções e Hubs de Eventos, o Application Insights também pode rastrear as telemetrias de dependência de saída para o hub de eventos, calculando o tempo de processamento e mostrando o fluxo de ponta a ponta do sistema conectado por meio de Hubs de Eventos.

Esta seção apresenta recursos e informações úteis que você pode obter do Application Insights para sua solução Hubs de Eventos e Funções.

Mapeamento de Aplicações

O Mapa de Aplicativos mostra como os componentes de um sistema estão interagindo uns com os outros. Devido à telemetria de dependência que o Application Insights fornece, ele mapeia o fluxo de eventos entre o Azure Functions e os Hubs de Eventos, incluindo a média de cada execução de função e a duração média de um evento nos Hubs de Eventos, além de mostrar transações que contêm falhas marcadas em vermelho.

Depois de enviar a carga esperada para o seu sistema, você pode ir para o Application Insights no portal do Azure e, na barra lateral, escolher Mapa do Aplicativo. Aqui está um mapa que mostra três funções, três hubs de eventos e falhas aparentes ao gravar em um banco de dados downstream:

Mapeamento de Aplicações

Detalhes da transação ponto a ponto

Os detalhes da transação de ponta a ponta mostram como os componentes do sistema interagem uns com os outros, em ordem cronológica. Esta vista também mostra quanto tempo um evento passou a processar. Você também pode detalhar a telemetria de cada componente a partir dessa exibição, o que facilita a solução de problemas entre componentes dentro da mesma solicitação quando ocorre um problema.

Transação de ponta a ponta

Métricas e telemetria da plataforma

As métricas geradas pela plataforma no Azure Monitor for Event Hubs e Azure Functions podem ser usadas para o monitoramento geral do comportamento e da integridade da solução:

O Azure Functions integra-se com o Application Insights para fornecer telemetria avançada e detalhada e informações sobre o host do Functions e as execuções de funções. Para saber mais, consulte Analisar telemetria do Azure Functions no Application Insights. Ao usar o Application Insights para monitorar uma topologia, há uma variedade de configurações disponíveis. Para saber mais, consulte Como configurar o monitoramento para o Azure Functions.

Veja a seguir um exemplo de telemetria extra para funções acionadas por Hubs de Eventos geradas na tabela de rastreamentos:

Trigger Details: PartionId: 6, Offset: 3985758552064-3985758624640, EnqueueTimeUtc: 2022-10-31T12:51:58.1750000+00:00-2022-10-31T12:52:03.8160000+00:00, SequenceNumber: 3712266-3712275, Count: 10

Essas informações exigem que você use a extensão de Hubs de Eventos 4.2.0 ou uma versão posterior. Esses dados são muito úteis, pois contêm informações sobre a mensagem que disparou a execução da função e podem ser usados para consultas e insights. Inclui os seguintes dados para cada vez que a função é acionada:

  • O ID da partição (6)
  • O intervalo de deslocamento da partição (3985758552064-3985758624640)
  • O intervalo de tempo de Enqueue em UTC (2022-10-31T12:51:58.1750000+00:00-2022-10-31T12:52:03.8160000+00:00)
  • O intervalo de números sequenciais 3712266-3712275
  • E a contagem de mensagens (10)

Consulte a seção Exemplos de consultas do Application Insights para obter exemplos sobre como usar essa telemetria.

A telemetria personalizada também é possível para diferentes linguagens (biblioteca de classes C#, C# Isolated, C# Script, JavaScript, Java, PowerShell e Python). Esse log aparece na tabela de rastreamentos no Application Insights. Você pode criar suas próprias entradas no Application Insights e adicionar dimensões personalizadas que podem ser usadas para consultar dados e criar painéis personalizados.

Finalmente, quando seu aplicativo de função se conecta a um hub de eventos usando uma associação de saída, as entradas também são gravadas na tabela Dependências do Application Insights.

Tabela de dependências

Para Hubs de Eventos, a correlação é injetada na carga útil do evento e você vê uma propriedade Diagnostic-Id em eventos:

Propriedade Diagnostic Id

Isso segue o formato W3C Trace Context que também é usado como Operation Id e Operation Links na telemetria criada pelo Functions, que permite que o Application Insights construa a correlação entre eventos do hub de eventos e execuções de funções, mesmo quando eles são distribuídos.

Correlação de eventos em lote

Exemplo de consultas do Application Insights

Abaixo está uma lista de consultas úteis do Application Insights ao monitorar Hubs de Eventos com o Azure Functions. Esta consulta exibe informações detalhadas para a função acionada pelo hub de eventos usando telemetria emitida pela extensão 4.2.0 e superior dos Hubs de Eventos.

Quando a amostragem é habilitada no Application Insights, pode haver lacunas nos dados.

Informações detalhadas sobre o processamento de eventos

Os dados só são emitidos no formato correto quando o envio em lote é usado. Despacho em lote significa que a função aceita vários eventos para cada execução, o que é recomendado para desempenho. Não se esqueça das seguintes considerações:

  • O dispatchTimeMilliseconds valor aproxima o período de tempo entre quando o evento foi gravado no hub de eventos e quando foi captado pelo aplicativo de função para processamento.
  • dispatchTimeMilliseconds pode ser negativo ou impreciso devido ao desvio de relógio entre o servidor do hub de eventos e o aplicativo de função.
  • As partições dos Hubs de Eventos são processadas sequencialmente. Uma mensagem não será enviada para o código de função para processamento até que todas as mensagens anteriores tenham sido processadas. Monitore o tempo de execução de suas funções, pois tempos de execução mais longos causarão atrasos de envio.
  • O cálculo usa o enqueueTime da primeira mensagem no lote. Os tempos de envio podem ser menores para outras mensagens no lote.
  • dispatchTimeMilliseconds baseia-se no ponto no tempo.
  • Os números de sequência são por partição e o processamento duplicado pode ocorrer porque os Hubs de Eventos não garantem a entrega exata de uma mensagem.
traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| extend dispatchTimeMilliseconds = (timestamp - enqueueTimeStart) / 1ms
| project timestamp, cloud_RoleInstance, operation_Name, processId =
customDimensions.ProcessId, partitionId, messageCount, sequenceNumberStart,
sequenceNumberEnd, enqueueTimeStart, enqueueTimeEnd, dispatchTimeMilliseconds

Processamento detalhado de eventos

Visualização de latência de despacho

Esta consulta visualiza a latência de envio de eventos dos percentis 50 e 90 para uma determinada função acionada do hub de eventos. Consulte a consulta acima para obter mais detalhes e notas.

traces
| where operation_Name == "<ENTER THE NAME OF YOUR FUNCTION HERE>"
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| extend dispatchTimeMilliseconds = (timestamp - enqueueTimeStart) / 1ms
| summarize percentiles(dispatchTimeMilliseconds, 50, 90) by bin(timestamp, 5m)
| render timechart

Visualização de latência de despacho

Resumo da latência de envio

Esta consulta é semelhante à anterior, mas mostra uma vista de resumo.

traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| extend dispatchTimeMilliseconds = (timestamp - enqueueTimeStart) / 1ms
| summarize messageCount = sum(messageCount),
percentiles(dispatchTimeMilliseconds, 50, 90, 99, 99.9, 99.99) by operation_Name

Resumo da latência de envio

Distribuição de mensagens entre partições

Esta consulta mostra como visualizar a distribuição de mensagens entre partições.

traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| summarize messageCount = sum(messageCount) by cloud_RoleInstance,
bin(timestamp, 5m)
| render areachart kind=stacked

Distribuição de mensagens entre partições

Distribuição de mensagens entre instâncias

Esta consulta mostra como visualizar a distribuição de mensagens entre instâncias.

traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| summarize messageCount = sum(messageCount) by cloud_RoleInstance,
bin(timestamp, 5m)
| render areachart kind=stacked

Distribuição de mensagens entre instâncias

Executando instâncias e instâncias alocadas

Esta consulta mostra como visualizar o número de instâncias do Azure Functions que estão processando eventos de Hubs de Eventos e o número total de instâncias (processando e aguardando concessão). Na maioria das vezes devem ser os mesmos.

traces
| where message startswith "Trigger Details: Parti"
| summarize type = "Executing Instances", Count = dcount(cloud_RoleInstance) by
bin(timestamp, 60s)
| union (
    traces
    | summarize type = "Allocated Instances", Count = dcount(cloud_RoleInstance) by
bin(timestamp, 60s)
)
| project timestamp, type, Count
| render timechart

Executando instâncias e instâncias alocadas

Toda a telemetria para uma execução de função específica

O campo operation_Id pode ser usado nas diferentes tabelas do Application Insights. Para Hubs de Eventos acionados pelo Azure Functions, a consulta a seguir, por exemplo, resultará nas informações de gatilho, telemetria de logs dentro do código de Função e dependências e exceções:

union isfuzzy=true requests, exceptions, traces, dependencies
| where * has "<ENTER THE OPERATION_ID OF YOUR FUNCTION EXECUTION HERE>"
| order by timestamp asc

Toda a telemetria para uma execução de função específica

Latência de ponta a ponta para um evento

Como a propriedade enqueueTimeUtc no rastreamento de detalhes do gatilho mostra o tempo de enfila apenas do primeiro evento de cada lote processado pela função, uma consulta mais avançada pode ser usada para calcular a latência de ponta a ponta de eventos entre duas funções com Hubs de Eventos intermediários. Esta consulta expandirá os links de operação (se houver) na solicitação da segunda função e mapeará sua hora de término para o mesmo ID de operação correspondente da hora de início da primeira função.

let start = view(){
requests
| where operation_Name == "FirstFunction"
| project start_t = timestamp, first_operation_Id = operation_Id
};
let link = view(){
requests
| where operation_Name == "SecondFunction"
| mv-expand ex = parse_json(tostring(customDimensions["_MS.links"]))
| extend parent = case(isnotempty(ex.operation_Id), ex.operation_Id, operation_Id )
| project first_operation_Id = parent, second_operation_Id = operation_Id
};
let finish = view(){
traces
| where customDimensions["EventName"] == "FunctionCompleted" and operation_Name
== "SecondFunction"
| project end_t = timestamp, second_operation_Id = operation_Id
};
start
| join kind=inner (
link
| join kind=inner finish on second_operation_Id
) on first_operation_Id
| project start_t, end_t, first_operation_Id, second_operation_Id
| summarize avg(datetime_diff('second', end_t, start_t))

Latência de ponta a ponta para um evento

Contribuidores

Este artigo é mantido pela Microsoft. Foi originalmente escrito pelos seguintes contribuidores.

Autor principal:

  • David Barkol - Brasil | Especialista Principal de Soluções GBB

Para ver perfis não públicos do LinkedIn, inicie sessão no LinkedIn.

Próximos passos

Para saber mais, considere rever estes artigos relacionados: