コード例 #1
0
ファイル: ps-top.go プロジェクト: ChengShuY/ps-top
func usage() {
	fmt.Println(lib.MyName() + " - " + lib.Copyright())
	fmt.Println("")
	fmt.Println("Top-like program to show MySQL activity by using information collected")
	fmt.Println("from performance_schema.")
	fmt.Println("")
	fmt.Println("Usage: " + lib.MyName() + " <options>")
	fmt.Println("")
	fmt.Println("Options:")
	fmt.Println("--anonymise=<true|false>                 Anonymise hostname, user, db and table names")
	fmt.Println("--count=<count>                          Set the number of times to watch")
	fmt.Println("--defaults-file=/path/to/defaults.file   Connect to MySQL using given defaults-file")
	fmt.Println("--help                                   Show this help message")
	fmt.Println("--host=<hostname>                        MySQL host to connect to")
	fmt.Println("--interval=<seconds>                     Set the default poll interval (in seconds)")
	fmt.Println("--limit=<rows>                           Limit the number of lines of output (excluding headers)")
	fmt.Println("--password=<password>                    Password to use when connecting")
	fmt.Println("--port=<port>                            MySQL port to connect to")
	fmt.Println("--socket=<path>                          MySQL path of the socket to connect to")
	fmt.Println("--user=<user>                            User to connect with")
	fmt.Println("--use-environment                        Connect to MySQL using a go dsn collected from MYSQL_DSN e.g. MYSQL_DSN='test_user:test_pass@tcp(127.0.0.1:3306)/performance_schema'")
	fmt.Println("--version                                Show the version")
	fmt.Println("--view=<view>                            Determine the view you want to see when " + lib.MyName() + " starts (default: table_io_latency")
	fmt.Println("                                         Possible values: table_io_latency table_io_ops file_io_latency table_lock_latency user_latency mutex_latency stages_latency")
}
コード例 #2
0
ファイル: ps-top.go プロジェクト: denji/ps-top
func main() {
	flag.Parse()

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *flagDebug {
		logger.Enable(lib.MyName() + ".log")
	}
	if *flagVersion {
		fmt.Println(lib.MyName() + " version " + version.Version())
		return
	}
	if *flagHelp {
		usage()
		return
	}

	conn := connector.NewConnector(flagHost, flagSocket, flagPort, flagUser, flagPassword, flagDefaultsFile)
	disp := display.NewScreenDisplay(*flagLimit, false)

	app := app.NewApp(conn, *flagInterval, *flagCount, false, *flagView, disp)
	app.Run()
	app.Cleanup()
}
コード例 #3
0
ファイル: ps-stats.go プロジェクト: denji/ps-top
func main() {
	var err = errors.New("unknown")

	flag.Parse()

	// Too many arguments
	if len(flag.Args()) > 2 {
		usage()
		os.Exit(1)
	}
	// delay
	if len(flag.Args()) >= 1 {
		delay, err = strconv.Atoi(flag.Args()[0])
		if err != nil {
			log.Fatal("Unable to parse delay: ", err)
		}
	} else {
		delay = 1
	}
	// count
	if len(flag.Args()) >= 2 {
		count, err = strconv.Atoi(flag.Args()[1])
		if err != nil {
			log.Fatal("Unable to parse count: ", err)
		}
	} else {
		count = 0
	}

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *flagDebug {
		logger.Enable(lib.MyName() + ".log")
	}
	if *flagVersion {
		fmt.Println(lib.MyName() + " version " + version.Version())
		return
	}
	if *flagHelp {
		usage()
		return
	}

	conn := connector.NewConnector(flagHost, flagSocket, flagPort, flagUser, flagPassword, flagDefaultsFile)
	disp := display.NewStdoutDisplay(*flagLimit, true)

	app := app.NewApp(conn, delay, count, true, *flagView, disp)
	app.Run()
	app.Cleanup()
}
コード例 #4
0
ファイル: screen.go プロジェクト: ChengShuY/ps-top
// Initialise initialises the screen and clears it on startup
func (s *TermboxScreen) Initialise() {
	err := termbox.Init()
	if err != nil {
		fmt.Println("Could not start termbox for " + lib.MyName() + ". View ~/." + lib.MyName() + ".log for error messages.")
		log.Printf("Cannot start "+lib.MyName()+", termbox.Init() gave an error:\n%s\n", err)
		os.Exit(1)
	}

	s.Clear()
	s.fg = termbox.ColorDefault
	s.bg = termbox.ColorDefault

	s.SetSize(termbox.Size())
}
コード例 #5
0
ファイル: flags.go プロジェクト: ChengShuY/ps-top
// new connector returns a connected Connector given the different parameters
func NewConnector(flags Flags) *Connector {
	var defaultsFile string
	connector := new(Connector)

	if *flags.UseEnvironment {
		connector.ConnectByEnvironment()
	} else {
		if *flags.Host != "" || *flags.Socket != "" {
			logger.Println("--host= or --socket= defined")
			var components = make(map[string]string)
			if *flags.Host != "" && *flags.Socket != "" {
				fmt.Println(lib.MyName() + ": Do not specify --host and --socket together")
				os.Exit(1)
			}
			if *flags.Host != "" {
				components["host"] = *flags.Host
			}
			if *flags.Port != 0 {
				if *flags.Socket == "" {
					components["port"] = fmt.Sprintf("%d", *flags.Port)
				} else {
					fmt.Println(lib.MyName() + ": Do not specify --socket and --port together")
					os.Exit(1)
				}
			}
			if *flags.Socket != "" {
				components["socket"] = *flags.Socket
			}
			if *flags.User != "" {
				components["user"] = *flags.User
			}
			if *flags.Password != "" {
				components["password"] = *flags.Password
			}
			connector.ConnectByComponents(components)
		} else {
			if flags.DefaultsFile != nil && *flags.DefaultsFile != "" {
				logger.Println("--defaults-file defined")
				defaultsFile = *flags.DefaultsFile
			} else {
				logger.Println("connecting by implicit defaults file")
			}
			connector.ConnectByDefaultsFile(defaultsFile)
		}
	}

	return connector
}
コード例 #6
0
ファイル: ps-stats.go プロジェクト: denji/ps-top
func usage() {
	fmt.Println(lib.MyName() + " - " + lib.Copyright())
	fmt.Println("")
	fmt.Println("vmstat-like program to show MySQL activity by using information collected")
	fmt.Println("from performance_schema without sent to stdout.")
	fmt.Println("")
	fmt.Println("Usage: " + lib.MyName() + " <options> [delay [count]]")
	fmt.Println("")
	fmt.Println("Options:")
	fmt.Println("--defaults-file=/path/to/defaults.file   Connect to MySQL using given defaults-file")
	fmt.Println("--help                                   Show this help message")
	fmt.Println("--host=<hostname>                        MySQL host to connect to")
	fmt.Println("--limit=<rows>                           Limit the number of lines of output (excluding headers)")
	fmt.Println("--password=<password>                    Password to use when connecting")
	fmt.Println("--port=<port>                            MySQL port to connect to")
	fmt.Println("--socket=<path>                          MySQL path of the socket to connect to")
	fmt.Println("--totals                                 Only send the totals to stdout (in stdout mode)")
	fmt.Println("--user=<user>                            User to connect with")
	fmt.Println("--version                                Show the version")
	fmt.Println("--view=<view>                            Determine the view you want to see when " + lib.MyName() + " starts (default: table_io_latency")
	fmt.Println("                                         Possible values: table_io_latency table_io_ops file_io_latency table_lock_latency user_latency mutex_latency stages_latency")
}
コード例 #7
0
ファイル: app.go プロジェクト: ChengShuY/ps-top
// ensure performance_schema is enabled
// - if not will not return and will exit
func ensurePerformanceSchemaEnabled(variables *global.Variables) {
	if variables == nil {
		log.Fatal("ensurePerformanceSchemaEnabled() variables is nil")
	}

	// check that performance_schema = ON
	if value := variables.Get("performance_schema"); value != "ON" {
		log.Fatal(fmt.Sprintf("ensurePerformanceSchemaEnabled(): performance_schema = '%s'. Please configure performance_schema = 1 in /etc/my.cnf (or equivalent) and restart mysqld to use %s.",
			value, lib.MyName()))
	} else {
		logger.Println("performance_schema = ON check succeeds")
	}
}
コード例 #8
0
ファイル: ps-top.go プロジェクト: ChengShuY/ps-top
func main() {
	connectorFlags = connector.Flags{
		DefaultsFile:   flag.String("defaults-file", "", "Define the defaults file to read"),
		Host:           flag.String("host", "", "Provide the hostname of the MySQL to connect to"),
		Password:       flag.String("password", "", "Provide the password when connecting to the MySQL server"),
		Port:           flag.Int("port", 0, "Provide the port number of the MySQL to connect to (default: 3306)"), /* Port is deliberately 0 here, defaults to 3306 elsewhere */
		Socket:         flag.String("socket", "", "Provide the path to the local MySQL server to connect to"),
		User:           flag.String("user", "", "Provide the username to connect with to MySQL (default: $USER)"),
		UseEnvironment: flag.Bool("use-environment", false, "Use the environment variable MYSQL_DSN (go dsn) to connect with to MySQL"),
	}

	flag.Parse()

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *flagDebug {
		logger.Enable()
	}
	if *flagVersion {
		fmt.Println(lib.MyName() + " version " + version.Version())
		return
	}
	if *flagHelp {
		usage()
		return
	}

	settings := app.Settings{
		Anonymise: *flagAnonymise,
		Conn:      connector.NewConnector(connectorFlags),
		Interval:  *flagInterval,
		Count:     *flagCount,
		Stdout:    false,
		View:      *flagView,
		Disp:      display.NewScreenDisplay(*flagLimit, false),
	}

	app := app.NewApp(settings)
	app.Run()
	app.Cleanup()
}
コード例 #9
0
ファイル: screen.go プロジェクト: ChengShuY/ps-top
// DisplayHelp displays a help page on the screen
func (s *ScreenDisplay) DisplayHelp() {
	s.screen.PrintAt(0, 0, lib.MyName()+" version "+version.Version()+" "+lib.Copyright())

	s.screen.PrintAt(0, 2, "Program to show the top I/O information by accessing information from the")
	s.screen.PrintAt(0, 3, "performance_schema schema. Ideas based on mysql-sys.")

	s.screen.PrintAt(0, 5, "Keys:")
	s.screen.PrintAt(0, 6, "- - reduce the poll interval by 1 second (minimum 1 second)")
	s.screen.PrintAt(0, 7, "+ - increase the poll interval by 1 second")
	s.screen.PrintAt(0, 8, "h/? - this help screen")
	s.screen.PrintAt(0, 9, "q - quit")
	s.screen.PrintAt(0, 10, "s - sort differently (where enabled) - sorts on a different column")
	s.screen.PrintAt(0, 11, "t - toggle between showing time since resetting statistics or since P_S data was collected")
	s.screen.PrintAt(0, 12, "z - reset statistics")
	s.screen.PrintAt(0, 13, "<tab> or <right arrow> - change display modes between: latency, ops, file I/O, lock and user modes")
	s.screen.PrintAt(0, 14, "<left arrow> - change display modes to the previous screen (see above)")
	s.screen.PrintAt(0, 16, "Press h to return to main screen")
}
コード例 #10
0
ファイル: logger.go プロジェクト: ChengShuY/ps-top
// EnableLogging allows me to do this or not
func Enable() bool {
	if enabled {
		return enabled // as nothing to do
	}

	oldValue := enabled

	enabled = true
	logfile = lib.MyName() + ".log"

	file, err := os.OpenFile(logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		log.Fatal("Failed to open log file", logfile, ":", err)
	}
	logger = log.New(file, "", log.Ldate|log.Ltime)

	return oldValue
}
コード例 #11
0
ファイル: context.go プロジェクト: ChengShuY/ps-top
// MyName returns the program's name
func (c Context) MyName() string {
	return lib.MyName()
}
コード例 #12
0
ファイル: ps-stats.go プロジェクト: denji/ps-top
	"github.com/sjmudd/ps-top/app"
	"github.com/sjmudd/ps-top/connector"
	"github.com/sjmudd/ps-top/display"
	"github.com/sjmudd/ps-top/lib"
	"github.com/sjmudd/ps-top/logger"
	"github.com/sjmudd/ps-top/version"
)

