Monitorar logs em aplicativos de contêiner do Azure com o Log Analytics

Azure Container Apps integra-se com Azure Monitor Log Analytics para o ajudar a monitorizar e analisar os registos da sua aplicação container. Quando seleciona esta solução para monitorização de logs, o seu ambiente Container Apps inclui um espaço de trabalho de Log Analytics que fornece um local comum para armazenar dados de registos do sistema e aplicações de todas as aplicações de contentores a correr no ambiente.

Pode aceder a entradas de registo consultando tabelas Log Analytics através do portal Azure ou de um shell de comandos usando o CLI do Azure.

O Azure Container Apps fornece três tipos de registos para o ajudar a monitorizar e resolver problemas:

  • Logs de console: seu aplicativo gera esses logs.
  • Logs do sistema: o serviço Aplicativos de contêiner gera esses logs.
  • Registos HTTP: A camada de entrada emite estes registos quando o registo HTTP está ativado através das definições de diagnóstico.

Registos do sistema

O serviço Container Apps fornece mensagens de registo do sistema ao nível da aplicação em contentor. Os logs do sistema emitem as seguintes mensagens:

Origem Tipo Mensagem
Dapr Informações Componente dapr <component-name> criado com êxito com o âmbito <dapr-component-scope>
Dapr Informações Nome do componente <> dapr atualizado com êxito com o tipo de componente de escopo <>
Dapr Erro Erro ao criar o componente Dapr <component-name>
Montagens de volume Informações Volume <volume-name> montado com êxito para a revisão <revision-scope>
Montagens de volume Erro Erro ao montar o volume <volume-name>
Vinculação de domínio Informações Domínio de domínio <vinculado com êxito ao nome do aplicativo de >contêiner<>
Autenticação Informações Autenticação ativada na aplicação. Criando configuração de autenticação
Autenticação Informações Configuração de autenticação criada com êxito
Peso do tráfego Informações A definir uma percentagem de tráfego de <percentagem>% para a revisão <revision-name\>
Aprovisionamento de revisões Informações Criando uma nova revisão: <nome da revisão>
Aprovisionamento de revisões Informações Nome da revisão <provisionada com êxito>
Aprovisionamento de revisões Informações Desativando revisões antigas desde 'ActiveRevisionsMode=Single'
Aprovisionamento de revisões Erro Erro no provisionamento da revisão <revision-name>. ErrorCode: <[ErrImagePull]|[ Tempo limite]|[ContainerCrashing]>

Pode aceder aos dados do registo do sistema consultando a ContainerAppSystemLogs_CL tabela. As colunas específicas de Aplicações de Contentor mais frequentemente usadas na tabela são:

Coluna Descrição
ContainerAppName_s Nome do aplicativo de contêiner
EnvironmentName_s Nome do ambiente de aplicativos de contêiner
Log_s Mensagem de log
RevisionName_s Nome da revisão

Registos da consola

Os registos da consola provêm das mensagens stderr e stdout dos contentores na sua aplicação de contentores e dos sidecars do Dapr. Você pode visualizar os logs do console consultando a ContainerAppConsoleLogs_CL tabela.

Sugestão

Instrumentar o seu código com mensagens de registo bem definidas pode ajudá-lo a perceber o desempenho do seu código e a depurar problemas. Para saber mais sobre as melhores práticas, consulte Design para operações.

As colunas específicas do Container Apps mais utilizadas em ContainerAppConsoleLogs_CL incluem:

Coluna Descrição
ContainerAppName_s Nome do aplicativo de contêiner
ContainerGroupName_g Nome da réplica
ContainerId_s Identificador de contêiner
ContainerImage_s Nome da imagem do contêiner
EnvironmentName_s Nome do ambiente de aplicativos de contêiner
Log_s Mensagem de log
RevisionName_s Nome da revisão

Registos HTTP

O Azure Container Apps pode emitir logs HTTP usando as definições de diagnóstico do Azure Monitor no ambiente gerido do Container Apps.

Utilize registos HTTP para inspecionar o volume de pedidos, caminhos, métodos e resultados de resposta ao diagnosticar o comportamento da API e do tráfego web.

O ContainerAppHTTPLogs esquema contém os seguintes campos e descrições:

