Пример #1
0
//initializes a test instance of MysqlStatDBs.
// instance does not connect with a db
func initMysqlStatDBs() *MysqlStatDBs {
	syscall.Dup2(int(logFile.Fd()), 2)
	s := new(MysqlStatDBs)
	s.Db = &testMysqlDB{
		Logger: log.New(os.Stderr, "TESTING LOG: ", log.Lshortfile),
	}
	s.Metrics = MysqlStatMetricsNew(metrics.NewMetricContext("system"))
	return s
}
Пример #2
0
func TestMemstat(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	mstat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 100)
	var expected float64 = 1.779400704e+09
	actual := mstat.Usage()
	if actual != expected {
		t.Errorf("Memstat Usage: %v expected: %v", actual, expected)
	}
}
Пример #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 TestTcpstat(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	tstat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 200)
	var expected float64 = 45
	actual := tstat.CurrEstab.Get()
	if actual != expected {
		t.Errorf("Tcpstat current estab: %v expected: %v", actual, expected)
	}
}
Пример #5
0
func TestPidstatMem(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	pstat := NewProcessStat(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 1000)
	root = "testdata/t1/"
	time.Sleep(time.Millisecond * 1000)
	var expected float64 = 1.794048e+06
	actual := pstat.ByMemUsage()[0].MemUsage()
	if math.Abs(actual-expected) > 0.01 {
		t.Errorf("Mem usage for top pid: %v expected: %v", actual, expected)
	}
}
Пример #6
0
func TestLoadstat(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	lstat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 1000)
	root = "testdata/t1/"
	time.Sleep(time.Millisecond * 200)
	var expected float64 = 0.13
	actual := lstat.OneMinute.Get()
	if actual != expected {
		t.Errorf("OneMinute loadavg: %v expected: %v", actual, expected)
	}
}
Пример #7
0
func TestDiskStat(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	dstat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 1000)
	root = "testdata/t1/"
	time.Sleep(time.Millisecond * 100)
	var expected uint64 = 99609658
	actual := dstat.Disks["sda"].IOSpentMsecs.Get()
	if actual != expected {
		t.Errorf("Diskstat: %v expected: %v", actual, expected)
	}
}
Пример #8
0
func TestInterfaceStat(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	istat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 1000)
	root = "testdata/t1/"
	time.Sleep(time.Millisecond * 100)
	var expected uint64 = 7070289382
	actual := istat.Interfaces["eth0"].Metrics.TXbytes.Get()
	if actual != expected {
		t.Errorf("interfacestat txbytes: %v expected: %v", actual, expected)
	}
}
Пример #9
0
func TestCPUUsage(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	cstat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 1000)
	root = "testdata/t1/"
	time.Sleep(time.Millisecond * 100)
	var expected uint64 = 161584849
	actual := cstat.All.User.Get()
	if actual != expected {
		t.Errorf("CPU user counter: %v expected: %v", actual, expected)
	}
}
Пример #10
0
func initMetricsContext() *metrics.MetricContext {
	m := metrics.NewMetricContext("test")
	g1 := metrics.NewGauge()
	m.Register(g1, "testGauge1")
	g2 := metrics.NewGauge()
	m.Register(g2, "testGauge2")
	g3 := metrics.NewGauge()
	m.Register(g3, "testGauge3")
	g4 := metrics.NewGauge()
	m.Register(g4, "testGauge4")
	g5 := metrics.NewGauge()
	m.Register(g5, "testGauge5")
	g2.Set(float64(200))
	g3.Set(float64(300))
	g4.Set(float64(400))
	g5.Set(float64(500))
	return m
}
Пример #11
0
func main() {
	var user, address, conf string
	var stepSec int
	var servermode, human, loop bool

	m := metrics.NewMetricContext("system")

	flag.StringVar(&user, "u", "postgres", "user using 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.BoolVar(&loop, "loop", false, "loop")
	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 := stat.New(m, user, conf)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer sqlstat.Close()

	if loop {
		ticker := time.NewTicker(step * 2)
		for _ = range ticker.C {
			sqlstat.Collect()
			printAll(*sqlstat)
			//Print stats here, more stats than printed are actually collected/ stats con be removed from here
		}
	} else {
		sqlstat.Collect()
		printAll(*sqlstat)
	}

}
Пример #12
0
func TestLoadstat(t *testing.T) {
	root = "testdata/t0/"
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	ustat := New(m, time.Millisecond*50)
	time.Sleep(time.Millisecond * 1000)
	root = "testdata/t1/"
	time.Sleep(time.Millisecond * 200)
	var expectedUp float64 = 1
	var expectedIdle float64 = 4
	actualUp := ustat.Uptime.Get()
	actualIdle := ustat.Idle.Get()
	if actualUp != expectedUp {
		t.Errorf("Uptime: %v expected: %v", actualUp, expectedUp)
	}
	if actualIdle != expectedIdle {
		t.Errorf("Uptime: %v expected: %v", actualIdle, expectedIdle)
	}
}
Пример #13
0
//Initializes test instance of PostgresStat
// Important to not connect to database
func initPostgresStat() *PostgresStat {
	syscall.Dup2(int(logFile.Fd()), 2)

	s := new(PostgresStat)
	s.db = &testPostgresDB{
		Logger: log.New(os.Stderr, "TESTING LOG: ", 0),
	}
	s.PGDATA = "/data/pgsql"
	s.m = metrics.NewMetricContext("system")
	s.Modes = make(map[string]*ModeMetrics)
	s.DBs = make(map[string]*DBMetrics)
	s.Metrics = PostgresStatMetricsNew(s.m)
	s.dbLock = &sync.Mutex{}
	s.modeLock = &sync.Mutex{}
	s.pidCol = "procpid"
	s.queryCol = "current_query"
	s.idleCol = s.queryCol
	s.idleStr = "<IDLE>"

	return s
}
Пример #14
0
func main() {
	var user, password, host, address, cnf, form, checkConfigFile string
	var stepSec int
	var servermode, human, loop bool
	var checkConfig *conf.ConfigFile

	m := metrics.NewMetricContext("system")

	flag.StringVar(&user, "u", "root", "user using database")
	flag.StringVar(&password, "p", "", "password for database")
	flag.StringVar(&host, "h", "",
		"address and protocol of the database to connect to. leave blank for tcp(127.0.0.1:3306)")
	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(&cnf, "cnf", "/root/.my.cnf", "configuration file")
	flag.StringVar(&form, "form", "graphite", "output format of metrics to stdout")
	flag.BoolVar(&human, "human", false,
		"Makes output in MB for human readable sizes")
	flag.BoolVar(&loop, "loop", false, "loop on collecting metrics")
	flag.StringVar(&checkConfigFile, "check", "", "config file to check metrics with")
	flag.Parse()

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

	var err error
	var c metricchecks.Checker
	checkConfig = conf.NewConfigFile()
	if checkConfigFile != "" {
		cnf, err := metricchecks.FileToConfig(checkConfigFile)
		if err != nil {
			checkConfigFile = ""
		} else {
			checkConfig = cnf
		}
	}

	c, err = metricchecks.New("", checkConfig)
	if err != nil {
		checkConfigFile = ""
	}

	//initialize metrics collectors to not loop and collect
	sqlstatDBs, err := dbstat.New(m, user, password, host, cnf)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	sqlstatTables, err := tablestat.New(m, user, password, host, cnf)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	sqlstatUsers, err := userstat.New(m, user, password, host, cnf)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	sqlstatDBs.Collect()
	sqlstatTables.Collect()
	sqlstatUsers.Collect()

	if checkConfigFile != "" {
		checkMetrics(c, m)
	}
	outputTableMetrics(sqlstatDBs, sqlstatTables, m, form)
	outputUserMetrics(sqlstatUsers, m, form)
	if loop {
		ticker := time.NewTicker(step)
		for _ = range ticker.C {
			sqlstatDBs.Collect()
			sqlstatTables.Collect()
			sqlstatUsers.Collect()
			outputTableMetrics(sqlstatDBs, sqlstatTables, m, form)
			outputUserMetrics(sqlstatUsers, m, form)
		}
	}
	sqlstatDBs.Close()
	sqlstatTables.Close()
	sqlstatUsers.Close()
}
Пример #15
0
func main() {
	// never use more than one process
	runtime.GOMAXPROCS(1)
	// wait group to let the main program run forever in batchmode
	var wg sync.WaitGroup
	// options
	var batchmode, servermode bool
	var address string
	var stepSec int
	var nIter int
	var evt <-chan termui.Event
	var widgets *osmain.DisplayWidgets
	var uiSummaryBody *termui.Grid
	var uiHelpBody *termui.Grid
	var uiDetailList *termui.List

	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.IntVar(&nIter, "n", 0, "Quit after these many iterations")
	flag.IntVar(&nIter, "iterations", 0, "Quit after these many iterations")
	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.Usage = func() {
		fmt.Fprintf(os.Stderr, "Options \n")
		fmt.Fprintf(os.Stderr, "------- \n")
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "Notes \n")
		fmt.Fprintf(os.Stderr, "------- \n")
		fmt.Fprintf(os.Stderr, "All CPU percentages are normalized to total number of logical cpus \n")
	}
	flag.Parse()

	if servermode {
		batchmode = true
	}

	if !batchmode {
		err := termui.Init()
		termui.UseTheme("helloworld")
		if err != nil {
			log.Fatalf("Unable to initialize termui", err)
		}
		widgets = uiWidgets()
		uiSummaryBody = uiSummary(widgets)
		uiHelpBody = uiHelp()
		uiDetailList = termui.NewList()
		evt = termui.EventCh()
		// display summary view
		termui.Body = uiSummaryBody
		uiRefresh()
	}
	// Initialize a metric context
	m := metrics.NewMetricContext("system")
	// Default step for collectors
	step := time.Millisecond * time.Duration(stepSec) * 1000
	// Register various stats we are interested in tracking
	stats := osmain.Register(m, step)
	// run http server
	if servermode {
		go func() {
			http.HandleFunc("/api/v1/metrics.json", m.HttpJsonHandler)
			log.Fatal(http.ListenAndServe(address, nil))
		}()
	}

	iterationsRun := 0
	// runs forever
	wg.Add(1)
	go func() {
		for {
			// Clear previous problems
			var problems []string
			stats.Problems = problems
			// Quit after n iterations if specified
			iterationsRun++
			if nIter > 0 && iterationsRun > nIter {
				break
			}
			stats.Print(batchmode, widgets)
			if !batchmode {
				termui.Render(termui.Body)
			}
			time.Sleep(step)
			// be aggressive about reclaiming memory
			// tradeoff with CPU usage
			runtime.GC()
			debug.FreeOSMemory()
		}
	}()

	if !batchmode {
		for {
			e := <-evt
			if e.Type == termui.EventKey {
				switch e.Ch {
				case 'q':
					termui.Close()
					return
				case 'c':
					uiDetailList = widgets.ProcessesByCPU
					termui.Body = uiDetail(uiDetailList)
				case 'd':
					uiDetailList = widgets.DiskIOUsage
					termui.Body = uiDetail(uiDetailList)
				case 'C':
					uiDetailList = widgets.CgroupsCPU
					termui.Body = uiDetail(uiDetailList)
				case 'f':
					uiDetailList = widgets.FileSystemUsage
					termui.Body = uiDetail(uiDetailList)
				case 'm':
					uiDetailList = widgets.ProcessesByMemory
					termui.Body = uiDetail(uiDetailList)
				case 'p':
					uiDetailList = widgets.Problems
					termui.Body = uiDetail(uiDetailList)
				case 'M':
					uiDetailList = widgets.CgroupsMem
					termui.Body = uiDetail(uiDetailList)
				case 'n':
					uiDetailList = widgets.InterfaceUsage
					termui.Body = uiDetail(uiDetailList)
				case 'i':
					uiDetailList = widgets.ProcessesByIO
					termui.Body = uiDetail(uiDetailList)
				case 's':
					uiResetAttributes(widgets)
					termui.Body = uiSummaryBody
				case 'h':
					termui.Body = uiHelpBody
				}
				uiRefresh()
			}
			if e.Type == termui.EventResize {
				uiRefresh()
			}
		}
	}
	wg.Wait()
}