diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fe02006..14f89ed3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [PR #206](https://github.com/rqlite/rqlite/pull/206), [#217](https://github.com/rqlite/rqlite/pull/217): Support loading from SQLite dump files (experimental). - [PR #211](https://github.com/rqlite/rqlite/pull/211): Diagnostics show actual foreign key constraint state. - [PR #212](https://github.com/rqlite/rqlite/pull/212): Add database configuration to diagnostics output. +- [PR #224](https://github.com/rqlite/rqlite/pull/224): Add low-level database layer expvar stats. ## 3.6.0 (October 1st 2016) - [PR #195](https://github.com/rqlite/rqlite/pull/195): Set Content-type "application/json" on all HTTP responses. diff --git a/db/db.go b/db/db.go index 5b6fe2bf..d1c7ead0 100644 --- a/db/db.go +++ b/db/db.go @@ -4,6 +4,7 @@ package db import ( "database/sql/driver" + "expvar" "fmt" "io" "time" @@ -17,13 +18,24 @@ const ( fkChecks = "PRAGMA foreign_keys" fkChecksEnabled = "PRAGMA foreign_keys=ON" fkChecksDisabled = "PRAGMA foreign_keys=OFF" + + numExecutions = "executions" + numQueries = "queries" + numTransactions = "transactions" ) // DBVersion is the SQLite version. var DBVersion string +// stats captures stats for the DB layer. +var stats *expvar.Map + func init() { DBVersion, _, _ = sqlite3.Version() + stats = expvar.NewMap("db") + stats.Add(numExecutions, 0) + stats.Add(numQueries, 0) + stats.Add(numTransactions, 0) } // DB is the SQL database. @@ -161,6 +173,9 @@ func (db *DB) FKConstraints() (bool, error) { // Execute executes queries that modify the database. func (db *DB) Execute(queries []string, tx, xTime bool) ([]*Result, error) { + stats.Add(numQueries, 1) + stats.Add(numExecutions, int64(len(queries))) + type Execer interface { Exec(query string, args []driver.Value) (driver.Result, error) } @@ -254,6 +269,8 @@ func (db *DB) Execute(queries []string, tx, xTime bool) ([]*Result, error) { // Query executes queries that return rows, but don't modify the database. func (db *DB) Query(queries []string, tx, xTime bool) ([]*Rows, error) { + stats.Add(numQueries, int64(len(queries))) + type Queryer interface { Query(query string, args []driver.Value) (driver.Rows, error) }