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:
* 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.
* Time taken to make an SQL query along with the actual query (again, not average times, but individual times, for individual queries)
* Time taken to fetch data from Redis along with the Redis command
* Time taken to render an HTML page along with path to the HTML file
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).
What is the equivalent of this in Haskell?
Here's what I've tried so far [1] , but it has the following disadvantages:
* 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)
* Requires the application to explicitly import the instrumented versions of the libraries (replace import Scotty with import InstrumentedScotty, in my example)
* Forces all the code interacting with instrumented APIs to be run in a MonadIO environment - because of the underlying calls to getCurrentTime
I'm sure there's a better way, but I couldn't get my hands on it!
-- Saurabh.