<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">On Sun, Jan 26, 2020 at 1:58 PM Frank Muller <<a href="mailto:frank.muller.erl@gmail.com">frank.muller.erl@gmail.com</a>> wrote:</span><br></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="color:rgb(49,49,49);word-spacing:1px">Hi everyone</span><br style="color:rgb(49,49,49);word-spacing:1px"><br style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px">I would like to implement a custom instrumentation module for my Erlang code.</span><br style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px">Let assume this function:</span><br style="color:rgb(49,49,49);word-spacing:1px"><br style="color:rgb(49,49,49);word-spacing:1px"></blockquote><div><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">If you have</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">f1() -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  Exprs,</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  ok.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">You can write</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">f1() -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  S = instrument:start(),</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  try</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">    Exprs,</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">    ok</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  finally</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">    instrument:end(S)</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  end.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">However, some times you want to track an error apart from a success value. Positive and negative exit paths often require different instrumentation. The success path is often interested in processing time (latency) in addition to processing count. The error path often centers around the idea of an error count, especially if the exit is fast. If you blend them, the problem is that the fast errors muddles your view of the successes, as your latency distribution becomes multi-modal. In turn, your mean and median doesn't work like you think they do anymore.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px"><div dir="auto">Other problem I can think of is when we have multiple return paths and/or recursive loop:</div></span><br style="color:rgb(49,49,49);word-spacing:1px"></blockquote><div><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">If you loop, you want to wrap:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">f1(0) -> ok;</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">f1(N) -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  do(),</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  f(N-1).</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">f1_(N) -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  S = instrument:start(),</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  try</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">    f1(N)</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  finally</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">    instrument:end(S)</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  end.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">This only pushes a single exception handler to the stack. An important caveat is when Exprs or do() hibernates. Beware of that situation, since it removes the stack and invokes a continuation.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><br style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px">Is that doable?</span><br style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px">If yes, can I apply like this logic to all modules running in my Erlang node?</span><br style="color:rgb(49,49,49);word-spacing:1px"><br></div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Yes, parse transforms.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">But in my experience, applying something to all modules is usually the wrong way to go about instrumentation. Maybe with a </div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">-instrument([F, ...]).</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">to help the parsetransform along the way.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">(</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">This is considerably easier in something like Elixir with its macro system, or OCaml, because you have PPX extensions.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">In OCaml, you would have</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">let f1() -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">    Expr.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">And you could just annotate it</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">let%instrument f1() -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">  Expr.</div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">And write a PPX rewriter for that. </div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">)</div><br></div></div><div><br></div>-- <br><div dir="ltr" class="gmail_signature">J.</div></div>