gormalert

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2024 License: MIT Imports: 5 Imported by: 0

README

GORM SCAN ALERT

This is a library intended to automatically detect sequential scans on our database, and give you a way to be warned about them.

This currently only supports Postgres and Mysql as the dialect. (This is not battle tested on Mysql, apart from the tests on this repo)

Usage

Once you have your *gorm.DB object, you can add the gormalert scanner as a plugin to it. To make it easier, there's a helper method for it:


...
gormalert.RegisterScanAlert(db, gormalert.DefaultAlertOptions(), func(query, explain string) {
    // Tell someone about the sequential scan!
    fmt.Printf("The query %q just did a sequential scan!\n", query)
})

The db object will be instrumented with the alert after that. I don't recommend running this in production, but instead on your tests and staging environments.

Example

This is a helper that create DB objects for tests, and this code adds a clause to automatically fail any test that performs a table scan using that object.

func testDB(t *testing.T) (*gorm.DB, func()) {
	db, closer := dbtest.DB(t, ...)

	gormalert.RegisterScanAlert(db, gormalert.DefaultAlertOptions(), func(source string, result string) {
		t.Errorf("the query %q executed a sequential scan: %s", source, result)
	})

	return db, closer
}

Alternatively the ExpectDBWithoutSequentialScan helper can be used to achieve similar result:

func TestSomething(t testing.T) {
	// setup
	db := ...
	ExpectDBWithoutSequentialScan(t, db)

	// tests
	...
}
Options
type AlertOptions struct {
	Name        string
	Async       bool
	QueryType   []QueryType
	ErrorLogger func(string)
}

You can instrument any of the query types:

  • CreateQuery
  • UpdateQuery
  • SelectQuery
  • DeleteQuery
  • RawQuery

The scans are attached to callbacks on gorm for the respective methods (e.g. CreateQuery will trigger only for db.Create(...)). The RawQuery will trigger for calls of Exec(...) or Raw(...), no mater which kind of query those methods are performing.

The Async option will run the callback within a Goroutine, which should not block the main flow.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExpectDBWithoutSequentialScan

func ExpectDBWithoutSequentialScan(t *testing.T, db *gorm.DB)

ExpectDBWithoutSequentialScan will annotate the given db connection and will - in case it detects a table scan - fail the running test.

func NewScanAlerterPlugin

func NewScanAlerterPlugin(options AlertOptions, action actionFunc) *scanAlerter

func RegisterScanAlert

func RegisterScanAlert(db *gorm.DB, options AlertOptions, action actionFunc)

Types

type AlertOptions

type AlertOptions struct {
	// Name is the name of the plugin. In case you are registering multiple
	// scanalerts, this must be unique for each one of them.
	Name string

	// Async will perform the detection within a go routing, instead of blocking.
	Async bool

	// QueryType contains the selection of which kind of query this should be scanning for.
	// This filter only applies for explicit methods from gorm's DB object
	// (e.g. Update, First, Find, Create, etc...)
	QueryTypes []QueryType

	// ErrorLogger provides a way to flush out internal errors from the plugin.
	// If not selected errors will be ignored.
	ErrorLogger func(args ...any)
}

AlertOptions contains a group of options to be used by the scanalert plugin.

func DefaultAlertOptions

func DefaultAlertOptions() AlertOptions

type QueryType

type QueryType string
const (
	// CreateQuery will scan for calls to `Create()`.
	CreateQuery QueryType = "create"
	// DeleteQuery will scan for calls to `Delete()`
	DeleteQuery QueryType = "delete"
	// RawQuery will scan for calls to `Raw()` or `Exec()`
	RawQuery QueryType = "raw"
	// SelectQuery will scan for calls to `Select()`
	SelectQuery QueryType = "query"
	// UpdateQuery will scan for calls to `Update()`.
	UpdateQuery QueryType = "update"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL