Is there a clean way to implement query analytics into an application using sqlboiler? #1188
-
I'm trying to build some analytics into my web application to understand how many queries are being run per endpoint so I can identify areas that need improvement/optimization. I'm using hooks to capture this information, and finding a few different ways where what I'm trying to do isn't quite covered by sqlboiler (e.g. #1185, #1187). For example: currently if I wanted to capture the fact that a select query was run, I can add an AfterSelect hook. However, if a Select query returns 5 items, then the hook fires 5 times. This is great if I'm wanting to inspect, validate, or otherwise operate on each item returned by a select, but if I only want to know that a Select query ran, that's 4 more triggers than I need. Is there maybe some sort of elegant way to mark up the context to differentiate between selects? Failing that, I'm preparing some fairly significant local changes to sqlboiler that add a "Query" variant to each hook method where the actual object(s) aren't passed into the hook, so something like func AddItemQueryHook(hookPoint boil.HookPoint, itemQueryHook ItemQueryHook) {
switch hookPoint {
case boil.BeforeSelectQueryHook:
itemBeforeSelectQueryHooks = append(itemBeforeSelectQueryHooks, itemQueryHook)
case boil.AfterSelectQueryHook:
itemAfterSelectQueryHooks = append(itemAfterSelectQueryHooks, itemQueryHook)
}
} func (q itemQuery) All(ctx context.Context, exec boil.ContextExecutor) (ItemSlice, error) {
var o []*Item
if err := doItemBeforeSelectQueryHooks(ctx, exec); err != nil {
return o, err
}
err := q.Bind(ctx, exec, &o)
if err != nil {
return nil, errors.Wrap(err, "models: failed to assign all query results to Item slice")
}
if err := doItemAfterSelectQueryHooks(ctx, exec); err != nil {
return o, err
}
if len(itemAfterSelectHooks) != 0 {
for _, obj := range o {
if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
return o, err
}
}
}
return o, nil
} et al Any thoughts? Is this possible through some existing method that I completely missed? :) Here's a functional version of my described idea: https://github.com/volatiletech/sqlboiler/compare/master...parnic:sqlboiler:add-hook-one-per-query?expand=1 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I'd say the easiest way is to wrap the top level sql.DB and collect your metrics when the methods are called. For example: type MyDB struct {
db *sql.DB
}
func (m MyDB) QueryContext(..) (...) {
// collect analytics
m.db.QueryContext(...)
}
// Other methods |
Beta Was this translation helpful? Give feedback.
I'd say the easiest way is to wrap the top level sql.DB and collect your metrics when the methods are called.
For example: