-// 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 {
+ done chan 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 ?
case showStages:
app.essgben.Collect(app.dbh)
}
+ app.wi.CollectedNow()
lib.Logger.Println("app.Collect() took", time.Duration(time.Since(start)).String())
}
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
}
}
}
-// 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() {
- done := make(chan struct{})
- defer close(done)
+ app.done = make(chan struct{})
+ defer close(app.done)
- sigChan := make(chan os.Signal, 1)
- signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
+ app.sigChan = make(chan os.Signal, 1)
+ signal.Notify(app.sigChan, syscall.SIGINT, syscall.SIGTERM)
- var wi wait_info.WaitInfo
- wi.SetWaitInterval(time.Second)
+ app.wi.SetWaitInterval(time.Second)
- termboxChan := new_tb_chan()
+ termboxChan := app.screen.TermBoxChan()
for !app.Finished() {
select {
- case <-done:
- fmt.Println("exiting")
+ case <-app.done:
+ fmt.Println("app.done(): exiting")
app.SetFinished()
- case sig := <-sigChan:
+ case sig := <-app.sigChan:
fmt.Println("Caught a signal", sig)
- done <- struct{}{}
- case <-wi.WaitNextPeriod():
+ app.done <- struct{}{}
+ case <-app.wi.WaitNextPeriod():
app.Collect()
- wi.CollectedNow()
app.Display()
case event := <-termboxChan:
// switch on event type
}
switch event.Ch {
case '-': // decrease the interval if > 1
- if wi.WaitInterval() > time.Second {
- wi.SetWaitInterval(wi.WaitInterval() - time.Second)
+ if app.wi.WaitInterval() > time.Second {
+ app.wi.SetWaitInterval(app.wi.WaitInterval() - time.Second)
}
case '+': // increase interval by creating a new ticker
- wi.SetWaitInterval(wi.WaitInterval() + time.Second)
+ app.wi.SetWaitInterval(app.wi.WaitInterval() + time.Second)
case 'h', '?': // help
app.SetHelp(!app.Help())
case 'q': // quit
// 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
+}