Campo Tipo Descrição
Pedido
Method cadeia (de caracteres) Método de pedido HTTP (por exemplo, GET, POST).
Path cadeia (de caracteres) Caminho do pedido, incluindo a string de consulta. Valores sensíveis como tokens ou chaves API podem aparecer aqui se os seus clientes os passarem na consulta, por isso trate em conformidade.
Authority cadeia (de caracteres) O cabeçalho HTTP Host (ou pseudo-cabeçalho HTTP/2 :authority ) enviado pelo cliente.
Protocol cadeia (de caracteres) Versão do protocolo observada no ingresso, uma de HTTP/1.1, HTTP/2 ou HTTP/3.
UserAgent cadeia (de caracteres) Cabeçalho do cliente User-Agent.
XForwardedFor cadeia (de caracteres) Cadeia de IP do cliente a partir do X-Forwarded-For cabeçalho. Contém IPs dos utilizadores finais, por isso trate como PII.
BytesReceived long Tamanho do corpo do pedido recebido do cliente, em bytes(%BYTES_RECEIVED%).
Resposta
StatusCode int Código de estado de resposta HTTP devolvido ao cliente. 0 indica que o cliente se desconectou antes do início da resposta(%RESPONSE_CODE%).
ResponseCodeDetails cadeia (de caracteres) Pequeno token a explicar quem definiu o código de estado e porquê. Por exemplo, via_upstream, direct_response, route_not_found, upstream_per_try_timeout(lista completa).
ResponseFlags cadeia (de caracteres) Um ou mais códigos curtos que descrevem condições ao nível do transporte. Por exemplo, - (nenhum), UH (sem upstream saudável), UT (timeout do upstream), NR (sem rota) (lista completa).
BytesSent long Tamanho do corpo da resposta enviado ao cliente, em bytes(%BYTES_SENT%).
Temporização
StartTime datetime O ingress Time (UTC) começou a processar a solicitação(%START_TIME%).
RequestDuration long Tempo total, em milissegundos, desde o início do pedido até ao último byte de resposta enviado(%DURATION%).
Identifiers
RequestId cadeia (de caracteres) Solicite ID de correlação. Reflete o x-request-id cabeçalho se o cliente forneceu um; caso contrário, o ingress gera um valor. Não é garantido que seja um UUID.
ConnectionId cadeia (de caracteres) Identificador da ligação downstream na qual este pedido foi recebido. Múltiplos pedidos na mesma ligação partilham este valor(%CONNECTION_ID%).
Aplicação / Roteamento
ContainerAppName cadeia (de caracteres) A aplicação Container que tratou do pedido.
RevisionName cadeia (de caracteres) Revisão da aplicação Container que serviu o pedido.
ReplicaName cadeia (de caracteres) Réplica (pod) que processou a solicitação.
EnvironmentName cadeia (de caracteres) Ambiente de Aplicações Container que hospeda a aplicação.
Ascendente
UpstreamHost cadeia (de caracteres) Endereço (IP:port) do endpoint a montante que processou o pedido(%UPSTREAM_HOST%).
UpstreamRequestAttemptCount int Número de vezes que a solicitação foi tentada a montante, incluindo novas tentativas. 0 significa que nunca foi tentado.
Diagnóstico de entrada
EnvoyPodName cadeia (de caracteres) Nome do pod de ingresso que produziu este registo. Útil para correlacionar registos de entrada durante a investigação de incidentes.
EnvoyContainerId cadeia (de caracteres) ID do contentor da instância de entrada. Útil para correlacionar registos de entrada durante a investigação de incidentes.

Note

Depois de ativares os registos HTTP, pode demorar vários minutos até aparecer a tabela ContainerAppHTTPLogs no Log Analytics.

Consultar os registos HTTP no Log Analytics

Use primeiro as seguintes consultas focadas na triagem e depois os exemplos adicionais de análise que se seguem.

Ver erros HTTP recentes

Use esta consulta quando vir taxas de erro elevadas nos seus painéis, quando os clientes reportarem falhas ou quando quiser uma triagem rápida do que está a falhar neste momento.

ContainerAppHTTPLogs
| where TimeGenerated > ago(1h)
| where StatusCode >= 400
| project TimeGenerated, ContainerAppName, RevisionName, Method, Path,
  StatusCode, ResponseCodeDetails, RequestDuration, RequestId
