Trace instrumentando o código com dbg
- 5 minutes read - 942 wordsEste post é sobre como instrumentar uma aplicação e coletar traces para posterior analise. A ideia veio deste post: Erlang trace files in Wireshark e também deste código hackney_trace.erl.
Aqui estamos falando de como utilizar a BEAM VM para capturar traces da aplicação. Podemos usar trace nas seguintes situações:
- low level information próprio para debug do software
- queremos localizar extamente o ponto que ocorre algum evento
- as informações são destinadas para o desenvolvedor
- adicionar e remover trace devem ser rápidos
Um módulo em Elixir pode ser construído para instrumentar uma aplicação com pontos de trace. Esta técnica é um dos jeitos de utilizar o módulo dbg.
O código a seguir implementa um módulo chamado Trace. Dividi em blocos para
ficar mais fácil explicar o código.
| |
Apenas algumas definições de algumas constantes.
| |
Funções para ativar e desativar o trace.
| |
A função enable/3 pode ativar trace para arquivo ou enviar para alguma porta
remota. Neste post vamos explorar a opção de envio para arquivo. A função apenas
passa os parâmetros corretos para o módulo dbg.
| |
Podemos mudar o level de trace durante a execução, para isso a função
set_level/2 deve ser utilizada.
| |
report_event/4 é a função no qual iremos observar e coletar as chamadas de
função.
| |
make_pattern/3 e change_pattern/1 servem para criar um pattern e informar o
dbg para fazer o trace.
Agora, precisamos apenas intrumentar a aplicação, escolhendo alguns pontos estratégicos:
- processamento de alguma request
- envio de uma response
- interface com algum serviço externo
- ou chamadas por blocos funcionais
Em cada ponto que queremos instrumentar, colocamos chamadas para a função
Trace.report_event/4:
... Trace.report_event(80, "ex_unit
context", :swix_service, [a: 1, b: 2, c: 3]) ... A função Trace.report_event/4 apenas retorna um atom. E durante a execução da
aplicação, podemos executar no console as seguintes chamadas:
Trace.enable(:max, :file, "/tmp/mytrace")Desta forma ativamos o dbg para fazer o trace das chamadas da função
Trace.report_event/4 e escrevendo o resultado em um arquivo, no formato
Erlang Terms.
Para desativar o trace:
Trace.disable() Lendo o resultado do trace
Neste post, vamos utilizar o wireshark para ler o arquivo gerado. Mas existem outras formas de ler o trace. Como por exemplo utilizando trace_cleint.
A escolha do wireshark é uma alternativa bem interessante pois podemos fazer uma análise mais gráfica.
Existe um plugin do wireshark feito em lua no qual vamo utilizar. Para instalar, baixe e instale os arquivos erlterm.lua e erlang-trace.lua no diretório ~/.config/wireshark/plugins. Abra o wireshark e depois o arquivo com o trace.
Pronto, podemos inspecionar o conteúdo do trace.
Outras formas de trace
A técnica apresentada envolve instrumentação de código. Entretanto o módulo
dbg oferece a possibilidade de não precisar instrumentar nada e apenas definir
trace calls. Existem também wrappers feitos em Elixir e Erlang no qual
facilitam o uso do dbg.
Referências: