X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=state%2Fstate.go;h=de0d4ff7b1992065bba6885ba92d45d3e7076671;hb=ac65d456eb98d64e3262ce8c3ac3d1ee0a27ee9f;hp=4df68d259a52cf74d4e0541496038264cb220799;hpb=5b2ab1f1d0e4066b9ed416fc7c829ab75b33870c;p=pstop.git diff --git a/state/state.go b/state/state.go index 4df68d2..de0d4ff 100644 --- a/state/state.go +++ b/state/state.go @@ -6,15 +6,21 @@ package state import ( "database/sql" "fmt" + "strings" "time" + "github.com/sjmudd/pstop/i_s/processlist" "github.com/sjmudd/pstop/lib" - fsbi "github.com/sjmudd/pstop/performance_schema/file_summary_by_instance" - "github.com/sjmudd/pstop/performance_schema/ps_table" - tiwsbt "github.com/sjmudd/pstop/performance_schema/table_io_waits_summary_by_table" - tlwsbt "github.com/sjmudd/pstop/performance_schema/table_lock_waits_summary_by_table" + ewsgben "github.com/sjmudd/pstop/p_s/events_waits_summary_global_by_event_name" + essgben "github.com/sjmudd/pstop/p_s/events_stages_summary_global_by_event_name" + fsbi "github.com/sjmudd/pstop/p_s/file_summary_by_instance" + "github.com/sjmudd/pstop/p_s/ps_table" + "github.com/sjmudd/pstop/p_s/setup_instruments" + tiwsbt "github.com/sjmudd/pstop/p_s/table_io_waits_summary_by_table" + tlwsbt "github.com/sjmudd/pstop/p_s/table_lock_waits_summary_by_table" "github.com/sjmudd/pstop/screen" "github.com/sjmudd/pstop/version" + "github.com/sjmudd/pstop/wait_info" ) // what information to show @@ -25,31 +31,46 @@ const ( showOps = iota showIO = iota showLocks = iota + showUsers = iota + showMutex = iota + showStages = iota ) type State struct { + finished bool datadir string dbh *sql.DB help bool hostname string fsbi ps_table.Tabler // ufsbi.File_summary_by_instance - tiwsbt tiwsbt.Table_io_waits_summary_by_table + tiwsbt tiwsbt.Object tlwsbt ps_table.Tabler // tlwsbt.Table_lock_waits_summary_by_table + ewsgben ps_table.Tabler // ewsgben.Events_waits_summary_global_by_event_name + essgben ps_table.Tabler // essgben.Events_stages_summary_global_by_event_name + users processlist.Object screen screen.TermboxScreen show Show mysql_version string want_relative_stats bool + wait_info.WaitInfo // embedded + setup_instruments setup_instruments.SetupInstruments } func (state *State) Setup(dbh *sql.DB) { state.dbh = dbh + state.finished = false state.screen.Initialise() + state.setup_instruments = setup_instruments.NewSetupInstruments(dbh) + state.setup_instruments.EnableMonitoring() + _, variables := lib.SelectAllGlobalVariablesByVariableName(state.dbh) // setup to their initial types/values state.fsbi = fsbi.NewFileSummaryByInstance(variables) - state.tlwsbt = new(tlwsbt.Table_lock_waits_summary_by_table) + state.tlwsbt = new(tlwsbt.Object) + state.ewsgben = new(ewsgben.Object) + state.essgben = new(essgben.Object) state.want_relative_stats = true // we show info from the point we start collecting data state.fsbi.SetWantRelativeStats(state.want_relative_stats) @@ -58,6 +79,12 @@ func (state *State) Setup(dbh *sql.DB) { state.tlwsbt.SetNow() state.tiwsbt.SetWantRelativeStats(state.want_relative_stats) state.tiwsbt.SetNow() + state.users.SetWantRelativeStats(state.want_relative_stats) // ignored + state.users.SetNow() // ignored + state.essgben.SetWantRelativeStats(state.want_relative_stats) + state.essgben.SetNow() + state.ewsgben.SetWantRelativeStats(state.want_relative_stats) // ignored + state.ewsgben.SetNow() // ignored state.ResetDBStatistics() @@ -65,7 +92,11 @@ func (state *State) Setup(dbh *sql.DB) { state.show = showLatency state.tiwsbt.SetWantsLatency(true) + // get short name (to save space) _, hostname := lib.SelectGlobalVariableByVariableName(state.dbh, "HOSTNAME") + if index := strings.Index(hostname, "."); index >= 0 { + hostname = hostname[0:index] + } _, mysql_version := lib.SelectGlobalVariableByVariableName(state.dbh, "VERSION") _, datadir := lib.SelectGlobalVariableByVariableName(state.dbh, "DATADIR") state.SetHostname(hostname) @@ -73,22 +104,36 @@ func (state *State) Setup(dbh *sql.DB) { state.SetDatadir(datadir) } +// have we finished ? +func (state State) Finished() bool { + return state.finished +} + +// indicate we have finished +func (state *State) SetFinished() { + state.finished = true +} + // do a fresh collection of data and then update the initial values based on that. func (state *State) ResetDBStatistics() { - // collect all initial values on startup / reset - state.fsbi.Collect(state.dbh) - state.tlwsbt.Collect(state.dbh) - state.tiwsbt.Collect(state.dbh) - - state.UpdateInitialValues() + state.CollectAll() + state.SyncReferenceValues() } -func (state *State) UpdateInitialValues() { +func (state *State) SyncReferenceValues() { start := time.Now() - state.fsbi.UpdateInitialValues() - state.tlwsbt.UpdateInitialValues() - state.tiwsbt.UpdateInitialValues() - lib.Logger.Println("state.UpdateInitialValues() took", time.Duration(time.Since(start)).String()) + state.fsbi.SyncReferenceValues() + state.tlwsbt.SyncReferenceValues() + state.tiwsbt.SyncReferenceValues() + state.essgben.SyncReferenceValues() + lib.Logger.Println("state.SyncReferenceValues() took", time.Duration(time.Since(start)).String()) +} + +// collect all initial values on startup / reset +func (state *State) CollectAll() { + state.fsbi.Collect(state.dbh) + state.tlwsbt.Collect(state.dbh) + state.tiwsbt.Collect(state.dbh) } // Only collect the data we are looking at. @@ -102,6 +147,12 @@ func (state *State) Collect() { state.fsbi.Collect(state.dbh) case showLocks: state.tlwsbt.Collect(state.dbh) + case showUsers: + state.users.Collect(state.dbh) + case showMutex: + state.ewsgben.Collect(state.dbh) + case showStages: + state.essgben.Collect(state.dbh) } lib.Logger.Println("state.Collect() took", time.Duration(time.Since(start)).String()) } @@ -137,6 +188,8 @@ func (state State) Help() bool { return state.help } +// states go: showLatency -> showOps -> showIO -> showLocks -> showUsers -> showMutex -> showStages + // display the output according to the mode we are in func (state *State) Display() { if state.help { @@ -150,31 +203,54 @@ func (state *State) Display() { state.displayIO() case showLocks: state.displayLocks() + case showUsers: + state.displayUsers() + case showMutex: + state.displayMutex() + case showStages: + state.displayStages() } } } -// change to the next display mode -func (state *State) DisplayNext() { - if state.show == showLocks { - state.show = showLatency - } else { - state.show++ - } - // this needs to be done more cleanly +// fix_latency_setting() ensures the SetWantsLatency() value is +// correct. This needs to be done more cleanly. +func (state *State) fix_latency_setting() { if state.show == showLatency { state.tiwsbt.SetWantsLatency(true) } if state.show == showOps { state.tiwsbt.SetWantsLatency(false) } +} + +// change to the previous display mode +func (state *State) DisplayPrevious() { + if state.show == showLatency { + state.show = showStages + } else { + state.show-- + } + state.fix_latency_setting() + state.screen.Clear() + state.screen.Flush() +} + +// change to the next display mode +func (state *State) DisplayNext() { + if state.show == showStages { + state.show = showLatency + } else { + state.show++ + } + state.fix_latency_setting() state.screen.Clear() state.screen.Flush() } func (state State) displayHeading() { state.displayLine0() - state.displayLine1() + state.displayDescription() } func (state State) displayLine0() { @@ -192,8 +268,14 @@ func (state State) displayLine0() { initial = state.fsbi.Last() case showLocks: initial = state.tlwsbt.Last() + case showUsers: + initial = state.users.Last() + case showStages: + initial = state.essgben.Last() + case showMutex: + initial = state.ewsgben.Last() default: - initial = time.Now() // THIS IS WRONG !!! + // should not get here ! } d := now.Sub(initial) @@ -205,21 +287,29 @@ func (state State) displayLine0() { state.screen.PrintAt(0, 0, top_line) } -func (state State) displayLine1() { +func (state State) displayDescription() { + description := "UNKNOWN" + switch state.show { case showLatency, showOps: - state.screen.PrintAt(0, 1, state.tiwsbt.Description()) + description = state.tiwsbt.Description() case showIO: - state.screen.PrintAt(0, 1, state.fsbi.Description()) + description = state.fsbi.Description() case showLocks: - state.screen.PrintAt(0, 1, state.tlwsbt.Description()) - default: - state.screen.PrintAt(0, 1, "UNKNOWN") + description = state.tlwsbt.Description() + case showUsers: + description = state.users.Description() + case showMutex: + description = state.ewsgben.Description() + case showStages: + description = state.essgben.Description() } + + state.screen.PrintAt(0, 1, description) } func (state *State) displayOpsOrLatency() { - state.screen.PrintAt(0, 2, state.tiwsbt.Headings()) + state.screen.BoldPrintAt(0, 2, state.tiwsbt.Headings()) max_rows := state.screen.Height() - 3 row_content := state.tiwsbt.RowContent(max_rows) @@ -238,12 +328,12 @@ func (state *State) displayOpsOrLatency() { } // print out the totals at the bottom - state.screen.PrintAt(0, state.screen.Height()-1, state.tiwsbt.TotalRowContent()) + state.screen.BoldPrintAt(0, state.screen.Height()-1, state.tiwsbt.TotalRowContent()) } // show actual I/O latency values func (state State) displayIO() { - state.screen.PrintAt(0, 2, state.fsbi.Headings()) + state.screen.BoldPrintAt(0, 2, state.fsbi.Headings()) // print out the data max_rows := state.screen.Height() - 3 @@ -263,11 +353,11 @@ func (state State) displayIO() { } // print out the totals at the bottom - state.screen.PrintAt(0, state.screen.Height()-1, state.fsbi.TotalRowContent()) + state.screen.BoldPrintAt(0, state.screen.Height()-1, state.fsbi.TotalRowContent()) } func (state *State) displayLocks() { - state.screen.PrintAt(0, 2, state.tlwsbt.Headings()) + state.screen.BoldPrintAt(0, 2, state.tlwsbt.Headings()) // print out the data max_rows := state.screen.Height() - 3 @@ -287,9 +377,82 @@ func (state *State) displayLocks() { } // print out the totals at the bottom - state.screen.PrintAt(0, state.screen.Height()-1, state.tlwsbt.TotalRowContent()) + state.screen.BoldPrintAt(0, state.screen.Height()-1, state.tlwsbt.TotalRowContent()) +} + +func (state *State) displayUsers() { + state.screen.BoldPrintAt(0, 2, state.users.Headings()) + + // print out the data + max_rows := state.screen.Height() - 3 + row_content := state.users.RowContent(max_rows) + + // print out rows + for k := range row_content { + y := 3 + k + state.screen.PrintAt(0, y, row_content[k]) + } + // print out empty rows + for k := len(row_content); k < (state.screen.Height() - 3); k++ { + y := 3 + k + if y < state.screen.Height()-1 { + state.screen.PrintAt(0, y, state.users.EmptyRowContent()) + } + } + + // print out the totals at the bottom + state.screen.BoldPrintAt(0, state.screen.Height()-1, state.users.TotalRowContent()) } +func (state *State) displayMutex() { + state.screen.BoldPrintAt(0, 2, state.ewsgben.Headings()) + + // print out the data + max_rows := state.screen.Height() - 3 + row_content := state.ewsgben.RowContent(max_rows) + + // print out rows + for k := range row_content { + y := 3 + k + state.screen.PrintAt(0, y, row_content[k]) + } + // print out empty rows + for k := len(row_content); k < (state.screen.Height() - 3); k++ { + y := 3 + k + if y < state.screen.Height()-1 { + state.screen.PrintAt(0, y, state.ewsgben.EmptyRowContent()) + } + } + + // print out the totals at the bottom + state.screen.BoldPrintAt(0, state.screen.Height()-1, state.ewsgben.TotalRowContent()) +} + +func (state *State) displayStages() { + state.screen.BoldPrintAt(0, 2, state.essgben.Headings()) + + // print out the data + max_rows := state.screen.Height() - 3 + row_content := state.essgben.RowContent(max_rows) + + // print out rows + for k := range row_content { + y := 3 + k + state.screen.PrintAt(0, y, row_content[k]) + } + // print out empty rows + for k := len(row_content); k < (state.screen.Height() - 3); k++ { + y := 3 + k + if y < state.screen.Height()-1 { + state.screen.PrintAt(0, y, state.essgben.EmptyRowContent()) + } + } + + // print out the totals at the bottom + state.screen.BoldPrintAt(0, state.screen.Height()-1, state.essgben.TotalRowContent()) +} + + // do we want to show all p_s data? func (state State) WantRelativeStats() bool { return state.want_relative_stats @@ -302,8 +465,8 @@ func (state *State) SetWantRelativeStats(want_relative_stats bool) { state.fsbi.SetWantRelativeStats(want_relative_stats) state.tlwsbt.SetWantRelativeStats(state.want_relative_stats) state.tiwsbt.SetWantRelativeStats(state.want_relative_stats) - - state.Display() + state.ewsgben.SetWantRelativeStats(state.want_relative_stats) + state.essgben.SetWantRelativeStats(state.want_relative_stats) } // if there's a better way of doing this do it better ... @@ -321,6 +484,7 @@ func (state *State) ScreenSetSize(width, height int) { func (state *State) Cleanup() { state.screen.Close() if state.dbh != nil { + state.setup_instruments.RestoreConfiguration() _ = state.dbh.Close() } }