| order by TimeGenerated desc
| take 100

Sugestão

Verifica ResponseCodeDetails porque é que um pedido falhou. Por exemplo, route_not_found indica uma configuração incorreta de encaminhamento, enquanto via_upstream significa que o contentor devolveu o erro.

Localizar solicitações lentas

Use esta consulta quando a sua aplicação parecer lenta, estiver a investigar uma queixa de latência ou quiser verificar uma correção de desempenho.

ContainerAppHTTPLogs
| where TimeGenerated > ago(1h)
| where ContainerAppName == "<app-name>"
| top 50 by RequestDuration desc
| project TimeGenerated, Method, Path, StatusCode, RequestDuration,
  ReplicaName, UpstreamRequestAttemptCount, RequestId

Sugestão

RequestDuration é indicado em milissegundos. Se vires valores elevados juntamente com UpstreamRequestAttemptCount > 1, o pedido foi tentado novamente, o que aumenta o tempo total.

Acompanhar o volume de pedidos e a taxa de erro por revisão

Usa esta consulta depois de implementares uma nova revisão e quereres confirmar que está saudável, ou estás a fazer um rollout azul/verde e queres comparar duas revisões lado a lado.

ContainerAppHTTPLogs
| where TimeGenerated > ago(6h)
| where ContainerAppName == "<app-name>"
| summarize Requests = count(),
  Errors = countif(StatusCode >= 500),
  ErrorRatePct = round(100.0 * countif(StatusCode >= 500) / count(), 2),
  P95DurationMs = percentile(RequestDuration, 95)
  by RevisionName, bin(TimeGenerated, 5m)
| order by TimeGenerated desc
| render timechart

Sugestão

Uma nova revisão que começa subitamente a processar pedidos 0 geralmente indica um problema na ponderação do tráfego na sua configuração de ingress. Uma nova revisão com uma taxa de erro ou P95 superior à da anterior é uma regressão de implantação; considere reverter.

Rastrear um único pedido de ponta a ponta

Utilize esta consulta quando um cliente reportar uma transação específica com falha e lhe fornecer o ID do pedido (o valor do cabeçalho x-request-id que viu). Precisas de encontrar esse pedido exato e quaisquer registos de aplicações relacionados.

let _requestId = "<request-id>";
ContainerAppHTTPLogs
| where TimeGenerated > ago(24h)
| where RequestId == _requestId
| project TimeGenerated, ContainerAppName, RevisionName, ReplicaName,
  Method, Path, StatusCode, ResponseCodeDetails, ResponseFlags,
  RequestDuration, UpstreamHost, UserAgent, XForwardedFor

Sugestão

Depois de teres o ReplicaName da linha acima, faz a junção com ContainerAppConsoleLogs_CL filtrado pela mesma réplica e por uma pequena janela temporal em torno de TimeGenerated para veres as linhas de registo da tua aplicação para esse pedido.

Identifique os seus principais endpoints com falhas

Utilize esta consulta quando encontrar muitos erros, mas não souber por onde começar. Esta consulta revela quais os caminhos responsáveis pelo maior número de falhas, para que possa priorizar correções por impacto.

ContainerAppHTTPLogs
| where TimeGenerated > ago(24h)
| where StatusCode >= 400
| summarize Errors = count(),
  DistinctClientIPs = dcount(XForwardedFor),
  SampleStatusCodes = make_set(StatusCode, 5),
  ExampleDetails = take_any(ResponseCodeDetails)
  by ContainerAppName, Method, Path
| order by Errors desc
| take 20

Sugestão

Um número elevado de DistinctClientIPs a par dos erros sugere um problema real com impacto generalizado. Um valor baixo normalmente indica um único cliente com comportamento anómalo (por exemplo, um digitalizador ou um ciclo de novas tentativas com falhas).

Inspecionar registos recentes de log HTTP

Utilize esta consulta para inspecionar entradas recentes do registo HTTP:

ContainerAppHTTPLogs
| where TimeGenerated > ago(2h)
| project TimeGenerated, Method, Path, StatusCode, ContainerAppName, EnvironmentName
| order by TimeGenerated desc
| take 100

