-// lib - library routines for pstop.
+// app - pstop application package
//
-// this file contains the library routines related to the stored state in pstop.
+// This file contains the library routines related to running the app.
package app
import (
)
var (
- re_valid_version = regexp.MustCompile(`^(5\.[67]\.|10\.[01])`)
+ re_valid_version = regexp.MustCompile(`^(5\.[67]\.|10\.[01])`)
)
type App struct {
sigChan chan os.Signal
wi wait_info.WaitInfo
finished bool
- datadir string
dbh *sql.DB
help bool
hostname string
app.dbh = dbh
if err := app.validate_mysql_version(); err != nil {
- log.Fatal(err)
- }
+ log.Fatal(err)
+ }
app.finished = false
-
app.screen.Initialise()
-
app.setup_instruments = setup_instruments.NewSetupInstruments(dbh)
app.setup_instruments.EnableMonitoring()
app.tiwsbt.SetWantRelativeStats(app.want_relative_stats)
app.tiwsbt.SetNow()
app.users.SetWantRelativeStats(app.want_relative_stats) // ignored
- app.users.SetNow() // ignored
+ app.users.SetNow() // ignored
app.essgben.SetWantRelativeStats(app.want_relative_stats)
app.essgben.SetNow()
app.ewsgben.SetWantRelativeStats(app.want_relative_stats) // ignored
- app.ewsgben.SetNow() // ignored
+ app.ewsgben.SetNow() // ignored
app.ResetDBStatistics()
hostname = hostname[0:index]
}
_, mysql_version := lib.SelectGlobalVariableByVariableName(app.dbh, "VERSION")
- _, datadir := lib.SelectGlobalVariableByVariableName(app.dbh, "DATADIR")
app.SetHostname(hostname)
app.SetMySQLVersion(mysql_version)
- app.SetDatadir(datadir)
}
// have we finished ?
return app.mysql_version
}
-func (app App) Datadir() string {
- return app.datadir
-}
-
func (app *App) SetHelp(newHelp bool) {
app.help = newHelp
app.screen.Flush()
}
-func (app *App) SetDatadir(datadir string) {
- app.datadir = datadir
-}
-
func (app *App) SetMySQLVersion(mysql_version string) {
app.mysql_version = mysql_version
}
app.screen.BoldPrintAt(0, 2, app.tiwsbt.Headings())
max_rows := app.screen.Height() - 3
+ last_row := app.screen.Height() - 1
row_content := app.tiwsbt.RowContent(max_rows)
// print out rows
for k := range row_content {
y := 3 + k
app.screen.PrintAt(0, y, row_content[k])
+ app.screen.ClearLine(len(row_content[k]), y)
}
// print out empty rows
- for k := len(row_content); k < (app.screen.Height() - 3); k++ {
+ for k := len(row_content); k < max_rows; k++ {
y := 3 + k
- if y < app.screen.Height()-1 {
+ if y < max_rows - 1 {
app.screen.PrintAt(0, y, app.tiwsbt.EmptyRowContent())
}
}
// print out the totals at the bottom
- app.screen.BoldPrintAt(0, app.screen.Height()-1, app.tiwsbt.TotalRowContent())
+ total := app.tiwsbt.TotalRowContent()
+ app.screen.BoldPrintAt(0, last_row, total)
+ app.screen.ClearLine(len(total), last_row)
}
// show actual I/O latency values
app.screen.BoldPrintAt(0, 2, app.fsbi.Headings())
// print out the data
- max_rows := app.screen.Height() - 3
+ max_rows := app.screen.Height() - 4
+ last_row := app.screen.Height() - 1
row_content := app.fsbi.RowContent(max_rows)
// print out rows
for k := range row_content {
y := 3 + k
app.screen.PrintAt(0, y, row_content[k])
+ app.screen.ClearLine(len(row_content[k]), y)
}
// print out empty rows
- for k := len(row_content); k < (app.screen.Height() - 3); k++ {
+ for k := len(row_content); k < max_rows; k++ {
y := 3 + k
- if y < app.screen.Height()-1 {
+ if y < last_row {
app.screen.PrintAt(0, y, app.fsbi.EmptyRowContent())
}
}
// print out the totals at the bottom
- app.screen.BoldPrintAt(0, app.screen.Height()-1, app.fsbi.TotalRowContent())
+ total := app.fsbi.TotalRowContent()
+ app.screen.BoldPrintAt(0, last_row, total)
+ app.screen.ClearLine(len(total), last_row)
}
func (app *App) displayLocks() {
app.screen.BoldPrintAt(0, 2, app.tlwsbt.Headings())
// print out the data
- max_rows := app.screen.Height() - 3
+ max_rows := app.screen.Height() - 4
+ last_row := app.screen.Height() - 1
row_content := app.tlwsbt.RowContent(max_rows)
// print out rows
for k := range row_content {
y := 3 + k
app.screen.PrintAt(0, y, row_content[k])
+ app.screen.ClearLine(len(row_content[k]), y)
}
// print out empty rows
for k := len(row_content); k < (app.screen.Height() - 3); k++ {
y := 3 + k
- if y < app.screen.Height()-1 {
+ if y < last_row {
app.screen.PrintAt(0, y, app.tlwsbt.EmptyRowContent())
}
}
// print out the totals at the bottom
- app.screen.BoldPrintAt(0, app.screen.Height()-1, app.tlwsbt.TotalRowContent())
+ total := app.tlwsbt.TotalRowContent()
+ app.screen.BoldPrintAt(0, last_row, total)
+ app.screen.ClearLine(len(total), last_row)
}
func (app *App) displayUsers() {
app.screen.BoldPrintAt(0, 2, app.users.Headings())
// print out the data
- max_rows := app.screen.Height() - 3
+ max_rows := app.screen.Height() - 4
+ last_row := app.screen.Height() - 1
row_content := app.users.RowContent(max_rows)
// print out rows
for k := range row_content {
y := 3 + k
app.screen.PrintAt(0, y, row_content[k])
+ app.screen.ClearLine(len(row_content[k]), y)
}
// print out empty rows
- for k := len(row_content); k < (app.screen.Height() - 3); k++ {
+ for k := len(row_content); k < max_rows; k++ {
y := 3 + k
- if y < app.screen.Height()-1 {
+ if y < last_row {
app.screen.PrintAt(0, y, app.users.EmptyRowContent())
}
}
// print out the totals at the bottom
- app.screen.BoldPrintAt(0, app.screen.Height()-1, app.users.TotalRowContent())
+ total := app.users.TotalRowContent()
+ app.screen.BoldPrintAt(0, last_row, total)
+ app.screen.ClearLine(len(total), last_row)
}
func (app *App) displayMutex() {
app.screen.BoldPrintAt(0, 2, app.ewsgben.Headings())
// print out the data
- max_rows := app.screen.Height() - 3
+ max_rows := app.screen.Height() - 4
+ last_row := app.screen.Height() - 1
row_content := app.ewsgben.RowContent(max_rows)
// print out rows
for k := range row_content {
y := 3 + k
app.screen.PrintAt(0, y, row_content[k])
+ app.screen.ClearLine(len(row_content[k]), y)
}
// print out empty rows
- for k := len(row_content); k < (app.screen.Height() - 3); k++ {
+ for k := len(row_content); k < max_rows; k++ {
y := 3 + k
- if y < app.screen.Height()-1 {
+ if y < last_row {
app.screen.PrintAt(0, y, app.ewsgben.EmptyRowContent())
}
}
// print out the totals at the bottom
- app.screen.BoldPrintAt(0, app.screen.Height()-1, app.ewsgben.TotalRowContent())
+ total := app.ewsgben.TotalRowContent()
+ app.screen.BoldPrintAt(0, last_row, total)
+ app.screen.ClearLine(len(total), last_row)
}
func (app *App) displayStages() {
app.screen.BoldPrintAt(0, 2, app.essgben.Headings())
// print out the data
- max_rows := app.screen.Height() - 3
+ max_rows := app.screen.Height() - 4
+ last_row := app.screen.Height() - 1
row_content := app.essgben.RowContent(max_rows)
// print out rows
for k := range row_content {
y := 3 + k
app.screen.PrintAt(0, y, row_content[k])
+ app.screen.ClearLine(len(row_content[k]), y)
}
// print out empty rows
- for k := len(row_content); k < (app.screen.Height() - 3); k++ {
+ for k := len(row_content); k < max_rows; k++ {
y := 3 + k
- if y < app.screen.Height()-1 {
+ if y < last_row {
app.screen.PrintAt(0, y, app.essgben.EmptyRowContent())
}
}
// print out the totals at the bottom
- app.screen.BoldPrintAt(0, app.screen.Height()-1, app.essgben.TotalRowContent())
+ total := app.essgben.TotalRowContent()
+ app.screen.BoldPrintAt(0, last_row, total)
+ app.screen.ClearLine(len(total), last_row)
}
// do we want to show all p_s data?
}
}
-// make chan for termbox events and run a poller to send events to the channel
-// - return the channel
-func new_tb_chan() chan termbox.Event {
- termboxChan := make(chan termbox.Event)
- go func() {
- for {
- termboxChan <- termbox.PollEvent()
- }
- }()
- return termboxChan
-}
-
// get into a run loop
func (app *App) Run() {
app.done = make(chan struct{})
app.wi.SetWaitInterval(time.Second)
- termboxChan := new_tb_chan()
+ termboxChan := app.screen.TermBoxChan()
for !app.Finished() {
select {
// rather than giving an error message if the requires P_S tables can't
// be found.
func (app *App) validate_mysql_version() error {
- var tables = [...]string{
- "performance_schema.events_waits_summary_global_by_event_name",
- "performance_schema.file_summary_by_instance",
- "performance_schema.table_io_waits_summary_by_table",
- "performance_schema.table_lock_waits_summary_by_table",
- }
-
- lib.Logger.Println("validate_mysql_version()")
-
- lib.Logger.Println("- Getting MySQL version")
- err, mysql_version := lib.SelectGlobalVariableByVariableName(app.dbh, "VERSION")
- if err != nil {
- return err
- }
- lib.Logger.Println("- mysql_version: '" + mysql_version + "'")
-
- if !re_valid_version.MatchString(mysql_version) {
- return errors.New(lib.MyName() + " does not work with MySQL version " + mysql_version)
- }
- lib.Logger.Println("OK: MySQL version is valid, continuing")
-
- lib.Logger.Println("Checking access to required tables:")
- for i := range tables {
- if err := lib.CheckTableAccess(app.dbh, tables[i]); err == nil {
- lib.Logger.Println("OK: " + tables[i] + " found")
- } else {
- return err
- }
- }
- lib.Logger.Println("OK: all table checks passed")
-
- return nil
+ var tables = [...]string{
+ "performance_schema.events_stages_summary_global_by_event_name",
+ "performance_schema.events_waits_summary_global_by_event_name",
+ "performance_schema.file_summary_by_instance",
+ "performance_schema.table_io_waits_summary_by_table",
+ "performance_schema.table_lock_waits_summary_by_table",
+ }
+
+ lib.Logger.Println("validate_mysql_version()")
+
+ lib.Logger.Println("- Getting MySQL version")
+ err, mysql_version := lib.SelectGlobalVariableByVariableName(app.dbh, "VERSION")
+ if err != nil {
+ return err
+ }
+ lib.Logger.Println("- mysql_version: '" + mysql_version + "'")
+
+ if !re_valid_version.MatchString(mysql_version) {
+ return errors.New(lib.MyName() + " does not work with MySQL version " + mysql_version)
+ }
+ lib.Logger.Println("OK: MySQL version is valid, continuing")
+
+ lib.Logger.Println("Checking access to required tables:")
+ for i := range tables {
+ if err := lib.CheckTableAccess(app.dbh, tables[i]); err == nil {
+ lib.Logger.Println("OK: " + tables[i] + " found")
+ } else {
+ return err
+ }
+ }
+ lib.Logger.Println("OK: all table checks passed")
+
+ return nil
}