Skip to content

Commit 7cb9b5f

Browse files
authored
Merge pull request #210 from moov-io/perf-debug
Adding in additional metrics to track for database connections
2 parents 3a27ee1 + ceb6668 commit 7cb9b5f

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

database/mysql.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ var (
3838
Help: "How many MySQL connections and what status they're in.",
3939
}, []string{"state"})
4040

41+
mysqlConnectionsCounters = kitprom.NewGaugeFrom(stdprom.GaugeOpts{
42+
Name: "mysql_connections_counters",
43+
Help: `Counters specific to the sql connections.
44+
wait_count: The total number of connections waited for.
45+
wait_duration: The total time blocked waiting for a new connection.
46+
max_idle_closed: The total number of connections closed due to SetMaxIdleConns.
47+
max_idle_time_closed: The total number of connections closed due to SetConnMaxIdleTime.
48+
max_lifetime_closed: The total number of connections closed due to SetConnMaxLifetime.
49+
`,
50+
}, []string{"counter"})
51+
4152
// mySQLErrDuplicateKey is the error code for duplicate entries
4253
// https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html#error_er_dup_entry
4354
mySQLErrDuplicateKey uint16 = 1062
@@ -65,14 +76,18 @@ type mysql struct {
6576
logger log.Logger
6677
tls *tls.Config
6778

79+
db *sql.DB
80+
6881
connections *kitprom.Gauge
82+
counters *kitprom.Gauge
6983
}
7084

7185
func (my *mysql) Connect(ctx context.Context) (*sql.DB, error) {
7286
db, err := sql.Open("mysql", my.dsn)
7387
if err != nil {
7488
return nil, err
7589
}
90+
7691
db.SetMaxOpenConns(maxActiveMySQLConnections)
7792

7893
// Check out DB is up and working
@@ -88,17 +103,33 @@ func (my *mysql) Connect(ctx context.Context) (*sql.DB, error) {
88103
case <-ctx.Done():
89104
return
90105
case <-t.C:
91-
stats := db.Stats()
92-
my.connections.With("state", "idle").Set(float64(stats.Idle))
93-
my.connections.With("state", "inuse").Set(float64(stats.InUse))
94-
my.connections.With("state", "open").Set(float64(stats.OpenConnections))
106+
my.RecordStats()
95107
}
96108
}
97109
}()
98110

111+
my.db = db
99112
return db, nil
100113
}
101114

115+
func (my *mysql) RecordStats() error {
116+
if my.db == nil {
117+
return errors.New("database not connected")
118+
}
119+
120+
stats := my.db.Stats()
121+
my.connections.With("state", "idle").Set(float64(stats.Idle))
122+
my.connections.With("state", "inuse").Set(float64(stats.InUse))
123+
my.connections.With("state", "open").Set(float64(stats.OpenConnections))
124+
my.counters.With("counter", "wait_count").Set(float64(stats.WaitCount))
125+
my.counters.With("counter", "wait_ms").Set(float64(stats.WaitDuration.Milliseconds()))
126+
my.counters.With("counter", "max_idle_closed").Set(float64(stats.MaxIdleClosed))
127+
my.counters.With("counter", "max_idle_time_closed").Set(float64(stats.MaxIdleTimeClosed))
128+
my.counters.With("counter", "max_lifetime_closed").Set(float64(stats.MaxLifetimeClosed))
129+
130+
return nil
131+
}
132+
102133
func mysqlConnection(logger log.Logger, mysqlConfig *MySQLConfig, databaseName string) (*mysql, error) {
103134
timeout := "30s"
104135
if v := os.Getenv("MYSQL_TIMEOUT"); v != "" {
@@ -142,7 +173,7 @@ func mysqlConnection(logger log.Logger, mysqlConfig *MySQLConfig, databaseName s
142173
logger.Logf("verifying MySQL server certificate using CA from file %s", mysqlConfig.TLSCAFile)
143174
_, err := state.PeerCertificates[0].Verify(x509.VerifyOptions{Roots: rootCertPool})
144175
if err != nil {
145-
return err
176+
return logger.Error().LogError(err).Err()
146177
}
147178
return nil
148179
}
@@ -166,6 +197,7 @@ func mysqlConnection(logger log.Logger, mysqlConfig *MySQLConfig, databaseName s
166197
logger: logger,
167198
tls: tlsConfig,
168199
connections: mysqlConnections,
200+
counters: mysqlConnectionsCounters,
169201
}, nil
170202
}
171203

database/mysql_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ func TestMySQL__TLS(t *testing.T) {
6868
require.NoError(t, err)
6969

7070
require.NoError(t, conn.Ping())
71+
72+
require.NoError(t, m.RecordStats())
7173
}
7274

7375
func TestMySQLUniqueViolation(t *testing.T) {

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,7 @@ google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ6
13131313
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
13141314
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
13151315
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
1316+
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
13161317
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
13171318
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
13181319
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1343,6 +1344,7 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
13431344
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
13441345
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
13451346
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
1347+
google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=
13461348
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
13471349
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
13481350
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=

0 commit comments

Comments
 (0)