1 // Top like progream which collects information from MySQL's
2 // performance_schema database.
15 _ "github.com/go-sql-driver/mysql"
16 "github.com/nsf/termbox-go"
18 "github.com/sjmudd/mysql_defaults_file"
19 "github.com/sjmudd/pstop/lib"
20 "github.com/sjmudd/pstop/state"
21 "github.com/sjmudd/pstop/version"
26 db = "performance_schema"
29 func get_db_handle() *sql.DB {
33 dbh, err = mysql_defaults_file.OpenUsingDefaultsFile(sql_driver, "", "performance_schema")
37 if err = dbh.Ping(); err != nil {
44 // make chan for termbox events and run a poller to send events to the channel
45 // - return the channel
46 func new_tb_chan() chan termbox.Event {
47 termboxChan := make(chan termbox.Event)
50 termboxChan <- termbox.PollEvent()
57 fmt.Println(lib.MyName() + " - " + lib.Copyright())
59 fmt.Println("Top-like program to show MySQL activity by using information collected")
60 fmt.Println("from performance_schema.")
62 fmt.Println("Usage: " + lib.MyName() + " <options>")
64 fmt.Println("Options:")
65 fmt.Println("-help show this help message")
66 fmt.Println("-version show the version")
70 var flag_version = flag.Bool("version", false, "Show the version of "+lib.MyName())
71 var flag_debug = flag.Bool("debug", false, "Enabling debug logging")
72 var flag_help = flag.Bool("help", false, "Provide some help for "+lib.MyName())
77 lib.Logger.EnableLogging(true)
80 fmt.Println(lib.MyName() + " version " + version.Version())
88 lib.Logger.Println("Starting " + lib.MyName())
91 interval := time.Second
92 sigChan := make(chan os.Signal, 1)
93 done := make(chan struct{})
95 termboxChan := new_tb_chan()
97 signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
99 ticker := time.NewTicker(interval) // generate a periodic signal
101 state.Setup(get_db_handle())
107 fmt.Println("exiting")
109 case sig := <-sigChan:
110 fmt.Println("Caught a signal", sig)
115 case event := <-termboxChan:
116 // switch on event type
118 case termbox.EventKey: // actions depend on key
120 case termbox.KeyCtrlZ, termbox.KeyCtrlC, termbox.KeyEsc:
122 case termbox.KeyTab: // tab - change display modes
127 case '-': // decrease the interval if > 1
128 if interval > time.Second {
130 interval -= time.Second
131 ticker = time.NewTicker(interval)
133 case '+': // increase interval by creating a new ticker
135 interval += time.Second
136 ticker = time.NewTicker(interval)
138 state.SetHelp(!state.Help())
141 case 't': // toggle between absolute/relative statistics
142 state.SetWantRelativeStats(!state.WantRelativeStats())
144 case 'z': // reset the statistics to now by taking a query of current values
145 state.ResetDBStatistics()
148 case termbox.EventResize: // set sizes
149 state.ScreenSetSize(event.Width, event.Height)
151 case termbox.EventError: // quit
152 log.Fatalf("Quitting because of termbox error: \n%s\n", event.Err)
158 lib.Logger.Println("Terminating " + lib.MyName())