Solução de problemas de execução e logs de funções
Encontre a causa quando uma função nunca roda, para antes de responder ou não gera saída de log, e aplique a correção.
Uma função criada com Functions pode falhar na instanciação, na invocação ou durante a execução. Sem saída de log, você não consegue dizer qual delas. Cada seção abaixo nomeia um sintoma, dá a sua causa e declara a correção. Comece pelos logs.
Nenhuma saída de log de uma função
Você chama console.log na função e nenhuma mensagem chega até você.
Uma função escreve mensagens de log com console.log, do mesmo jeito que o JavaScript faz em um browser. A Azion coleta essa saída e a entrega em três lugares: Azion CLI, Data Stream e Real-Time Events. Até você abrir um deles, uma função que falha e uma função que nunca roda parecem iguais.
Primeiro, confirme que o código registra alguma coisa. Este handler registra uma mensagem e retorna uma resposta:
Para ler a saída no terminal com Azion CLI:
O terminal imprime as mensagens de console dos últimos 5 minutos e continua imprimindo as novas. Adicione --function-id para restringir a saída a uma função. O subcomando se chama cells porque uma função roda dentro de uma Cell, o ambiente de isolamento que a Azion constrói sobre isolates V8.
Para enviar a mesma saída a um endpoint que você controla:
Acesse Azion Console > Data Stream.
O stream envia as mensagens de log das suas funções para essa URL.
O template Functions Event Collector preenche a caixa Data Set com este preset:
| Variável | Definição |
|---|---|
$time | Data e hora da requisição. |
$client | Identificador único do cliente Azion. |
$global_id | Identificação das configurações. |
$edge_function_id | Identificador da função. |
$request_id | Identificador da requisição. |
$message_source | A origem da mensagem. |
$log_level | Nível do log criado: ERROR, WARN, INFO, DEBUG ou TRACE. |
$log_message | Mensagem usada no log quando a função é requisitada. |
Para ler a mesma saída em Azion Console:
Acesse Azion Console > Real-Time Events.
A aba Functions Console lista uma entrada por mensagem de log, com o seu nível, a sua linha e o identificador da requisição que a produziu.
A função nunca roda
A função existe em Functions e nenhuma requisição a executa. Nada das suas chamadas de console.log chega aos logs da função.
Criar uma função não a executa. Uma função roda quando uma aplicação a instancia e uma regra do Rules Engine seleciona essa instância pelo comportamento Run Function. Sem os dois, o código nunca é executado.
Verifique a cadeia nesta ordem:
- Módulo Functions: na aba Main Settings da aplicação, ative Functions e selecione Save.
- Instância de função: na aba Functions Instances, selecione + Function Instance, selecione a sua função e defina os seus Args. A instância vincula a função à aplicação e carrega os argumentos JSON passados para o contexto de execução dela. Consulte Instâncias de função.
- Regra Run Function: na aba Rules Engine, adicione uma regra, defina os seus critérios e selecione o comportamento Run Function com a sua instância.
- Critérios da regra: uma regra executa os seus comportamentos apenas quando a requisição atende aos seus critérios. Compare os critérios com a URI que você requisita.
- Ordem dos comportamentos: Deliver, Deny (403 Forbidden) e Finish Request Phase encerram o processamento de uma requisição. Um Run Function posicionado depois de um deles nunca é executado. Mova-o para cima do comportamento que encerra a requisição.
A próxima requisição que atende aos critérios executa a função, e as suas mensagens chegam aos logs da função.
Run Function não aparece na lista de comportamentos
Você adiciona uma regra na aba Rules Engine de uma aplicação e Run Function não está entre os comportamentos.
O comportamento Run Function depende de dois módulos: Application Accelerator e Functions. Enquanto Application Accelerator estiver desativado, Rules Engine oferece apenas parte das suas variáveis e dos seus comportamentos.
Para ativar os dois módulos:
Acesse Azion Console > Applications > a sua aplicação.
Run Function aparece na lista de comportamentos de uma regra, na fase de requisição e na fase de resposta.
A função falha na instanciação
A instância de função carrega um objeto Args grande, e a função falha na instanciação.
Args é o objeto JSON que uma instância de função passa para o contexto de execução da função. O campo aceita no máximo 100 KB. Argumentos acima desse tamanho fazem a função falhar na instanciação.
- Reduza o objeto Args: diminua o JSON até que ele fique abaixo de 100 KB.
- Solicite um limite maior: os 100 KB são um default. Para aumentá-lo no seu plano, entre em contato com o suporte técnico.
Com os argumentos abaixo de 100 KB, a instância é salva e a função recebe o objeto no seu contexto de execução.
A função para antes de retornar uma resposta
A função inicia e a invocação termina antes de o código retornar a sua resposta.
Uma invocação roda dentro de três tetos, e um quarto limita o contexto de execução que a carrega:
- Tempo de execução de CPU, 2 s: o tempo máximo de CPU por invocação. Ele mede a computação ativa, não o tempo de relógio, então o tempo gasto esperando por
fetch()não conta. Uma função que o excede é encerrada. - Tempo de execução, 5 min: o tempo máximo de relógio para uma invocação, incluindo espera de I/O, chamadas
fetch()e operações assíncronas. - Sub-requisições, 50: o número máximo de chamadas
fetch()de saída em uma invocação. - Memória por isolate, 512 MB: a memória máxima para um único contexto de execução (isolate V8), incluindo heap, stack e todas as alocações do runtime.
Reduza o trabalho que a invocação realiza:
- Encontre onde está a pressão: uma função que passa a execução esperando por uma origem fica longe do teto de CPU, por mais longa que seja a requisição. Uma função que analisa ou transforma um corpo grande a cada requisição gasta esse orçamento.
- Tire o trabalho do caminho da resposta: o trabalho de que a resposta não precisa é entregue a
ctx.waitUntil(), que estende a duração da função para além da resposta. Isso tira o trabalho do caminho da resposta sem tirá-lo da invocação. O tempo de relógio de 5 minutos continua a delimitá-lo. - Consolide as chamadas de saída: um design cuja contagem de chamadas cresce com a entrada, uma requisição por item de uma lista, ultrapassa o teto de sub-requisições assim que a lista passa de 50 itens. Substitua uma chamada por membro por uma chamada que retorna o conjunto. Essa troca tem o seu próprio limite: o corpo que uma função pode processar é limitado por plano, em 100 MB no Hobby, 200 MB no Pro e 500 MB no Enterprise.
- Solicite um limite maior: todo teto é um default. Para aumentar um deles no seu plano, entre em contato com o suporte técnico.
Para o conjunto completo, consulte Limites.
Uma função cujo trabalho cabe dentro dos tetos de CPU e de tempo de relógio roda até o fim e retorna a sua resposta.
Entradas ERROR nos logs da função
Os logs da função carregam entradas cujo nível é ERROR, como TypeError: Object not found.
Toda entrada de log carrega um nível e uma origem de linha. CONSOLE marca uma linha que o seu próprio código escreveu com console.log. RUNTIME marca uma linha que Azion Runtime produziu, como uma exceção levantada enquanto a função era executada.
- Leia a requisição inteira: o identificador da requisição agrega todas as mensagens de uma mesma requisição. Filtre por ele para ver o que a função registrou antes do erro.
- Consulte os eventos: a query
functionConsoleEventsretornalevel,lineSourceelinepara um intervalo de tempo. Consulte Consulte logs de funções com GraphQL API. - Filtre em Azion Console: a aba Functions Console de Real-Time Events mostra os mesmos campos com filtros.
Agora você tem a mensagem da exceção e o identificador da requisição que a produziu.
O preview não renderiza nada
Você abre Preview deployment para uma função e nenhuma resposta aparece ao lado do editor de código. O preview mostra um aviso que nomeia a função ausente.
Preview deployment renderiza o resultado de uma função auxiliar no seu código-fonte, chamada PreviewProvider. Essa função monta uma requisição simulada e entrega o resultado ao preview. Sem PreviewProvider, o preview não tem nada para renderizar.
- Adicione a função
PreviewProvider: ela cria a requisição que o preview envia ao seu handler. Consulte Preview deployment. - Depure a função em execução com
inspect: a ferramentainspectdentro de Preview deployment mostra o comportamento da função em tempo real.
O preview renderiza a resposta ao lado do editor de código, e o botão open a mostra em uma aba separada.