Suggestions for wrapping Database to gather timings

I would like to wrap Database calls in something that will time every DB operation my code makes, even in production. We don’t do anything fancy, just CRUD commands. One thought I had is to create my own wrapper for Database which provides its own withConnection and withTransaction which wrap calls to the default implementations in a timer and do something with the time. (I understand that this would measure not just the DB call time, but also the execution time of any code in the block provided to withConnection()/withTransaction(). I am OK with this.)

Has anyone done something similar - is there any example code anywhere? Am I approaching this wrong? (Note I do not want the timings logged either in the DB server or in the application server… I need to gather them programmatically myself)

Thank you

Hi @mrubin

I dont have an example code handy, but this seems to lend very well to AOP. Your wrapper class can make use of AOP pointcuts to inject timing/logging/monitoring calls before and after the actual DB calls. I think this is a fairly well known pattern, so you should be able to get good number of examples online.

HTH
-Aditya

You probably want to do something much more advanced, but just incase it gives you inspiration, this is what I use when I am curious how long something takes.

def time[R](what: String = "")(block: => R): R = {
val t0 = System.nanoTime()
val result = block 
val t1 = System.nanoTime()
Logger.info(s"$what time: " + (t1 - t0) / 1000 / 1000 + "ms (" + (t1 - t0) / 1000 + "ns)")
result
}
util.Time.time(s"something slow") {
   SomethingPotentiallySlow()
}
1 Like

Thank you for these suggestions.

@Adam

I think this gets little tricky when you want to time non blocking calls (calls wrapped in Promise, CompletableFuture etc.).
I guess putting the timing statements in the callbacks is the recommended way.

Cheers
Aditya