Use os seguintes exemplos para cenários comuns de análise de logs HTTP.

Distribuição dos códigos de estado

ContainerAppHTTPLogs
| where TimeGenerated > ago(24h)
| summarize Count = count() by toint(StatusCode)
| order by Count desc

Vista centrada nos erros (4xx/5xx)

ContainerAppHTTPLogs
| where TimeGenerated > ago(2h)
| extend StatusCodeInt = toint(StatusCode)
| where StatusCodeInt >= 400
| project
    Time=TimeGenerated,
    StatusCode=StatusCodeInt,
    Method,
    Path,
    Details=ResponseCodeDetails,
    EnvName=EnvironmentName,
    AppName=ContainerAppName,
    Revision=RevisionName
| top 100 by Time desc

Latência (P50/P95/P99) por aplicação e caminho

ContainerAppHTTPLogs
| where TimeGenerated > ago(2h)
| summarize
    Requests = count(),
    P50 = percentile(RequestDuration, 50),
    P95 = percentile(RequestDuration, 95),
    P99 = percentile(RequestDuration, 99)
  by ContainerAppName, Path
| order by P95 desc

Consultar registos com Log Analytics

O Log Analytics é uma ferramenta no portal do Azure que você pode usar para exibir e analisar dados de log. Ao usar o Log Analytics, pode escrever consultas Kusto e depois ordenar, filtrar e visualizar os resultados em gráficos para detetar tendências e identificar problemas. Você pode trabalhar interativamente com os resultados da consulta ou usá-los com outros recursos, como alertas, painéis e pastas de trabalho.

portal do Azure

Inicie o Log Analytics a partir de Logs no menu da barra lateral na página do seu aplicativo de contêiner. Também pode começar Log Analytics a partir de Monitor > Logs.

Consulte os registos usando as tabelas listadas na categoria Registos Personalizados no separador Tabelas . As tabelas desta categoria são ContainerAppSystemLogs_CL e ContainerAppConsoleLogs_CL.

Captura de ecrã da página de consulta Log Analytics mostrando tabelas de registo personalizadas.

A consulta Kusto a seguir exibe entradas de log do console para o aplicativo de contêiner chamado album-api.

ContainerAppConsoleLogs_CL
| where ContainerAppName_s == 'album-api'
| project Time=TimeGenerated, AppName=ContainerAppName_s, Revision=RevisionName_s, Container=ContainerName_s, Message=Log_s
| take 100

A consulta Kusto a seguir exibe entradas de log do sistema para o aplicativo de contêiner chamado album-api.

ContainerAppSystemLogs_CL
| where ContainerAppName_s == 'album-api'
| project Time=TimeGenerated, EnvName=EnvironmentName_s, AppName=ContainerAppName_s, Revision=RevisionName_s, Message=Log_s
| take 100

Para mais informações sobre o Log Analytics e as consultas de registos, consulte o tutorial do Log Analytics.

CLI do Azure ou PowerShell

Pode consultar os registos de Aplicações Container usando CLI do Azure.

Estes exemplos de consultas da CLI do Azure geram uma tabela contendo registros de log para o nome do aplicativo contêiner album-api. Os parâmetros após o project operador especificam as colunas da tabela. A variável $WORKSPACE_CUSTOMER_ID tem o GUID do espaço de trabalho Log Analytics.

Este exemplo consulta a ContainerAppConsoleLogs_CL tabela:

az monitor log-analytics query --workspace $WORKSPACE_CUSTOMER_ID --analytics-query "ContainerAppConsoleLogs_CL | where ContainerAppName_s == 'album-api' | project Time=TimeGenerated, AppName=ContainerAppName_s, Revision=RevisionName_s, Container=ContainerName_s, Message=Log_s, LogLevel_s | take 5" --out table

Este exemplo consulta a ContainerAppSystemLogs_CL tabela:

az monitor log-analytics query --workspace $WORKSPACE_CUSTOMER_ID --analytics-query "ContainerAppSystemLogs_CL | where ContainerAppName_s == 'album-api' | project Time=TimeGenerated, AppName=ContainerAppName_s, Revision=RevisionName_s, Message=Log_s, LogLevel_s | take 5" --out table

Próximos passos