Пример #1
0
//initializes a test instance of MysqlStat.
// instance does not connect with a db
func initMysqlStat() *MysqlStat {
	syscall.Dup2(int(logFile.Fd()), 2)
	s := new(MysqlStat)
	s.db = &testMysqlDB{
		Logger: log.New(os.Stderr, "TESTING LOG: ", log.Lshortfile),
	}
	s.Metrics = MysqlStatMetricsNew(metrics.NewMetricContext("system"),
		time.Millisecond*time.Duration(1)*1000)
	return s
}
Пример #2
0
func main() {
	var user, password, address, conf string
	var stepSec int
	var servermode, human bool

	m := metrics.NewMetricContext("system")

	flag.StringVar(&user, "u", "root", "user using database")
	flag.StringVar(&password, "p", "", "password for database")
	flag.BoolVar(&servermode, "server", false, "Runs continously and exposes metrics as JSON on HTTP")
	flag.StringVar(&address, "address", ":12345", "address to listen on for http if running in server mode")
	flag.IntVar(&stepSec, "step", 2, "metrics are collected every step seconds")
	flag.StringVar(&conf, "conf", "/root/.my.cnf", "configuration file")
	flag.BoolVar(&human, "h", false, "Makes output in MB for human readable sizes")
	flag.Parse()

	if servermode {
		go func() {
			http.HandleFunc("/metrics.json", m.HttpJsonHandler)
			log.Fatal(http.ListenAndServe(address, nil))
		}()
	}
	step := time.Millisecond * time.Duration(stepSec) * 1000

	sqlstat, err := mysqlstat.New(m, step, user, password, conf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	sqlstatTables, err := mysqlstattable.New(m, step, user, password, conf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	ticker := time.NewTicker(step * 2)
	for _ = range ticker.C {
		//Print stats here, more stats than printed are actually collected
		fmt.Println("--------------------------")
		fmt.Println("Version: " + strconv.FormatFloat(sqlstat.Metrics.Version.Get(), 'f', -1, 64))
		fmt.Println("Queries made: " + strconv.Itoa(int(sqlstat.Metrics.Queries.Get())))
		fmt.Println("Uptime: " + strconv.Itoa(int(sqlstat.Metrics.Uptime.Get())))
		fmt.Println("Database sizes: ")
		for dbname, db := range sqlstatTables.DBs {
			size := db.Metrics.SizeBytes.Get()
			units := " B"
			if human {
				size /= (1024 * 1024)
				units = " GB"
			}
			fmt.Println("    " + dbname + ": " + strconv.FormatFloat(size, 'f', 2, 64) + units)
		}
	}

}
Пример #3
0
func initMysqlStatTable() *MysqlStatTables {
	syscall.Dup2(int(logFile.Fd()), 2)
	s := new(MysqlStatTables)
	s.db = &testMysqlDB{
		Logger: log.New(os.Stderr, "TESTING LOG: ", log.Lshortfile),
	}
	s.nLock = &sync.Mutex{}

	s.m = metrics.NewMetricContext("system")
	s.DBs = make(map[string]*DBStats)
	return s
}
Пример #4
0
func main() {
	// options
	var batchmode, servermode bool
	var address string
	var stepSec int

	flag.BoolVar(&batchmode, "b", false, "Run in batch mode; suitable for parsing")
	flag.BoolVar(&batchmode, "batchmode", false, "Run in batch mode; suitable for parsing")
	flag.BoolVar(&servermode, "server", false,
		"Runs continously and exposes metrics as JSON on HTTP")
	flag.StringVar(&address, "address", ":19999",
		"address to listen on for http if running in server mode")
	flag.IntVar(&stepSec, "step", 2,
		"metrics are collected every step seconds")
	flag.Parse()

	if servermode {
		batchmode = true
	}

	if !batchmode {
		fmt.Println("Gathering statistics......")
	}

	// Initialize a metric context
	m := metrics.NewMetricContext("system")

	// Default step for collectors
	step := time.Millisecond * time.Duration(stepSec) * 1000

	// Collect cpu/memory/disk/per-pid metrics
	cstat := cpustat.New(m, step)
	mstat := memstat.New(m, step)
	procs := pidstat.NewProcessStat(m, step)

	// Filter processes which have < 1% CPU or < 1% memory
	// and try to keep minimum of 5

	procs.SetPidFilter(pidstat.PidFilterFunc(func(p *pidstat.PerProcessStat) bool {

		if len(procs.Processes) < DISPLAY_PID_COUNT {
			return true
		}

		if p.CPUUsage() > 1.0 {
			return true
		}
		memUsagePct := (p.MemUsage() / mstat.Total()) * 100.0
		if memUsagePct > 1.0 {
			return true
		}
		return false
	}))

	// pass the collected metrics to OS dependent set if they
	// need it
	osind := new(osmain.OsIndependentStats)
	osind.Cstat = cstat
	osind.Mstat = mstat
	osind.Procs = procs

	// register os dependent metrics
	// these could be specific to the OS (say cgroups)
	// or stats which are implemented not on all supported
	// platforms yet
	d := osmain.RegisterOsDependent(m, step, osind)

	// run http server
	if servermode {
		go func() {
			http.HandleFunc("/metrics.json", m.HttpJsonHandler)
			log.Fatal(http.ListenAndServe(address, nil))
		}()
	}

	// command line refresh every 2 step
	ticker := time.NewTicker(step * 2)
	for _ = range ticker.C {

		// Problems
		var problems []string

		if !batchmode {
			fmt.Printf("\033[2J") // clear screen
			fmt.Printf("\033[H")  // move cursor top left top
		}

		fmt.Println("--------------------------")
		mem_pct_usage := (mstat.Usage() / mstat.Total()) * 100
		fmt.Printf(
			"total: cpu: %3.1f%%, mem: %3.1f%% (%s/%s)\n",
			cstat.Usage(), mem_pct_usage,
			misc.ByteSize(mstat.Usage()), misc.ByteSize(mstat.Total()))

		if cstat.Usage() > 80.0 {
			problems = append(problems, "CPU usage > 80%")
		}

		if mem_pct_usage > 80.0 {
			problems = append(problems, "Memory usage > 80%")
		}

		// Top processes by usage
		procs_by_usage := procs.ByCPUUsage()
		fmt.Println("Top processes by CPU usage:")
		n := DISPLAY_PID_COUNT
		if len(procs_by_usage) < n {
			n = len(procs_by_usage)
		}

		for i := 0; i < n; i++ {
			fmt.Printf("cpu: %3.1f%%  command: %s user: %s pid: %v\n",
				procs_by_usage[i].CPUUsage(),
				procs_by_usage[i].Comm(),
				procs_by_usage[i].User(),
				procs_by_usage[i].Pid())
		}

		fmt.Println("---")
		procs_by_usage = procs.ByMemUsage()
		fmt.Println("Top processes by Mem usage:")
		n = DISPLAY_PID_COUNT
		if len(procs_by_usage) < n {
			n = len(procs_by_usage)
		}

		for i := 0; i < n; i++ {
			fmt.Printf("mem: %s command: %s user: %s pid: %v\n",
				misc.ByteSize(procs_by_usage[i].MemUsage()),
				procs_by_usage[i].Comm(),
				procs_by_usage[i].User(),
				procs_by_usage[i].Pid())
		}

		osmain.PrintOsDependent(d, batchmode)

		for i := range problems {
			msg := problems[i]
			if !batchmode {
				msg = ansi.Color(msg, "red")
			}
			fmt.Println("Problem: ", msg)
		}

		// be aggressive about reclaiming memory
		// tradeoff with CPU usage
		runtime.GC()
		debug.FreeOSMemory()
	}
}