Пример #1
0
func (s *ProcVmstatTestSuite) TestProcVmstat001(t *C) {
	m := system.NewMonitor("", &system.Config{}, s.logger)
	content, err := ioutil.ReadFile(sample + "/proc/vmstat001.txt")
	if err != nil {
		t.Fatal(err)
	}
	got, err := m.ProcVmstat(content)
	if err != nil {
		t.Fatal(err)
	}
	// Remember: the order of this array must match order in which each
	// stat appears in the input file:
	expect := []mm.Metric{
		{Name: "vmstat/numa_hit", Type: "counter", Number: 42594095},    // ok
		{Name: "vmstat/numa_miss", Type: "counter", Number: 0},          // ok
		{Name: "vmstat/numa_foreign", Type: "counter", Number: 0},       // ok
		{Name: "vmstat/numa_interleave", Type: "counter", Number: 7297}, // ok
		{Name: "vmstat/numa_local", Type: "counter", Number: 42594095},  // ok
		{Name: "vmstat/numa_other", Type: "counter", Number: 0},         // ok
		{Name: "vmstat/pgpgin", Type: "counter", Number: 646645},        // ok
		{Name: "vmstat/pgpgout", Type: "counter", Number: 5401659},      // ok
		{Name: "vmstat/pswpin", Type: "counter", Number: 0},             // ok
		{Name: "vmstat/pswpout", Type: "counter", Number: 0},            // ok
	}
	if same, diff := test.IsDeeply(got, expect); !same {
		test.Dump(got)
		t.Error(diff)
	}
}
Пример #2
0
func (s *ProcMeminfoTestSuite) TestProcMeminfo001(t *C) {
	m := system.NewMonitor("", &system.Config{}, s.logger)
	content, err := ioutil.ReadFile(sample + "/proc/meminfo001.txt")
	if err != nil {
		t.Fatal(err)
	}
	got, err := m.ProcMeminfo(content)
	if err != nil {
		t.Fatal(err)
	}
	// Remember: the order of this array must match order in which each
	// stat appears in the input file:
	expect := []mm.Metric{
		{Name: "memory/MemTotal", Type: "gauge", Number: 8046892},  // ok
		{Name: "memory/MemFree", Type: "gauge", Number: 5273644},   // ok
		{Name: "memory/Buffers", Type: "gauge", Number: 300684},    // ok
		{Name: "memory/Cached", Type: "gauge", Number: 946852},     // ok
		{Name: "memory/SwapCached", Type: "gauge", Number: 0},      // ok
		{Name: "memory/Active", Type: "gauge", Number: 1936436},    // ok
		{Name: "memory/Inactive", Type: "gauge", Number: 598916},   // ok
		{Name: "memory/SwapTotal", Type: "gauge", Number: 8253436}, // ok
		{Name: "memory/SwapFree", Type: "gauge", Number: 8253436},  // ok
		{Name: "memory/Dirty", Type: "gauge", Number: 0},           // ok
	}
	if same, diff := test.IsDeeply(got, expect); !same {
		test.Dump(got)
		t.Error(diff)
	}
}
Пример #3
0
func (f *Factory) Make(service string, instanceId uint, data []byte) (mm.Monitor, error) {
	var monitor mm.Monitor
	switch service {
	case "mysql":
		// Load the MySQL instance info (DSN, name, etc.).
		mysqlIt := &proto.MySQLInstance{}
		if err := f.ir.Get(service, instanceId, mysqlIt); err != nil {
			return nil, err
		}

		// Parse the MySQL sysconfig config.
		config := &mysql.Config{}
		if err := json.Unmarshal(data, config); err != nil {
			return nil, err
		}

		// The user-friendly name of the service, e.g. sysconfig-mysql-db101:
		alias := "mm-mysql-" + mysqlIt.Hostname

		// Make a MySQL metrics monitor.
		monitor = mysql.NewMonitor(
			alias,
			config,
			pct.NewLogger(f.logChan, alias),
			mysqlConn.NewConnection(mysqlIt.DSN),
			f.mrm,
		)
	case "server":
		// Parse the system mm config.
		config := &system.Config{}
		if err := json.Unmarshal(data, config); err != nil {
			return nil, err
		}

		// Only one system for now, so no SystemInstance and no  "-instanceName" suffix.
		alias := "mm-system"

		// Make a MySQL metrics monitor.
		monitor = system.NewMonitor(
			alias,
			config,
			pct.NewLogger(f.logChan, alias),
		)
	default:
		return nil, errors.New("Unknown metrics monitor type: " + service)
	}
	return monitor, nil
}
Пример #4
0
func (s *ProcLoadavgTestSuite) TestProcLoadavg001(t *C) {
	m := system.NewMonitor("", &system.Config{}, s.logger)
	content, err := ioutil.ReadFile(sample + "/proc/loadavg001.txt")
	if err != nil {
		t.Fatal(err)
	}
	got, err := m.ProcLoadavg(content)
	if err != nil {
		t.Fatal(err)
	}
	// Remember: the order of this array must match order in which each
	// stat appears in the input file:
	expect := []mm.Metric{
		{Name: "loadavg/1min", Type: "gauge", Number: 0.45},     // ok
		{Name: "loadavg/5min", Type: "gauge", Number: 0.56},     // ok
		{Name: "loadavg/15min", Type: "gauge", Number: 0.58},    // ok
		{Name: "loadavg/running", Type: "gauge", Number: 1},     // ok
		{Name: "loadavg/processes", Type: "gauge", Number: 598}, // ok
	}
	if same, diff := test.IsDeeply(got, expect); !same {
		test.Dump(got)
		t.Error(diff)
	}
}
Пример #5
0
func (s *ProcStatTestSuite) TestProcStat001(t *C) {
	files, err := filepath.Glob(sample + "/proc/stat001-*.txt")
	if err != nil {
		t.Fatal(err)
	}

	m := system.NewMonitor("", &system.Config{}, s.logger)

	metrics := []mm.Metric{}

	for _, file := range files {
		content, err := ioutil.ReadFile(file)
		if err != nil {
			t.Fatal(err)
		}
		got, err := m.ProcStat(content)
		if err != nil {
			t.Fatal(err)
		}
		metrics = append(metrics, got...)
	}

	/*
					Totals		Diff
		stat001-1
			cpu		390817611
			cpu0	97641434
			cpu1	97717127
		stat001-2
			cpu		391386603	568992
			cpu0	97783608	142174	These don't add up because the real input has 4 CPU.
			cpu1	97859411	142284  This does not affect the tests.
		stat001-3
			cpu		391759882	373279
			cpu0	97876875	93267
			cpu1	97952757	93346

			1    2    3      4    5      6   7       8     9     10
			user nice system idle iowait irq softirq steal guest guestlow
	*/
	expect := []mm.Metric{
		// First input, no CPU because that requires previous values, so only cpu-ext:
		{Name: "cpu-ext/intr", Type: "counter", Number: 39222211},    // ok
		{Name: "cpu-ext/ctxt", Type: "counter", Number: 122462971},   // ok
		{Name: "cpu-ext/processes", Type: "counter", Number: 227223}, // ok
		{Name: "cpu-ext/procs_running", Type: "gauge", Number: 1},    // ok
		{Name: "cpu-ext/procs_blocked", Type: "gauge", Number: 0},    // ok
		// Second input, now we have CPU values, plus more cpu-ext values.
		{Name: "cpu/user", Type: "gauge", Number: 0.041477},    // ok 5
		{Name: "cpu/nice", Type: "gauge", Number: 0},           // ok
		{Name: "cpu/system", Type: "gauge", Number: 0.017751},  // ok 7
		{Name: "cpu/idle", Type: "gauge", Number: 99.938488},   // ok
		{Name: "cpu/iowait", Type: "gauge", Number: 0.002285},  // ok 9
		{Name: "cpu/irq", Type: "gauge", Number: 0},            // ok
		{Name: "cpu/softirq", Type: "gauge", Number: 0},        // ok 11
		{Name: "cpu/steal", Type: "gauge", Number: 0},          // ok
		{Name: "cpu/guest", Type: "gauge", Number: 0},          // ok 13
		{Name: "cpu0/user", Type: "gauge", Number: 0.131529},   // ok
		{Name: "cpu0/nice", Type: "gauge", Number: 0},          // ok 15
		{Name: "cpu0/system", Type: "gauge", Number: 0.039388}, // ok
		{Name: "cpu0/idle", Type: "gauge", Number: 99.819939},  // ok 17
		{Name: "cpu0/iowait", Type: "gauge", Number: 0.009144},
		{Name: "cpu0/irq", Type: "gauge", Number: 0}, // 19
		{Name: "cpu0/softirq", Type: "gauge", Number: 0},
		{Name: "cpu0/steal", Type: "gauge", Number: 0}, // 21
		{Name: "cpu0/guest", Type: "gauge", Number: 0},
		{Name: "cpu1/user", Type: "gauge", Number: 0.026707}, // 23
		{Name: "cpu1/nice", Type: "gauge", Number: 0},
		{Name: "cpu1/system", Type: "gauge", Number: 0.023193}, // 25
		{Name: "cpu1/idle", Type: "gauge", Number: 99.950100},
		{Name: "cpu1/iowait", Type: "gauge", Number: 0}, // 27
		{Name: "cpu1/irq", Type: "gauge", Number: 0},
		{Name: "cpu1/softirq", Type: "gauge", Number: 0}, // 29
		{Name: "cpu1/steal", Type: "gauge", Number: 0},
		{Name: "cpu1/guest", Type: "gauge", Number: 0},               // ok 31
		{Name: "cpu-ext/intr", Type: "counter", Number: 39276666},    // ok
		{Name: "cpu-ext/ctxt", Type: "counter", Number: 122631533},   // ok 33
		{Name: "cpu-ext/processes", Type: "counter", Number: 227521}, // ok
		{Name: "cpu-ext/procs_running", Type: "gauge", Number: 2},    // ok 35
		{Name: "cpu-ext/procs_blocked", Type: "gauge", Number: 0},    // ok
		// Third input.
		{Name: "cpu/user", Type: "gauge", Number: 0.038309},   // ok 37
		{Name: "cpu/nice", Type: "gauge", Number: 0},          // ok
		{Name: "cpu/system", Type: "gauge", Number: 0.017681}, // ok 39
		{Name: "cpu/idle", Type: "gauge", Number: 99.941063},
		{Name: "cpu/iowait", Type: "gauge", Number: 0.002947}, // 41
		{Name: "cpu/irq", Type: "gauge", Number: 0},
		{Name: "cpu/softirq", Type: "gauge", Number: 0}, // 43
		{Name: "cpu/steal", Type: "gauge", Number: 0},
		{Name: "cpu/guest", Type: "gauge", Number: 0}, // 45
		{Name: "cpu0/user", Type: "gauge", Number: 0.122230},
		{Name: "cpu0/nice", Type: "gauge", Number: 0}, // 47
		{Name: "cpu0/system", Type: "gauge", Number: 0.041815},
		{Name: "cpu0/idle", Type: "gauge", Number: 99.824161}, // 49
		{Name: "cpu0/iowait", Type: "gauge", Number: 0.011794},
		{Name: "cpu0/irq", Type: "gauge", Number: 0}, // 51
		{Name: "cpu0/softirq", Type: "gauge", Number: 0},
		{Name: "cpu0/steal", Type: "gauge", Number: 0}, // 53
		{Name: "cpu0/guest", Type: "gauge", Number: 0},
		{Name: "cpu1/user", Type: "gauge", Number: 0.021426},   // ok 55
		{Name: "cpu1/nice", Type: "gauge", Number: 0},          // ok
		{Name: "cpu1/system", Type: "gauge", Number: 0.024640}, // -- 57
		{Name: "cpu1/idle", Type: "gauge", Number: 99.953935},
		{Name: "cpu1/iowait", Type: "gauge", Number: 0}, // 59
		{Name: "cpu1/irq", Type: "gauge", Number: 0},
		{Name: "cpu1/softirq", Type: "gauge", Number: 0}, // 61
		{Name: "cpu1/steal", Type: "gauge", Number: 0},
		{Name: "cpu1/guest", Type: "gauge", Number: 0},               // 63
		{Name: "cpu-ext/intr", Type: "counter", Number: 39312673},    // ok
		{Name: "cpu-ext/ctxt", Type: "counter", Number: 122742465},   // 65 ok
		{Name: "cpu-ext/processes", Type: "counter", Number: 227717}, // ok
		{Name: "cpu-ext/procs_running", Type: "gauge", Number: 3},    // 67 ok
		{Name: "cpu-ext/procs_blocked", Type: "gauge", Number: 0},    // ok
	}

	if same, diff := test.IsDeeply(metrics, expect); !same {
		test.Dump(metrics)
		t.Error(diff)
	}
}
Пример #6
0
func (s *ManagerTestSuite) TestStartCollectStop(t *C) {
	files := []string{"stat", "meminfo", "vmstat", "loadavg", "diskstats"}
	for _, file := range files {
		if !pct.FileExists("/proc/" + file) {
			t.Fatal("/proc/" + file + " does not exist")
		}
	}

	// Create the monitor.
	m := system.NewMonitor(s.name, &system.Config{}, s.logger)
	if m == nil {
		t.Fatal("Make new system.Monitor")
	}

	// Start the monitor.
	err := m.Start(s.tickChan, s.collectionChan)
	if err != nil {
		t.Fatalf("Start monitor without error, got %s", err)
	}

	// system-monitor=Ready once it has started its internals,
	// should be very fast.
	if ok := test.WaitStatusPrefix(3, m, s.name, "Idle"); !ok {
		t.Fatal("Monitor is ready")
	}

	// The monitor should only collect and send metrics on ticks; we haven't ticked yet.
	got := test.WaitCollection(s.collectionChan, 0)
	if len(got) > 0 {
		t.Fatal("No tick, no collection; got %+v", got)
	}

	// Now tick.  This should make monitor collect.
	now := time.Now()
	s.tickChan <- now

	got = test.WaitCollection(s.collectionChan, 1)
	t.Assert(got, Not(HasLen), 0)
	t.Check(got, HasLen, 1)

	c := got[0]
	t.Check(c.Ts, Equals, now.Unix())

	t.Assert(c.Metrics, Not(HasLen), 0)

	// /proc/stat values are relative (current - prev) so there shouldn't be any
	// after one tick.
	haveCPU, _ := haveMetric("cpu/user", c.Metrics)
	t.Check(haveCPU, Equals, false)

	// But other metrics are not relative, so we should have them.
	metrics := []string{"memory/MemTotal", "vmstat/numa_local", "loadavg/running", "disk/sda/reads"}
	for _, metric := range metrics {
		ok, val := haveMetric(metric, c.Metrics)
		t.Check(ok, Equals, true)
		t.Check(val, Not(Equals), 0)
	}

	// Tick a 2nd time and now we should get CPU metrics.
	time.Sleep(200 * time.Millisecond)
	now = time.Now()
	s.tickChan <- now

	got = test.WaitCollection(s.collectionChan, 1)
	t.Assert(got, Not(HasLen), 0)
	t.Check(got, HasLen, 1)
	c = got[0]
	t.Check(c.Ts, Equals, now.Unix())
	t.Assert(c.Metrics, Not(HasLen), 0)

	metrics = []string{"cpu/user", "cpu/nice", "cpu/system", "cpu/idle"}
	for _, metric := range metrics {
		ok, val := haveMetric(metric, c.Metrics)
		t.Check(ok, Equals, true)

		// Running this test requires some CPU so user and idle shouldn't be zero.
		if metric == "cpu/user" || metric == "cpu/idle" {
			t.Check(val, Not(Equals), 0)
		}
	}

	/**
	 * Stop the monitor.
	 */

	m.Stop()

	if ok := test.WaitStatus(5, m, s.name, "Stopped"); !ok {
		t.Fatal("Monitor has stopped")
	}
}
Пример #7
0
func (s *ProcDiskstatsTestSuite) TestProcDiskstats001(t *C) {
	m := system.NewMonitor("", &system.Config{}, s.logger)
	content, err := ioutil.ReadFile(sample + "/proc/diskstats001.txt")
	if err != nil {
		t.Fatal(err)
	}
	got, err := m.ProcDiskstats(content)
	if err != nil {
		t.Fatal(err)
	}
	// Remember: the order of this array must match order in which each
	// stat appears in the input file:
	expect := []mm.Metric{
		{Name: "disk/sda/reads", Type: "counter", Number: 56058},
		{Name: "disk/sda/reads_merged", Type: "counter", Number: 2313},
		{Name: "disk/sda/sectors_read", Type: "counter", Number: 1270506},
		{Name: "disk/sda/read_time", Type: "counter", Number: 280760},
		{Name: "disk/sda/writes", Type: "counter", Number: 232825},
		{Name: "disk/sda/writes_merged", Type: "counter", Number: 256917},
		{Name: "disk/sda/sectors_written", Type: "counter", Number: 10804063},
		{Name: "disk/sda/write_time", Type: "counter", Number: 2097320},
		{Name: "disk/sda/io_time", Type: "counter", Number: 1163068},
		{Name: "disk/sda/io_time_weighted", Type: "counter", Number: 2378728},
		{Name: "disk/sda/iops", Type: "counter", Number: 56058 + 232825},
		// --
		{Name: "disk/sda1/reads", Type: "counter", Number: 385},
		{Name: "disk/sda1/reads_merged", Type: "counter", Number: 1138},
		{Name: "disk/sda1/sectors_read", Type: "counter", Number: 4518},
		{Name: "disk/sda1/read_time", Type: "counter", Number: 4480},
		{Name: "disk/sda1/writes", Type: "counter", Number: 1},
		{Name: "disk/sda1/writes_merged", Type: "counter", Number: 0},
		{Name: "disk/sda1/sectors_written", Type: "counter", Number: 1},
		{Name: "disk/sda1/write_time", Type: "counter", Number: 0},
		{Name: "disk/sda1/io_time", Type: "counter", Number: 2808},
		{Name: "disk/sda1/io_time_weighted", Type: "counter", Number: 4480},
		{Name: "disk/sda1/iops", Type: "counter", Number: 385 + 1},
		// --
		{Name: "disk/sda2/reads", Type: "counter", Number: 276},
		{Name: "disk/sda2/reads_merged", Type: "counter", Number: 240},
		{Name: "disk/sda2/sectors_read", Type: "counter", Number: 2104},
		{Name: "disk/sda2/read_time", Type: "counter", Number: 1692},
		{Name: "disk/sda2/writes", Type: "counter", Number: 15},
		{Name: "disk/sda2/writes_merged", Type: "counter", Number: 0},
		{Name: "disk/sda2/sectors_written", Type: "counter", Number: 30},
		{Name: "disk/sda2/write_time", Type: "counter", Number: 0},
		{Name: "disk/sda2/io_time", Type: "counter", Number: 1592},
		{Name: "disk/sda2/io_time_weighted", Type: "counter", Number: 1692},
		{Name: "disk/sda2/iops", Type: "counter", Number: 276 + 15},
		// --
		{Name: "disk/sda3/reads", Type: "counter", Number: 55223},
		{Name: "disk/sda3/reads_merged", Type: "counter", Number: 932},
		{Name: "disk/sda3/sectors_read", Type: "counter", Number: 1262468},
		{Name: "disk/sda3/read_time", Type: "counter", Number: 270204},
		{Name: "disk/sda3/writes", Type: "counter", Number: 184397},
		{Name: "disk/sda3/writes_merged", Type: "counter", Number: 256917},
		{Name: "disk/sda3/sectors_written", Type: "counter", Number: 10804032},
		{Name: "disk/sda3/write_time", Type: "counter", Number: 1436428},
		{Name: "disk/sda3/io_time", Type: "counter", Number: 512824},
		{Name: "disk/sda3/io_time_weighted", Type: "counter", Number: 1707280},
		{Name: "disk/sda3/iops", Type: "counter", Number: 55223 + 184397},
		// --
		{Name: "disk/sr0/reads", Type: "counter", Number: 0},
		{Name: "disk/sr0/reads_merged", Type: "counter", Number: 0},
		{Name: "disk/sr0/sectors_read", Type: "counter", Number: 0},
		{Name: "disk/sr0/read_time", Type: "counter", Number: 0},
		{Name: "disk/sr0/writes", Type: "counter", Number: 0},
		{Name: "disk/sr0/writes_merged", Type: "counter", Number: 0},
		{Name: "disk/sr0/sectors_written", Type: "counter", Number: 0},
		{Name: "disk/sr0/write_time", Type: "counter", Number: 0},
		{Name: "disk/sr0/io_time", Type: "counter", Number: 0},
		{Name: "disk/sr0/io_time_weighted", Type: "counter", Number: 0},
		{Name: "disk/sr0/iops", Type: "counter", Number: 0},
		// --
		{Name: "disk/dm-0/reads", Type: "counter", Number: 43661},
		{Name: "disk/dm-0/reads_merged", Type: "counter", Number: 0},
		{Name: "disk/dm-0/sectors_read", Type: "counter", Number: 1094074},
		{Name: "disk/dm-0/read_time", Type: "counter", Number: 262092},
		{Name: "disk/dm-0/writes", Type: "counter", Number: 132099},
		{Name: "disk/dm-0/writes_merged", Type: "counter", Number: 0},
		{Name: "disk/dm-0/sectors_written", Type: "counter", Number: 5731328},
		{Name: "disk/dm-0/write_time", Type: "counter", Number: 4209168},
		{Name: "disk/dm-0/io_time", Type: "counter", Number: 231792},
		{Name: "disk/dm-0/io_time_weighted", Type: "counter", Number: 4471268},
		{Name: "disk/dm-0/iops", Type: "counter", Number: 43661 + 132099},
		// --
		{Name: "disk/dm-1/reads", Type: "counter", Number: 287},
		{Name: "disk/dm-1/reads_merged", Type: "counter", Number: 0},
		{Name: "disk/dm-1/sectors_read", Type: "counter", Number: 2296},
		{Name: "disk/dm-1/read_time", Type: "counter", Number: 1692},
		{Name: "disk/dm-1/writes", Type: "counter", Number: 0},
		{Name: "disk/dm-1/writes_merged", Type: "counter", Number: 0},
		{Name: "disk/dm-1/sectors_written", Type: "counter", Number: 0},
		{Name: "disk/dm-1/write_time", Type: "counter", Number: 0},
		{Name: "disk/dm-1/io_time", Type: "counter", Number: 700},
		{Name: "disk/dm-1/io_time_weighted", Type: "counter", Number: 1692},
		{Name: "disk/dm-1/iops", Type: "counter", Number: 287 + 0},
		// --
		{Name: "disk/dm-2/reads", Type: "counter", Number: 12213},
		{Name: "disk/dm-2/reads_merged", Type: "counter", Number: 0},
		{Name: "disk/dm-2/sectors_read", Type: "counter", Number: 165618},
		{Name: "disk/dm-2/read_time", Type: "counter", Number: 42444},
		{Name: "disk/dm-2/writes", Type: "counter", Number: 310480},
		{Name: "disk/dm-2/writes_merged", Type: "counter", Number: 0},
		{Name: "disk/dm-2/sectors_written", Type: "counter", Number: 5072704},
		{Name: "disk/dm-2/write_time", Type: "counter", Number: 1084328},
		{Name: "disk/dm-2/io_time", Type: "counter", Number: 946036},
		{Name: "disk/dm-2/io_time_weighted", Type: "counter", Number: 1126764},
		{Name: "disk/dm-2/iops", Type: "counter", Number: 12213 + 310480},
	}
	if same, diff := test.IsDeeply(got, expect); !same {
		t.Logf("%+v\n", got)
		t.Error(diff)
	}
}