var (
	count int
	delay int

	cpuprofile       = flag.String("cpuprofile", "", "write cpu profile to file")
	flagDebug        = flag.Bool("debug", false, "Enabling debug logging")
	flagDefaultsFile = flag.String("defaults-file", "", "Provide a defaults-file to use to connect to MySQL")
	flagHelp         = flag.Bool("help", false, "Provide some help for "+lib.MyName())
	flagHost         = flag.String("host", "", "Provide the hostname of the MySQL to connect to")
	flagLimit        = flag.Int("limit", 0, "Show a maximum of limit entries (defaults to screen size if output to screen)")
	flagPassword     = flag.String("password", "", "Provide the password when connecting to the MySQL server")
	flagPort         = flag.Int("port", 0, "Provide the port number of the MySQL to connect to (default: 3306)") /* deliberately 0 here, defaults to 3306 elsewhere */
	flagSocket       = flag.String("socket", "", "Provide the path to the local MySQL server to connect to")
	flagTotals       = flag.Bool("totals", false, "Only show the totals when in stdout mode and no detail (default: false)")
	flagUser         = flag.String("user", "", "Provide the username to connect with to MySQL (default: $USER)")
	flagVersion      = flag.Bool("version", false, "Show the version of "+lib.MyName())
	flagView         = flag.String("view", "", "Provide view to show when starting "+lib.MyName()+" (default: table_io_latency)")
)

