From 3a89201a940dd8d759299f79f4f15feed1db6c02 Mon Sep 17 00:00:00 2001 From: Julien Riou Date: Mon, 11 Jun 2018 21:02:24 +0200 Subject: [PATCH] Use state_change for measuring elapsed time --- base/db.go | 8 +++--- base/session.go | 54 +++++++++++++++++++--------------------- terminator/terminator.go | 13 ++++------ 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/base/db.go b/base/db.go index fcd49d6..ee210f5 100644 --- a/base/db.go +++ b/base/db.go @@ -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)) } } diff --git a/base/session.go b/base/session.go index 0ced787..8fdccc5 100644 --- a/base/session.go +++ b/base/session.go @@ -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 +} diff --git a/terminator/terminator.go b/terminator/terminator.go index fde6ea2..e2739c5 100644 --- a/terminator/terminator.go +++ b/terminator/terminator.go @@ -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) } }