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)
114 case event := <-termboxChan:
115 // switch on event type
117 case termbox.EventKey: // actions depend on key
119 case termbox.KeyCtrlZ, termbox.KeyCtrlC, termbox.KeyEsc:
121 case termbox.KeyTab: // tab - change display modes
125 case '-': // decrease the interval if > 1
126 if interval > time.Second {
128 interval -= time.Second
129 ticker = time.NewTicker(interval)
131 case '+': // increase interval by creating a new ticker
133 interval += time.Second
134 ticker = time.NewTicker(interval)
136 state.SetHelp(!state.Help())
139 case 't': // toggle between absolute/relative statistics
140 state.SetWantRelativeStats(!state.WantRelativeStats())
141 case 'z': // reset the statistics to now by taking a query of current values
142 state.ResetDBStatistics()
144 case termbox.EventResize: // set sizes
145 state.ScreenSetSize(event.Width, event.Height)
146 case termbox.EventError: // quit
147 log.Fatalf("Quitting because of termbox error: \n%s\n", event.Err)
153 lib.Logger.Println("Terminating " + lib.MyName())