Use state_change for measuring elapsed time

This commit is contained in:
Julien Riou 2018-06-11 21:02:24 +02:00
parent bb7ddf2bc5
commit 3a89201a94
No known key found for this signature in database
GPG key ID: BA3E15176E45E85D
3 changed files with 35 additions and 40 deletions

View file

@ -42,7 +42,7 @@ func (db *Db) Disconnect() {
// Sessions connects to the database and returns current sessions
func (db *Db) Sessions() (sessions []Session) {
query := `select pid as pid, usename as user, datname as db, host(client_addr)::text || ':' || client_port::text as client, state as state, substring(query from 1 for ` + strconv.Itoa(maxQueryLength) + `) as query, coalesce(extract(epoch from now() - backend_start), 0) as "backendDuration", coalesce(extract(epoch from now() - xact_start), 0) as "xactDuration", coalesce(extract(epoch from now() - query_start), 0) as "queryDuration" from pg_catalog.pg_stat_activity where pid <> pg_backend_pid();`
query := `select pid as pid, usename as user, datname as db, host(client_addr)::text || ':' || client_port::text as client, state as state, substring(query from 1 for ` + strconv.Itoa(maxQueryLength) + `) as query, coalesce(extract(epoch from now() - state_change), 0) as "stateDuration" from pg_catalog.pg_stat_activity where pid <> pg_backend_pid();`
rows, err := db.conn.Query(query)
Panic(err)
defer rows.Close()
@ -50,12 +50,12 @@ func (db *Db) Sessions() (sessions []Session) {
for rows.Next() {
var pid sql.NullInt64
var user, db, client, state, query sql.NullString
var backendDuration, xactDuration, queryDuration float64
err := rows.Scan(&pid, &user, &db, &client, &state, &query, &backendDuration, &xactDuration, &queryDuration)
var stateDuration float64
err := rows.Scan(&pid, &user, &db, &client, &state, &query, &stateDuration)
Panic(err)
if pid.Valid && user.Valid && db.Valid && client.Valid && state.Valid && query.Valid {
sessions = append(sessions, NewSession(pid.Int64, user.String, db.String, client.String, state.String, query.String, backendDuration, xactDuration, queryDuration))
sessions = append(sessions, NewSession(pid.Int64, user.String, db.String, client.String, state.String, query.String, stateDuration))
}
}

View file

@ -13,13 +13,11 @@ type Session struct {
Client string
State string
Query string
BackendDuration float64
XactDuration float64
QueryDuration float64
StateDuration float64
}
// NewSession instanciates a Session
func NewSession(pid int64, user string, db string, client string, state string, query string, backendDuration float64, xactDuration float64, queryDuration float64) Session {
func NewSession(pid int64, user string, db string, client string, state string, query string, stateDuration float64) Session {
return Session{
Pid: pid,
User: user,
@ -27,9 +25,7 @@ func NewSession(pid int64, user string, db string, client string, state string,
Client: client,
State: state,
Query: query,
BackendDuration: backendDuration,
XactDuration: xactDuration,
QueryDuration: queryDuration,
StateDuration: stateDuration,
}
}
@ -51,17 +47,19 @@ func (s Session) String() string {
if s.State != "" {
output = append(output, fmt.Sprintf("state=%s", s.State))
}
if s.BackendDuration != 0 {
output = append(output, fmt.Sprintf("backend_duration=%f", s.BackendDuration))
if s.StateDuration != 0 {
output = append(output, fmt.Sprintf("state_duration=%f", s.StateDuration))
}
if s.XactDuration != 0 {
output = append(output, fmt.Sprintf("xact_duration=%f", s.XactDuration))
}
if s.QueryDuration != 0 {
output = append(output, fmt.Sprintf("query_duration=%f", s.QueryDuration))
}
if s.Query != "" {
if s.Query != "" && !s.IsIdle() {
output = append(output, fmt.Sprintf("query=%s", s.Query))
}
return strings.Join(output, " ")
}
// IsIdle returns true when a session is doing nothing
func (s Session) IsIdle() bool {
if s.State == "idle" || s.State == "idle in transaction" || s.State == "idle in transaction (aborted)" {
return true
}
return false
}

View file

@ -67,11 +67,11 @@ func (t *Terminator) terminate() {
}
// activeSessions returns a list of active sessions
// A session is active when state is "active" and backend has started before elapsed
// A session is active when state is "active" and state has changed before elapsed seconds
// seconds
func activeSessions(sessions []base.Session, elapsed float64) (result []base.Session) {
for _, session := range sessions {
if session.State == "active" && session.QueryDuration > elapsed {
if session.State == "active" && session.StateDuration > elapsed {
result = append(result, session)
}
}
@ -79,14 +79,11 @@ func activeSessions(sessions []base.Session, elapsed float64) (result []base.Ses
}
// idleSessions returns a list of idle sessions
// A sessions is idle when state is "idle" and backend has started before elapsed seconds
// and when state is "idle in transaction" or "idle in transaction (aborted)" and
// transaction has started before elapsed seconds
// A sessions is idle when state is "idle", "idle in transaction" or "idle in transaction
// (aborted)"and state has changed before elapsed seconds
func idleSessions(sessions []base.Session, elapsed float64) (result []base.Session) {
for _, session := range sessions {
if session.State == "idle" && session.BackendDuration > elapsed {
result = append(result, session)
} else if (session.State == "idle in transaction" || session.State == "idle in transaction (aborted)") && session.XactDuration > elapsed {
if session.IsIdle() && session.StateDuration > elapsed {
result = append(result, session)
}
}