Skip to content

Commit

Permalink
top: do polling pg_stat_statements only if it's available (issue #59)
Browse files Browse the repository at this point in the history
  • Loading branch information
lesovsky committed Feb 13, 2019
1 parent 5e5565e commit c1293cf
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 12 deletions.
1 change: 1 addition & 0 deletions doc/Changelog
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pgcenter (0.6.1) unstable; urgency=low
* top: do polling pg_stat_statements only if it's available (issue #59)
* top: fixed handling of libpq errors during connection establishment (issue #58)
* top: fix srong assebling of path to logfile (issue #55)

Expand Down
36 changes: 24 additions & 12 deletions lib/stat/pgstat.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,16 @@ type Pgstat struct {

// PgInfo is the container for details about Postgres
type PgInfo struct {
PgAlive string /* is Postgres alive or not? */
PgVersionNum uint /* Postgres version in format XXYYZZ */
PgVersion string /* Postgres version in format X.Y.Z */
PgUptime string /* Postgres uptime */
PgRecovery string /* is Postgres master or standby? */
PgTrackCommitTs string /* track_commit_timestamp value */
PgAVMaxWorkers uint /* autovacuum_max_workers value */
PgMaxConns uint /* max_connections value */
PgMaxPrepXacts uint /* max_prepared_transactions value */
PgAlive string /* is Postgres alive or not? */
PgVersionNum uint /* Postgres version in format XXYYZZ */
PgVersion string /* Postgres version in format X.Y.Z */
PgUptime string /* Postgres uptime */
PgRecovery string /* is Postgres master or standby? */
PgTrackCommitTs string /* track_commit_timestamp value */
PgAVMaxWorkers uint /* autovacuum_max_workers value */
PgMaxConns uint /* max_connections value */
PgMaxPrepXacts uint /* max_prepared_transactions value */
PgStatStatementsAvail bool /* is pg_stat_statements available? */
}

// PgActivityStat is the container for Postgres' activity stats
Expand Down Expand Up @@ -146,12 +147,20 @@ func (s *Pgstat) ReadPgInfo(conn *sql.DB, isLocal bool) {
conn.QueryRow(PgGetSingleSettingQuery, "max_connections").Scan(&s.PgMaxConns)
conn.QueryRow(PgGetRecoveryStatusQuery).Scan(&s.PgRecovery)

// Is pg_stat_statement available?
s.UpdatePgStatStatementsStatus(conn)

// In case of remote Postgres we should to know remote CLK_TCK
if !isLocal {
conn.QueryRow(PgProcSysTicksQuery).Scan(&SysTicks)
}
}

// UpdatePgStatStatementsStatus method refreshes info about pg_stat_availability
func (s *Pgstat) UpdatePgStatStatementsStatus(conn *sql.DB) {
conn.QueryRow(PgCheckPGSSExists).Scan(&s.PgStatStatementsAvail)
}

// Reset method discards activity stats if Postgres restart detected
func (s *Pgstat) Reset() {
s.PgActivityStat.ConnTotal = 0
Expand Down Expand Up @@ -213,9 +222,12 @@ func (s *Pgstat) GetPgstatActivity(conn *sql.DB, refresh uint, isLocal bool) {
conn.QueryRow(queryAutovac).Scan(
&s.AVWorkers, &s.AVAntiwrap, &s.AVManual, &s.AVMaxTime)

conn.QueryRow(PgStatementsQuery).Scan(&s.StmtAvgTime, &s.CallsCurr)
s.StmtPerSec = (s.CallsCurr - s.CallsPrev) / refresh
s.CallsPrev = s.CallsCurr
// read pg_stat_statements only if it's available
if s.PgStatStatementsAvail == true {
conn.QueryRow(PgStatementsQuery).Scan(&s.StmtAvgTime, &s.CallsCurr)
s.StmtPerSec = (s.CallsCurr - s.CallsPrev) / refresh
s.CallsPrev = s.CallsCurr
}

conn.QueryRow(PgActivityTimeQuery).Scan(
&s.XactMaxTime, &s.PrepMaxTime)
Expand Down
2 changes: 2 additions & 0 deletions lib/stat/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const (
PgGetRecoveryStatusQuery = "SELECT pg_is_in_recovery()"
// PgGetUptimeQuery queries Postgres uptime
PgGetUptimeQuery = "SELECT date_trunc('seconds', now() - pg_postmaster_start_time())"
// PgCheckPGSSExists checks that pg_stat_statements view exists
PgCheckPGSSExists = "SELECT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'pg_stat_statements')"
// PgGetConfigAllQuery queries current Postgres configuration
PgGetConfigAllQuery = "SELECT name, setting, unit, category FROM pg_settings ORDER BY 4"
// PgGetCurrentLogfileQuery queries current Postgres logfile
Expand Down
6 changes: 6 additions & 0 deletions top/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ func setFilter(g *gocui.Gui, v *gocui.View, answer string) {
// Switch from context unit to another one
func switchContextTo(c string) func(g *gocui.Gui, v *gocui.View) error {
return func(g *gocui.Gui, v *gocui.View) error {
// in case of switching to pg_stat_statements and it isn't available - keep current stats context
if stats.PgStatStatementsAvail == false && c == stat.StatementsView {
printCmdline(g, msgPgStatStatementsUnavailable)
return nil
}

// Save current context unit with its settings into context list
ctx.contextList[ctx.current.Name] = ctx.current

Expand Down
6 changes: 6 additions & 0 deletions top/menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ var (
// Open 'gocui' view object and display menu items depending on passed menu type.
func menuOpen(m menuStyle) func(g *gocui.Gui, _ *gocui.View) error {
return func(g *gocui.Gui, _ *gocui.View) error {
// in case of opening menu for switching to pg_stat_statements and if pgss isn't available - it's unnecessary to open menu, just notify user and do nothing
if stats.PgStatStatementsAvail == false && m.menuType == menuPgss {
printCmdline(g, msgPgStatStatementsUnavailable)
return nil
}

g.Cursor = true

v, err := g.SetView("menu", 0, 5, 72, 6+len(m.menuItems))
Expand Down
5 changes: 5 additions & 0 deletions top/stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func doWork(g *gocui.Gui) {
break
}
printAllStat(g, stats)

// Check availability of pg_stat_statements if it's not available
if !stats.PgStatStatementsAvail {
stats.UpdatePgStatStatementsStatus(conn)
}
}

// Print all stats.
Expand Down
4 changes: 4 additions & 0 deletions top/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import (
"time"
)

const (
msgPgStatStatementsUnavailable = "NOTICE: pg_stat_statements is not available in this database"
)

var (
errSaved error // keep error during program lifecycle
cmdTimer *time.Timer // show cmdline's messages until timer is not expired
Expand Down

0 comments on commit c1293cf

Please sign in to comment.