func (s *ManagerTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "sysconfig-manager-test")

	s.mockMonitor = mock.NewSysconfigMonitor()
	s.factory = mock.NewSysconfigMonitorFactory([]sysconfig.Monitor{s.mockMonitor})

	s.tickChan = make(chan time.Time)

	s.dataChan = make(chan interface{}, 1)
	s.spool = mock.NewSpooler(s.dataChan)

	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "agent-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.tmpDir); err != nil {
		t.Fatal(err)
	}
	s.configDir = pct.Basedir.Dir("config")

	links := map[string]string{
		"agent":     "http://localhost/agent",
		"instances": "http://localhost/instances",
	}
	s.api = mock.NewAPI("http://localhost", "http://localhost", "123", "abc-123-def", links)

	s.im = instance.NewRepo(pct.NewLogger(s.logChan, "im-test"), s.configDir, s.api)
}
Example #2
0
func (s *ManagerTestSuite) SetUpSuite(t *C) {
	s.dsn = os.Getenv("PCT_TEST_MYSQL_DSN")
	if s.dsn == "" {
		t.Fatal("PCT_TEST_MYSQL_DSN is not set")
	}

	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, query.SERVICE_NAME+"-manager-test")

	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "agent-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.tmpDir); err != nil {
		t.Fatal(err)
	}
	s.configDir = pct.Basedir.Dir("config")

	// Real instance repo
	s.repo = instance.NewRepo(pct.NewLogger(s.logChan, "im-test"), s.configDir, s.api)
	data, err := json.Marshal(&proto.MySQLInstance{
		Hostname: "db1",
		DSN:      s.dsn,
	})
	t.Assert(err, IsNil)
	s.repo.Add("mysql", 1, data, false)
	s.mysqlInstance = proto.ServiceInstance{Service: "mysql", InstanceId: 1}

	links := map[string]string{
		"agent":     "http://localhost/agent",
		"instances": "http://localhost/instances",
	}
	s.api = mock.NewAPI("http://localhost", "http://localhost", "123", "abc-123-def", links)
}
Example #3
0
func (s *ManagerTestSuite) SetUpSuite(t *C) {
	s.dsn = os.Getenv("PCT_TEST_MYSQL_DSN")
	if s.dsn == "" {
		t.Fatal("PCT_TEST_MYSQL_DSN is not set")
	}
	s.realmysql = mysql.NewConnection(s.dsn)
	if err := s.realmysql.Connect(1); err != nil {
		t.Fatal(err)
	}
	s.reset = []mysql.Query{
		mysql.Query{Set: "SET GLOBAL slow_query_log=OFF"},
		mysql.Query{Set: "SET GLOBAL long_query_time=10"},
	}

	s.nullmysql = mock.NewNullMySQL()

	s.logChan = make(chan *proto.LogEntry, 1000)
	s.logger = pct.NewLogger(s.logChan, "qan-test")

	s.intervalChan = make(chan *qan.Interval, 1)
	s.iter = mock.NewMockIntervalIter(s.intervalChan)
	s.iterFactory = &mock.IntervalIterFactory{
		Iters:     []qan.IntervalIter{s.iter},
		TickChans: make(map[qan.IntervalIter]chan time.Time),
	}

	s.dataChan = make(chan interface{}, 2)
	s.spool = mock.NewSpooler(s.dataChan)
	s.workerFactory = &qan.SlowLogWorkerFactory{}

	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "agent-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.tmpDir); err != nil {
		t.Fatal(err)
	}
	s.configDir = pct.Basedir.Dir("config")

	s.im = instance.NewRepo(pct.NewLogger(s.logChan, "im-test"), s.configDir, s.api)
	data, err := json.Marshal(&proto.MySQLInstance{
		Hostname: "db1",
		DSN:      s.dsn,
	})
	t.Assert(err, IsNil)
	s.im.Add("mysql", 1, data, false)
	s.mysqlInstance = proto.ServiceInstance{Service: "mysql", InstanceId: 1}

	links := map[string]string{
		"agent":     "http://localhost/agent",
		"instances": "http://localhost/instances",
	}
	s.api = mock.NewAPI("http://localhost", "http://localhost", "123", "abc-123-def", links)
}
Example #4
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
}
Example #5
0
func (s *WorkerTestSuite) SetUpSuite(t *C) {
	s.dsn = os.Getenv("PCT_TEST_MYSQL_DSN")
	s.logChan = make(chan *proto.LogEntry, 100)
	s.logger = pct.NewLogger(s.logChan, "qan-worker")
	s.now = time.Now()
	s.mysqlInstance = proto.ServiceInstance{Service: "mysql", InstanceId: 1}
	s.config = qan.Config{
		ServiceInstance: s.mysqlInstance,
		Start: []mysql.Query{
			mysql.Query{Set: "SET GLOBAL slow_query_log=OFF"},
			mysql.Query{Set: "SET GLOBAL long_query_time=0.123"},
			mysql.Query{Set: "SET GLOBAL slow_query_log=ON"},
		},
		Stop: []mysql.Query{
			mysql.Query{Set: "SET GLOBAL slow_query_log=OFF"},
			mysql.Query{Set: "SET GLOBAL long_query_time=10"},
		},
		Interval:          60,         // 1 min
		MaxSlowLogSize:    1073741824, // 1 GiB
		RemoveOldSlowLogs: true,
		ExampleQueries:    true,
		WorkerRunTime:     60, // 1 min
		CollectFrom:       "slowlog",
	}
	s.nullmysql = mock.NewNullMySQL()
}
func (s *UpdateTestSuite) SetUpSuite(t *C) {
	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "percona-agent-test-pct-update")
	t.Assert(err, IsNil)

	s.logChan = make(chan *proto.LogEntry, 1000)
	s.logger = pct.NewLogger(s.logChan, "qan-test")

	links := map[string]string{
		"agent":     "http://localhost/agent",
		"instances": "http://localhost/instances",
		"update":    "http://localhost/update",
	}
	s.api = mock.NewAPI("http://localhost", "http://localhost", "123", "abc-123-def", links)

	test.CopyFile(test.RootDir+"/pct/fake-percona-agent-1.0.1.go", s.tmpDir)

	cwd, err := os.Getwd()
	t.Assert(err, IsNil)
	defer os.Chdir(cwd)

	err = os.Chdir(s.tmpDir)
	t.Assert(err, IsNil)

	out, err := exec.Command("go", "build", "fake-percona-agent-1.0.1.go").Output()
	if err != nil {
		t.Logf("%s", out)
		t.Fatal(err)
	}
	s.bin, s.sig, err = test.Sign(filepath.Join(s.tmpDir, "fake-percona-agent-1.0.1"))
	t.Assert(err, IsNil)

	s.pubKey, err = ioutil.ReadFile(filepath.Join(test.RootDir, "pct", "key.pub"))
	t.Assert(err, IsNil)
}
Example #7
0
func (i *Installer) writeInstances(si *proto.ServerInstance, mi *proto.MySQLInstance) error {
	// We could write the instance structs directly, but this is the job of an
	// instance repo and it's easy enough to create one, so do the right thing.
	logChan := make(chan *proto.LogEntry, 100)
	logger := pct.NewLogger(logChan, "instance-repo")
	repo := instance.NewRepo(logger, pct.Basedir.Dir("config"), i.api)
	if si != nil {
		bytes, err := json.Marshal(si)
		if err != nil {
			return err
		}
		if err := repo.Add("server", si.Id, bytes, true); err != nil {
			return err
		}
	}
	if mi != nil {
		bytes, err := json.Marshal(mi)
		if err != nil {
			return err
		}
		if err := repo.Add("mysql", mi.Id, bytes, true); err != nil {
			return err
		}
	}
	return nil
}
Example #8
0
// Test that a disabled slow log rotation in Percona Server (or MySQL) does not change analizer config
func (s *AnalyzerTestSuite) TestNoSlowLogTakeOver(t *C) {

	/*
		PS can be configured to rotate slow log, making qan break.
		Since qan cannot handle the situation where a slow log is rotated by a third party we take over Percona Server
		rotation and disable it on DB.
	*/
	a := qan.NewRealAnalyzer(
		pct.NewLogger(s.logChan, "qan-analyzer"),
		s.config,
		s.iter,
		s.nullmysql,
		s.restartChan,
		s.worker,
		s.clock,
		s.spool,
	)

	err := a.Start()
	t.Assert(err, IsNil)
	test.WaitStatus(1, a, "qan-analyzer", "Idle")

	// Disable DB rotation by setting max_slowlog_size to a value < 4096
	s.nullmysql.SetGlobalVarNumber("max_slowlog_size", 1000)
	// Trigger our PS slow log rotation take-over, everything should stay the same since max_slowlog_size is < 4096
	a.TakeOverPerconaServerRotation()
	t.Check(a.Config().MaxSlowLogSize, Equals, MAX_SLOW_LOG_SIZE)
	err = a.Stop()
	t.Assert(err, IsNil)
	test.WaitStatus(1, a, "qan-analyzer", "Stopped")
	t.Check(a.String(), Equals, "qan-analyzer")
}
Example #9
0
func (s *DiskvSpoolerTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "data_test")

	dir, _ := ioutil.TempDir("/tmp", "pct-data-spooler-test")
	s.dataDir = dir
}
Example #10
0
func (f *RealAnalyzerFactory) Make(
	config qan.Config,
	name string,
	mysqlConn mysql.Connector,
	restartChan <-chan bool,
	tickChan chan time.Time,
) qan.Analyzer {
	var worker qan.Worker
	analyzerType := config.CollectFrom
	switch analyzerType {
	case "slowlog":
		worker = f.slowlogWorkerFactory.Make(name+"-worker", config, mysqlConn)
	case "perfschema":
		worker = f.perfschemaWorkerFactory.Make(name+"-worker", mysqlConn)
	default:
		panic("Invalid analyzerType: " + analyzerType)
	}
	return qan.NewRealAnalyzer(
		pct.NewLogger(f.logChan, name),
		config,
		f.iterFactory.Make(analyzerType, mysqlConn, tickChan),
		mysqlConn,
		restartChan,
		worker,
		f.clock,
		f.spool,
	)
}
Example #11
0
func (s *AgentTestSuite) SetUpSuite(t *C) {
	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "agent-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.tmpDir); err != nil {
		t.Fatal(err)
	}
	s.configFile = filepath.Join(s.tmpDir, pct.CONFIG_DIR, "agent"+pct.CONFIG_FILE_SUFFIX)

	// Log
	// todo: use log.Manager instead
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "agent-test")

	// Agent
	s.config = &agent.Config{
		AgentUuid:   "abc-123-def",
		ApiKey:      "789",
		ApiHostname: agent.DEFAULT_API_HOSTNAME,
	}

	s.sendChan = make(chan *proto.Cmd, 5)
	s.recvChan = make(chan *proto.Reply, 5)
	s.sendDataChan = make(chan interface{}, 5)
	s.recvDataChan = make(chan interface{}, 5)
	s.client = mock.NewWebsocketClient(s.sendChan, s.recvChan, s.sendDataChan, s.recvDataChan)
	s.client.ErrChan = make(chan error)

	s.readyChan = make(chan bool, 2)
	s.traceChan = make(chan string, 10)
	s.doneChan = make(chan bool, 1)
}
func (s *WorkerTestSuite) TestIter(t *C) {
	tickChan := make(chan time.Time, 1)
	i := perfschema.NewIter(pct.NewLogger(s.logChan, "iter"), tickChan)
	t.Assert(i, NotNil)

	iterChan := i.IntervalChan()
	t.Assert(iterChan, NotNil)

	i.Start()
	defer i.Stop()

	t1, _ := time.Parse("2006-01-02 15:04:05", "2015-01-01 00:01:00")
	t2, _ := time.Parse("2006-01-02 15:04:05", "2015-01-01 00:02:00")
	t3, _ := time.Parse("2006-01-02 15:04:05", "2015-01-01 00:03:00")

	tickChan <- t1
	got := <-iterChan
	t.Check(got, DeepEquals, &qan.Interval{Number: 1, StartTime: time.Time{}, StopTime: t1})

	tickChan <- t2
	got = <-iterChan
	t.Check(got, DeepEquals, &qan.Interval{Number: 2, StartTime: t1, StopTime: t2})

	tickChan <- t3
	got = <-iterChan
	t.Check(got, DeepEquals, &qan.Interval{Number: 3, StartTime: t2, StopTime: t3})
}
Example #13
0
func (i *InstallerTestSuite) TestIsSupportedMySQLVersion(t *C) {
	var got bool
	var err error

	agentConfig := &agent.Config{}
	flags := installer.Flags{}

	apiConnector := pct.NewAPI()
	api := api.New(apiConnector, false)
	logChan := make(chan *proto.LogEntry, 100)
	logger := pct.NewLogger(logChan, "instance-repo")
	instanceRepo := instance.NewRepo(logger, pct.Basedir.Dir("config"), apiConnector)
	terminal := term.NewTerminal(os.Stdin, false, true)
	inst := installer.NewInstaller(terminal, "", api, instanceRepo, agentConfig, flags)
	conn := mock.NewNullMySQL()
	errSomethingWentWrong := fmt.Errorf("Something went wrong")

	conn.SetAtLeastVersion(false, errSomethingWentWrong)
	got, err = inst.IsVersionSupported(conn)
	t.Assert(conn.Version, Equals, agent.MIN_SUPPORTED_MYSQL_VERSION)
	t.Assert(err, Equals, errSomethingWentWrong)
	t.Assert(got, Equals, false)

	conn.SetAtLeastVersion(true, nil)
	got, err = inst.IsVersionSupported(conn)
	t.Assert(conn.Version, Equals, agent.MIN_SUPPORTED_MYSQL_VERSION)
	t.Assert(err, IsNil)
	t.Assert(got, Equals, true)

	conn.Close()
}
Example #14
0
func (f *Factory) Make(service string, instanceId uint, data []byte) (sysconfig.Monitor, error) {
	var monitor sysconfig.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 := "sysconfig-mysql-" + mysqlIt.Hostname

		// Make a MySQL sysconfig monitor.
		monitor = mysql.NewMonitor(
			alias,
			config,
			pct.NewLogger(f.logChan, alias),
			mysqlConn.NewConnection(mysqlIt.DSN),
		)
	default:
		return nil, errors.New("Unknown sysconfig monitor type: " + service)
	}
	return monitor, nil
}
Example #15
0
// @goroutine[0]
func (m *Manager) Start() error {
	m.mux.Lock()
	defer m.mux.Unlock()

	if m.config != nil {
		return pct.ServiceIsRunningError{Service: "log"}
	}

	// Load config from disk.
	config := &Config{}
	if err := pct.Basedir.ReadConfig("log", config); err != nil {
		if !os.IsNotExist(err) {
			return err
		}
	}
	if err := m.validateConfig(config); err != nil {
		return err
	}

	// Start relay (it buffers and sends log entries to API).
	level := proto.LogLevelNumber[config.Level]
	m.relay = NewRelay(m.client, m.logChan, config.File, level, config.Offline)
	go m.relay.Run()

	m.logger = pct.NewLogger(m.relay.LogChan(), "log")
	m.config = config
	m.running = true

	m.logger.Info("Started")
	m.status.Update("log", "Running")
	return nil
}
Example #16
0
func (s *AggregatorTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "mm-manager-test")
	s.tickChan = make(chan time.Time)
	s.collectionChan = make(chan *mm.Collection)
	s.dataChan = make(chan interface{}, 1)
	s.spool = mock.NewSpooler(s.dataChan)
}
Example #17
0
func (s *SenderTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "data_test")
	s.tickerChan = make(chan time.Time, 1)

	s.dataChan = make(chan []byte, 5)
	s.respChan = make(chan interface{})
	s.client = mock.NewDataClient(s.dataChan, s.respChan)
}
Example #18
0
func (s *ManagerTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "system-monitor-test")

	s.tickChan = make(chan time.Time)
	s.collectionChan = make(chan *mm.Collection, 1)

	s.name = "localhost"
}
Example #19
0
func (m *Monitor) createMysqlInstance(dsn string) (mi *MysqlInstance, err error) {
	m.logger.Debug("createMysqlInstance:call:" + mysql.HideDSNPassword(dsn))
	defer m.logger.Debug("createMysqlInstance:return:" + mysql.HideDSNPassword(dsn))

	mysqlConn := m.mysqlConnFactory.Make(dsn)
	// todo: fix
	logger := pct.NewLogger(m.logger.LogChan(), "mrms-monitor-mysql")
	subscribers := NewSubscribers(logger)
	return NewMysqlInstance(logger, mysqlConn, subscribers)
}
Example #20
0
func NewManager(logger *pct.Logger, configDir string, api pct.APIConnector) *Manager {
	repo := NewRepo(pct.NewLogger(logger.LogChan(), "instance-repo"), configDir, api)
	m := &Manager{
		logger:    logger,
		configDir: configDir,
		// --
		status: pct.NewStatus([]string{"instance", "instance-repo"}),
		repo:   repo,
	}
	return m
}
Example #21
0
func (s *ManagerTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "mm-manager-test")
	s.tickChan = make(chan time.Time)
	s.traceChan = make(chan string, 10)
	s.dataChan = make(chan interface{}, 1)
	s.spool = mock.NewSpooler(s.dataChan)

	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "agent-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.tmpDir); err != nil {
		t.Fatal(err)
	}
	s.configDir = pct.Basedir.Dir("config")

	s.im = instance.NewRepo(pct.NewLogger(s.logChan, "im"), s.configDir, s.api)
	data, err := json.Marshal(&proto.MySQLInstance{
		Hostname: "db1",
		DSN:      "user:host@tcp:(127.0.0.1:3306)",
	})
	t.Assert(err, IsNil)
	s.im.Add("mysql", 1, data, false)
	data, err = json.Marshal(&proto.ServerInstance{Hostname: "host1"})
	t.Assert(err, IsNil)
	s.im.Add("server", 1, data, false)

	s.mysqlMonitor = mock.NewMmMonitor()
	s.systemMonitor = mock.NewMmMonitor()
	s.factory = mock.NewMmMonitorFactory(map[string]mm.Monitor{
		"mysql-1":  s.mysqlMonitor,
		"server-1": s.systemMonitor,
	})

	links := map[string]string{
		"agent":     "http://localhost/agent",
		"instances": "http://localhost/instances",
	}
	s.api = mock.NewAPI("http://localhost", "http://localhost", "123", "abc-123-def", links)
}
Example #22
0
func (s *TestSuite) SetUpSuite(t *C) {
	if dsn == "" {
		t.Fatal("PCT_TEST_MYSQL_DSN is not set")
	}

	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "mm-manager-test")
	s.tickChan = make(chan time.Time)
	s.reportChan = make(chan *sysconfig.Report, 1)
	s.reportChan = make(chan *sysconfig.Report, 1)
	s.name = "sysconfig-mysql-db1"
}
Example #23
0
func (s *AnalyzerTestSuite) SetUpSuite(t *C) {
	s.nullmysql = mock.NewNullMySQL()

	s.logChan = make(chan *proto.LogEntry, 1000)
	s.logger = pct.NewLogger(s.logChan, "qan-test")

	s.intervalChan = make(chan *qan.Interval, 1)

	s.iter = mock.NewIter(s.intervalChan)

	s.dataChan = make(chan interface{}, 1)
	s.spool = mock.NewSpooler(s.dataChan)

	var err error
	s.tmpDir, err = ioutil.TempDir("/tmp", "agent-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.tmpDir); err != nil {
		t.Fatal(err)
	}
	s.configDir = pct.Basedir.Dir("config")

	s.im = instance.NewRepo(pct.NewLogger(s.logChan, "im-test"), s.configDir, s.api)
	data, err := json.Marshal(&proto.MySQLInstance{
		Hostname: "bm-cloud-db01",
		Alias:    "db01",
		DSN:      "user:pass@tcp/",
	})
	t.Assert(err, IsNil)
	s.im.Add("mysql", 1, data, false)
	s.mysqlInstance = proto.ServiceInstance{Service: "mysql", InstanceId: 1}

	links := map[string]string{
		"agent":     "http://localhost/agent",
		"instances": "http://localhost/instances",
	}
	s.api = mock.NewAPI("http://localhost", "http://localhost", "123", "abc-123-def", links)

	s.restartChan = make(chan bool, 1)
}
Example #24
0
func (s *TestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "ws")

	mock.SendChan = make(chan interface{}, 5)
	mock.RecvChan = make(chan interface{}, 5)
	s.server = new(mock.WebsocketServer)
	go s.server.Run(ADDR, ENDPOINT)
	time.Sleep(100 * time.Millisecond)

	links := map[string]string{"agent": URL}
	s.api = mock.NewAPI("http://localhost", ADDR, "apikey", "uuid", links)
}
Example #25
0
func (s *RelayTestSuite) SetUpSuite(t *C) {
	s.logFile = fmt.Sprintf("/tmp/log_test.go.%d", os.Getpid())

	s.sendChan = make(chan interface{}, 5)
	s.recvChan = make(chan interface{}, 5)
	s.connectChan = make(chan bool)
	s.client = mock.NewWebsocketClient(nil, nil, s.sendChan, s.recvChan)

	s.logChan = make(chan *proto.LogEntry, log.BUFFER_SIZE*3)
	s.relay = log.NewRelay(s.client, s.logChan, "", proto.LOG_INFO, false)
	s.logger = pct.NewLogger(s.relay.LogChan(), "test")
	go s.relay.Run() // calls client.Connect()
}
Example #26
0
func (s *AnalyzerTestSuite) TestRunMockWorker(t *C) {
	a := qan.NewRealAnalyzer(
		pct.NewLogger(s.logChan, "qan-analyzer"),
		s.config,
		s.iter,
		s.nullmysql,
		s.restartChan,
		s.worker,
		s.clock,
		s.spool,
	)

	err := a.Start()
	t.Assert(err, IsNil)
	test.WaitStatus(1, a, "qan-analyzer", "Idle")

	// No interval yet, so work should not have one.
	t.Check(s.worker.Interval, IsNil)

	// Send an interval. The analyzer runs the worker with it.
	now := time.Now()
	i := &qan.Interval{
		Number:      1,
		StartTime:   now,
		StopTime:    now.Add(1 * time.Minute),
		Filename:    "slow.log",
		StartOffset: 0,
		EndOffset:   999,
	}
	s.intervalChan <- i

	if !test.WaitState(s.worker.SetupChan) {
		t.Fatal("Timeout waiting for <-s.worker.SetupChan")
	}

	t.Check(s.worker.Interval, DeepEquals, i)

	if !test.WaitState(s.worker.RunChan) {
		t.Fatal("Timeout waiting for <-s.worker.SetupChan")
	}

	if !test.WaitState(s.worker.CleanupChan) {
		t.Fatal("Timeout waiting for <-s.worker.SetupChan")
	}

	err = a.Stop()
	t.Assert(err, IsNil)
	test.WaitStatus(1, a, "qan-analyzer", "Stopped")

	t.Check(a.String(), Equals, "qan-analyzer")
}
Example #27
0
func (s *DiskvSpoolerTestSuite) SetUpSuite(t *C) {
	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "data_test")

	s.basedir, _ = ioutil.TempDir("/tmp", "percona-agent-data-spooler-test")
	s.dataDir = path.Join(s.basedir, "data")
	s.trashDir = path.Join(s.basedir, "trash")

	s.limits = proto.DataSpoolLimits{
		MaxAge:   data.DEFAULT_DATA_MAX_AGE,
		MaxSize:  data.DEFAULT_DATA_MAX_SIZE,
		MaxFiles: data.DEFAULT_DATA_MAX_FILES,
	}
}
Example #28
0
func NewManager(logger *pct.Logger, configDir string, api pct.APIConnector, mrm mrms.Monitor) *Manager {
	repo := NewRepo(pct.NewLogger(logger.LogChan(), "instance-repo"), configDir, api)
	m := &Manager{
		logger:    logger,
		configDir: configDir,
		api:       api,
		// --
		status:         pct.NewStatus([]string{"instance", "instance-repo", "instance-mrms"}),
		repo:           repo,
		mrm:            mrm,
		mrmChans:       make(map[string]<-chan bool),
		mrmsGlobalChan: make(chan string, 100), // monitor up to 100 instances
	}
	return m
}
Example #29
0
func (f *RealIntervalIterFactory) Make(analyzerType string, mysqlConn mysql.Connector, tickChan chan time.Time) qan.IntervalIter {
	switch analyzerType {
	case "slowlog":
		// The interval iter gets the slow log file (@@global.slow_query_log_file)
		// every tick because it can change (not typical, but possible). If it changes,
		// the start offset is reset to 0 for the new file.
		getSlowLogFunc := func() (string, error) {
			if err := mysqlConn.Connect(1); err != nil {
				return "", err
			}
			defer mysqlConn.Close()
			// Slow log file can be absolute or relative. If it's relative,
			// then prepend the datadir.
			dataDir := mysqlConn.GetGlobalVarString("datadir")
			filename := AbsDataFile(dataDir, mysqlConn.GetGlobalVarString("slow_query_log_file"))
			return filename, nil
		}
		return slowlog.NewIter(pct.NewLogger(f.logChan, "qan-interval"), getSlowLogFunc, tickChan)
	case "perfschema":
		return perfschema.NewIter(pct.NewLogger(f.logChan, "qan-interval"), tickChan)
	default:
		panic("Invalid analyzerType: " + analyzerType)
	}
}
Example #30
0
func (s *ManagerTestSuite) SetUpSuite(t *C) {
	var err error
	s.basedir, err = ioutil.TempDir("/tmp", "percona-agent-data-manager-test")
	t.Assert(err, IsNil)

	if err := pct.Basedir.Init(s.basedir); err != nil {
		t.Fatal(err)
	}
	s.dataDir = pct.Basedir.Dir("data")
	s.trashDir = path.Join(s.basedir, "trash")

	s.logChan = make(chan *proto.LogEntry, 10)
	s.logger = pct.NewLogger(s.logChan, "data_test")

	s.dataChan = make(chan []byte, 5)
	s.respChan = make(chan interface{})
	s.client = mock.NewDataClient(s.dataChan, s.respChan)
}