Observabilidade com Hyperf e OpenTelemetry

Leo Cavalcante
Inside PicPay
Published in
5 min readMar 22, 2022

No PicPay, para melhorar a escalabilidade de nossas aplicações feitas em PHP, nós utilizamos a Swoole como runtime de alta-performance tornando as aplicações assíncronas e não-bloqueantes.

Começar a utilizar a Swoole trouxe alguns desafios, um deles é o da observabilidade, vamos entender mais a frente.

Photo by Davyn Ben on Unsplash

Observabilidade

Observabilidade é a metodologia que o mercado de microsserviços e cloud-native explora para monitorar as aplicações, saber como os recursos estão sendo utilizados, se a aplicação está entregando o que ela se propõe fazer e se tiverem erros, e como identificá-los.

Para isso, são definidos três pilares (e talvez um quarto):

Métricas

Métricas são medidas de avaliação quantitativa comumente usadas para comparar e acompanhar o desempenho ou a produção. Quantas vezes aconteceu.

Traces

Conjunto de Spans, são a coleção de lugares por onde o clico de vida de uma transação passou. Onde aconteceu.

Logs

Informações sobre qual era o atual contexto no momento que algo aconteceu durante o clico de vida de uma transação. O que aconteceu.

Eventos?

É cada vez mais comum separar logs de eventos e muitas pessoas veem como o quarto pilar da observabilidade. Eventos são informações sobre regras de negócio. Dados personalizados sobre a experiência de um determinado fluxo de dados. A maior diferença para os logs é que aqui não ficam dados sobre infraestrutura.

Hyperf

Hyperf é o framework web que adotamos para as aplicações PHP em Swoole. Os pontos que nos levaram a utilizá-lo foi por ele ter corrotinas como cidadãs de primeira-classe. O Hyperf foi feito para a Swoole, ele não foi adaptado para a Swoole como seria com outros frameworks de mercado como Laravel, Symfony e Laminas.

Todos os componentes dentro dele estão preparados para trabalhar com corrotinas usando pool de conexões, evitando estado global utilizando os contextos das corrotinas e evitando ao máximo memory-leaks já que agora a memória do processo não vai ser limpa a cada requisição e com isso também vem o cuidado de não fazer os dados de um requisição afetar a outra.

Resumidamente, o Hyperf está preparado para trabalhar da forma stateful que é totalmente o contrário da forma stateless do PHP-FPM tradicional.

Feito para microsserviços

Outro ponto muito legal que corroborou com nossa escolha, é a forma como o foco do Hyperf fica em microsserviços. Ele não se preocupa com coisas como views e sessões, coisas que são mais utilizadas na construção de sites.

No lugar, o Hyperf entrega componentes que foram pensados em microsserviços e no mundo cloud, coisas como: circuit-break, rate-limit, service-discovery, remote-config, gRPC etc.

E, claro, junto desses componentes cloud-native focados em microsserviços, tem os componentes para Observabilidade.

Problemas com APMs

Geralmente a observabilidade de aplicações é feita de forma trivial através de APMs. O provedor do serviço de monitoramento, por exemplo o New Relic, fornece um APM que pode ser adicionado ao servidor para rodar junto com a aplicação e ele faz a instrumentação do que está acontecendo.

Os APMs fazem isso utilizando uma técnica chamada Monkey Patch, essa técnica é uma forma de adicionar comportamento em tempo de execução. Quando você chama o cURL através das funções curl_, por exemplo, na verdade você tá chamando a biblioteca da New Relic que, por sua vez, chama a cURL padrão do PHP, mas no meio disso adiciona o comportamento que faz a instrumentação.

A Swoole tem uma feature chamada Runtime Hooks, que faz com que recursos atuais do PHP, como o cURL, PDO, Redis etc funcionem de forma assíncrona, dentro de seu event-loop e a Swoole faz isso utilizando a mesma técnica de Monkey Patch, sobrescrevendo as funções nativas do PHP para adicionar esse comportamento novo.

Aí vem o problema: duas extensões, cada uma querendo fazer o monkey patch, a sobrescrita das mesmas funções nativas do PHP. Elas entram em conflito e no fim nenhuma funciona.

OpenTelemetry

Uma das formas que encontramos para resolver esse problema com os APMs foi fazer a instrumentação utilizando o próprio PHP ao invés de APMs. Deu super certo, funcionou, felizmente a New Relic tem uma API REST, na verdade APIs REST que são exatamente 1:1 para os pilares, uma API para métricas, para traces e para eventos. Fazíamos a instrumentação de forma manual e enviávamos os dados para essas APIs.

O problema disso é que houve muita mistura entre código de regras de negócio e código de instrumentação, as classes e o métodos ganhavam mais linhas de coisas que não tinham relação direta.

De qualquer forma, foi por meio dessa ideia de instrumentar com o PHP que descobrimos o OpenTelemetry.

O projeto OTel é a fusão dos projetos OpenTracing e OpenCencus, ou seja, já existiam iniciativas para Observabilidade utilizando formatos abertos. O OpenTelemetry juntou essa galera para uma fundação e organização.

Já existiam projetos para o PHP de OpenTracing que geravam formatos abertos como Jaeger e StatsD e esses projetos forma herdados no OpenTelemetry. Essa foi a peça que faltava pra encaixar o ecossitema de observabilidade que já funcionava muito bem ao OpenTelemetry, por meio do seu componente de Collector, foi a peça que encaixou esses formatos abertos com o New Relic.

Lembra que o Hyperf é todo focado em microsserviços, inclusive na parte de Observabilidade? Então, ele mesmo já provê dois componentes chamados hyperf/trace e hyperf/metric que servem justamente para fazer a instrumentação das aplicações em Hyperf e exportá-las para formatos abertos.

Instrumentação com AOP

Um ponto bem legal sobre a instrumentação para evitar aquele problema de ter ela misturada com regras de negócio e código que faz outras coisas, é que o Hyperf utiliza uma técnica chama AOP, de Aspect Oriented Programming, ela é uma forma de implementar Monkey Patch (lembra dele?), ou seja, a gente consegue adicionar comportamento (no caso de instrumentação) em classes, métodos e funções, sem de fato alterar o código delas.

Só que dessa vez, esse monkey patch feito com AOP fornecido pelo Hyperf, é feito com o próprio PHP, não temos o problema de conflito com o monkey patch feito pela Swoole para deixar os componentes do PHP não-bloqueantes.

Recomendo bastante darem uma lida na técnica: https://en.wikipedia.org/wiki/Aspect-oriented_programming

Conclusão

Aplicação feita com Hyperf

É instrumentada e exporta os dados em formatos abertos, como Jaeger e StatsD.

OpenTelemetry Collector

Por ser a junção do OpenTracing com o OpenCensus, herda a possibilidade de receber formatos abertos (como Jaeger e Statsd) e tem suporte da própria New Relic para exportar os dados para sua plataforma.

New Relic

Super parceira do projeto, apoia a iniciativa e vem dando cada vez mais suporte para receber os dados que foram gerados pelos componentes do OpenTelemetry.

--

--