func usage() {
	fmt.Println(lib.MyName() + " - " + lib.Copyright())
	fmt.Println("")
	fmt.Println("vmstat-like program to show MySQL activity by using information collected")
コード例 #13
0
ファイル: ps-stats.go プロジェクト: ChengShuY/ps-top
func main() {
	connectorFlags = connector.Flags{
		Host:           flag.String("host", "", "Provide the hostname of the MySQL to connect to"),
		Password:       flag.String("password", "", "Provide the password when connecting to the MySQL server"),
		Port:           flag.Int("port", 0, "Provide the port number of the MySQL to connect to (default: 3306)"), /* Port is deliberately 0 here, defaults to 3306 elsewhere */
		Socket:         flag.String("socket", "", "Provide the path to the local MySQL server to connect to"),
		User:           flag.String("user", "", "Provide the username to connect with to MySQL (default: $USER)"),
		UseEnvironment: flag.Bool("use-environment", false, "Use the environment variable MYSQL_DSN (go dsn) to connect with to MySQL"),
	}

	var err = errors.New("unknown")

	flag.Parse()

	// Too many arguments
	if len(flag.Args()) > 2 {
		usage()
		os.Exit(1)
	}
	// delay
	if len(flag.Args()) >= 1 {
		delay, err = strconv.Atoi(flag.Args()[0])
		if err != nil {
			log.Fatal("Unable to parse delay: ", err)
		}
	} else {
		delay = 1
	}
	// count
	if len(flag.Args()) >= 2 {
		count, err = strconv.Atoi(flag.Args()[1])
		if err != nil {
			log.Fatal("Unable to parse count: ", err)
		}
	} else {
		count = 0
	}

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *flagDebug {
		logger.Enable()
	}
	if *flagVersion {
		fmt.Println(lib.MyName() + " version " + version.Version())
		return
	}
	if *flagHelp {
		usage()
		return
	}

	settings := app.Settings{
		Conn:     connector.NewConnector(connectorFlags),
		Interval: delay,
		Count:    count,
		Stdout:   true,
		View:     *flagView,
		Disp:     display.NewStdoutDisplay(*flagLimit, true),
	}

	app := app.NewApp(settings)
	app.Run()
	app.Cleanup()
}
コード例 #14
0
ファイル: base.go プロジェクト: denji/ps-top
// MyName returns the application name (binary name)
func (d BaseDisplay) MyName() string {
	return lib.MyName()
}