Use state_change for measuring elapsed time
This commit is contained in:
parent
bb7ddf2bc5
commit
3a89201a94
3 changed files with 35 additions and 40 deletions
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,29 +7,25 @@ import (
|
|||
|
||||
// Session represents a PostgreSQL backend
|
||||
type Session struct {
|
||||
Pid int64
|
||||
User string
|
||||
Db string
|
||||
Client string
|
||||
State string
|
||||
Query string
|
||||
BackendDuration float64
|
||||
XactDuration float64
|
||||
QueryDuration float64
|
||||
Pid int64
|
||||
User string
|
||||
Db string
|
||||
Client string
|
||||
State string
|
||||
Query string
|
||||
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,
|
||||
Db: db,
|
||||
Client: client,
|
||||
State: state,
|
||||
Query: query,
|
||||
BackendDuration: backendDuration,
|
||||
XactDuration: xactDuration,
|
||||
QueryDuration: queryDuration,
|
||||
Pid: pid,
|
||||
User: user,
|
||||
Db: db,
|
||||
Client: client,
|
||||
State: state,
|
||||
Query: query,
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue