<div dir="ltr">(copying the mailing list -- I don't think your intention was to keep this off the mailing list)<div><br></div><div>I've looked at middleware for Scotty (or any WAI application), but it has limitations. I want deeper insights about how much time is being spent where, when serving a web request -- which is why the need to instrument SQL, Redis, and HTML rendering.</div><div><br></div><div>One example that doesn't necessarily need to be in the IO monad is HTML rendering using Lucid, where the data is being passed separately to it (standard Controller <> View separation). </div><div><br></div><div>Also, if everything needs to be run in MonadIO, what does that do to fine-grained effect tracking? I wanted to have HasDb, HasRedis, HasEmail kind of monads (or type-classes) that give me some guarantees about the **type** of IO interactions a particular function call can do. If I instrument them and add an additional MonadIO constraint, does it mean any IO can be lifted into such monads?</div><div><br></div><div><div>It's unfortunate to know that the RTS doesn't have these kind of instrumentation capabilities built-in. Is it absolutely not possible to do this at an RTS level?</div></div><div><br></div><div>-- Saurabh.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 27, 2017 at 12:32 PM, David Turner <span dir="ltr"><<a href="mailto:dct25-561bs@mythic-beasts.com" target="_blank">dct25-561bs@mythic-beasts.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Hi Saurabh,<div dir="auto"><br></div><div dir="auto">There's no direct equivalent to monkey-patching in Haskell (AFAIK (*)). Why not instrument things always? The performance impact is usually quite negligible, and the ability to switch instrumentation on at runtime in production is sometimes invaluable.</div><div dir="auto"><br></div><div dir="auto">For instrumenting Scotty (in particular) or WAI-based apps (in general) you can instrument things simply by inserting an appropriate `Middleware`, a decision that can be deferred until service-startup time, and which involves no change to the Scotty-side code.</div><div dir="auto"><br></div><div dir="auto">There's no equivalent to WAI for database access so I don't have a general answer in that case, but typically database APIs have only a few core `execute` or `query` functions that are quite straightforward to wrap with instrumentation if needs be.</div><div dir="auto"><br></div><div dir="auto">This all kinda _has_ to be in IO anyway, as you're trying to measure a real-world activity. Certainly there's no problem with either Scotty or databases in this regard, as they're running in IO. Do you have an example where you need instrumentation of a pure (i.e. non-IO) computation? In such a case you could use the `unsafePerformIO` escape hatch (like `Debug.Trace` does) but you'll have to be very careful to measure what you think you're measuring: the language is quite free to reorder computations and avoid repeating duplicated computations via referential transparency etc.</div><div dir="auto"><br></div><div dir="auto">(*) I mean, you could do something with dynamic libs and LD_PRELOAD (the original monkey-patching) but please don't!</div><div dir="auto"><br></div><div dir="auto">Hope that helps,</div><div dir="auto"><br></div><div dir="auto">David</div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On 27 Jan 2017 05:21, "Saurabh Nanda" <<a href="mailto:saurabhnanda@gmail.com" target="_blank">saurabhnanda@gmail.com</a>> wrote:<br type="attribution"></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr"><div>(another cross post from Reddit - <a href="https://www.reddit.com/r/haskell/comments/5qfd36/instrumentation_without_required_application/" target="_blank">https://www.reddit.com/r/haske<wbr>ll/comments/5qfd36/instrumenta<wbr>tion_without_required_<wbr>application/</a>)</div><div><br></div><div>Is it possible to collect instrumentation data from a Hakell application without requiring the core application to change code? Here are some examples of instrumentation data:</div><div><br></div><div>* Time taken to serve an HTTP request (not average time, but individual times, for individual requests) along with the incoming request params+headers and outgoing response length.</div><div>* Time taken to make an SQL query along with the actual query (again, not average times, but individual times, for individual queries)</div><div>* Time taken to fetch data from Redis along with the Redis command</div><div>* Time taken to render an HTML page along with path to the HTML file</div><div><br></div><div>Most dynamic languages (like Ruby) allow monkey-patching OR "decorating" existing functions during runtime. Most instrumentation agents (like Skylight, Newrelic), simply monkey-patch the API surfaces of known libraries to collect this data. Therefore, using these instrumentation agents is a one line code change (just include the gem, or drop the JAR, or whatever).</div><div><br></div><div>What is the equivalent of this in Haskell?</div><div><br></div><div>Here's what I've tried so far [1] , but it has the following disadvantages:</div><div><br></div><div>* Requires changes to the application's cabal file to replace the non-instrumented versions of the libraries with the instrumented version (replace scotty with instrumentedscotty, in my example)</div><div>* Requires the application to explicitly import the instrumented versions of the libraries (replace import Scotty with import InstrumentedScotty, in my example)</div><div>* Forces all the code interacting with instrumented APIs to be run in a MonadIO environment - because of the underlying calls to getCurrentTime</div><div><br></div><div>I'm sure there's a better way, but I couldn't get my hands on it!</div><div><br></div><div>[1] <a href="https://gist.github.com/saurabhnanda/27592da0269bc35569ec6239e1a91b75" target="_blank">https://gist.github.com/saurab<wbr>hnanda/27592da0269bc35569ec623<wbr>9e1a91b75</a></div><div><br></div><div>-- Saurabh.</div>
</div>
<br></div></div>______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.<br></blockquote></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><a href="http://www.saurabhnanda.com" target="_blank">http://www.saurabhnanda.com</a></div>
</div>