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: