-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathhealthcheck.go
63 lines (54 loc) · 1.63 KB
/
healthcheck.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package db
import (
"context"
"fmt"
"time"
"github.com/jmoiron/sqlx"
)
type HealthCheck struct {
Name string
DB *sqlx.DB
}
func (h *HealthCheck) HealthChecks() (name string, ready, live func(ctx context.Context) error) {
return h.Name, newPGHealthCheck(h.DB), nil
}
func (h *HealthCheck) MetricName() string {
return h.Name
}
func (h *HealthCheck) Gauges(_ context.Context) map[string]float64 {
stats := h.DB.Stats()
return map[string]float64{
"in_use": float64(stats.InUse),
"idle": float64(stats.Idle),
"wait_count": float64(stats.WaitCount),
"wait_duration": float64(stats.WaitDuration / time.Millisecond),
"max_idle_closed": float64(stats.MaxIdleClosed),
"max_idle_time_closed": float64(stats.MaxIdleTimeClosed),
"max_lifetime_closed": float64(stats.MaxLifetimeClosed),
}
}
// New creates new PostgreSQL health check that verifies the following:
// - doing the ping command
// - selecting postgres version
func newPGHealthCheck(db *sqlx.DB) func(ctx context.Context) error {
return func(ctx context.Context) (err error) {
err = db.PingContext(ctx)
if err != nil {
return fmt.Errorf("postgreSQL health check failed on ping: %w", err)
}
rows, err := db.QueryContext(ctx, `SELECT VERSION()`)
if err != nil {
return fmt.Errorf("postgreSQL health check failed on select: %w", err)
}
defer func() {
// override checkErr only if there were no other errors
if err = rows.Close(); err != nil {
checkErr := fmt.Errorf("postgreSQL health check failed on rows closing: %w", err)
if err == nil {
err = checkErr
}
}
}()
return nil
}
}