Skip to content

Commit

Permalink
added db.PerfFunc
Browse files Browse the repository at this point in the history
  • Loading branch information
qiangxue committed Oct 11, 2017
1 parent 95c9401 commit 4671b36
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 12 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,10 @@ func main() {
)
```
And the following example shows how to use the `ozzo-log` package which allows logging message severities and categories
You can also configure `DB.PerfFunc` to capture the SQL statement execution times. Each time when a SQL statement
is executed or queried, this function will be called with the time used. This allows you to profile your DB performance.
The following example shows how to use the `ozzo-log` package which allows logging message severities and categories
and sending logged messages to different targets (e.g. files, console window, network).
```go
Expand Down
9 changes: 9 additions & 0 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ type (
// are provided, they will be passed to fmt.Sprintf() to generate the log message.
LogFunc func(format string, a ...interface{})

// PerfFunc is called when a query finishes execution.
// The query execution time is passed to this function so that the DB performance
// can be profiled. The "ns" parameter gives the number of nanoseconds that the
// SQL statement takes to execute, while the "execute" parameter indicates whether
// the SQL statement is executed or queried (usually SELECT statements).
PerfFunc func(ns int64, sql string, execute bool)

// BuilderFunc creates a Builder instance using the given DB instance and Executor.
BuilderFunc func(*DB, Executor) Builder

Expand All @@ -31,6 +38,8 @@ type (
FieldMapper FieldMapFunc
// LogFunc logs the SQL statements being executed. Defaults to nil, meaning no logging.
LogFunc LogFunc
// PerfFunc logs the SQL execution time. Defaults to nil, meaning no performance profiling.
PerfFunc PerfFunc

sqlDB *sql.DB
driverName string
Expand Down
30 changes: 19 additions & 11 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type Query struct {
LastError error
// LogFunc is used to log the SQL statement being executed.
LogFunc LogFunc
// PerfFunc is used to log the SQL execution time. It is ignored if nil.
PerfFunc PerfFunc
}

// NewQuery creates a new Query with the given SQL statement.
Expand All @@ -57,6 +59,7 @@ func NewQuery(db *DB, executor Executor, sql string) *Query {
params: Params{},
FieldMapper: db.FieldMapper,
LogFunc: db.LogFunc,
PerfFunc: db.PerfFunc,
}
}

Expand Down Expand Up @@ -90,11 +93,20 @@ func (q *Query) logSQL() string {

// log logs a message for the currently executed SQL statement.
func (q *Query) log(start time.Time, execute bool) {
t := float64(time.Now().Sub(start).Nanoseconds()) / 1e6
if execute {
q.LogFunc("[%.2fms] Execute SQL: %v", t, q.logSQL())
} else {
q.LogFunc("[%.2fms] Query SQL: %v", t, q.logSQL())
if q.LogFunc == nil && q.PerfFunc == nil {
return
}
ns := time.Now().Sub(start).Nanoseconds()
s := q.logSQL()
if q.LogFunc != nil {
if execute {
q.LogFunc("[%.2fms] Execute SQL: %v", float64(ns)/1e6, s)
} else {
q.LogFunc("[%.2fms] Query SQL: %v", float64(ns)/1e6, s)
}
}
if q.PerfFunc != nil {
q.PerfFunc(ns, s, execute)
}
}

Expand Down Expand Up @@ -154,9 +166,7 @@ func (q *Query) Execute() (result sql.Result, err error) {
return
}

if q.LogFunc != nil {
defer q.log(time.Now(), true)
}
defer q.log(time.Now(), true)

if q.stmt == nil {
result, err = q.executor.Exec(q.rawSQL, params...)
Expand Down Expand Up @@ -224,9 +234,7 @@ func (q *Query) Rows() (rows *Rows, err error) {
return
}

if q.LogFunc != nil {
defer q.log(time.Now(), false)
}
defer q.log(time.Now(), false)

var rr *sql.Rows
if q.stmt == nil {
Expand Down

0 comments on commit 4671b36

Please sign in to comment.