예제 #1
0
func TestReadFromCollector(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	collector := collector.New("Test")
	collector.SetInterval(1)
	collector.Configure(c)

	var wg sync.WaitGroup
	wg.Add(2)
	collectorStatChannel := make(chan metric.CollectorEmission)
	go func() {
		defer wg.Done()
		collector.Channel() <- metric.New("hello")
		time.Sleep(time.Duration(2) * time.Second)
		m2 := metric.New("world")
		m2.AddDimension("collectorCanonicalName", "Foobar")
		collector.Channel() <- m2
		time.Sleep(time.Duration(2) * time.Second)
		m2.AddDimension("collectorCanonicalName", "Foobar")
		collector.Channel() <- m2
		close(collector.Channel())
	}()
	collectorMetrics := map[string]uint64{}
	go func() {
		defer wg.Done()
		for collectorMetric := range collectorStatChannel {
			collectorMetrics[collectorMetric.Name] = collectorMetric.EmissionCount
		}
	}()
	readFromCollector(collector, []handler.Handler{}, collectorStatChannel)
	wg.Wait()
	assert.Equal(t, uint64(1), collectorMetrics["Test"])
	assert.Equal(t, uint64(2), collectorMetrics["Foobar"])
}
예제 #2
0
func TestHandlerBufferSize(t *testing.T) {
	base := BaseHandler{}
	base.log = l.WithField("testing", "basehandler_flush")
	base.interval = 5
	base.maxBufferSize = 100
	base.channel = make(chan metric.Metric)
	base.collectorEndpoints = map[string]CollectorEnd{
		"collector1": CollectorEnd{make(chan metric.Metric), 3},
	}

	emitFunc := func(metrics []metric.Metric) bool {
		assert.Equal(t, 3, len(metrics))
		return true
	}

	go base.run(emitFunc)
	base.CollectorEndpoints()["collector1"].Channel <- metric.New("testMetric")
	base.CollectorEndpoints()["collector1"].Channel <- metric.New("testMetric1")
	base.CollectorEndpoints()["collector1"].Channel <- metric.New("testMetric2")
	time.Sleep(1 * time.Second)
	assert.Equal(t, uint64(3), atomic.LoadUint64(&base.metricsSent))
	assert.Equal(t, uint64(0), atomic.LoadUint64(&base.metricsDropped))

	// This is just to stop goroutines that have been started before
	base.channel <- metric.Metric{}
	base.CollectorEndpoints()["collector1"].Channel <- metric.Metric{}
}
예제 #3
0
func TestKairosServerErrorParse(t *testing.T) {
	k := getTestKairosHandler(12, 13, 14)

	metrics := make([]metric.Metric, 0, 3)

	metrics = append(metrics, metric.New("Test1"))
	metrics = append(metrics, metric.New("Test2"))
	metrics = append(metrics, metric.New("test3"))

	metrics[0].AddDimension("somedim", "")
	metrics[1].AddDimension("somedim", "working")
	metrics[2].AddDimension("somedime", "")

	series := make([]KairosMetric, 0, len(metrics))
	for i := range metrics {
		series = append(series, k.convertToKairos(metrics[i]))
	}

	expectMetrics := make([]KairosMetric, 0, 2)
	expectMetrics = append(expectMetrics, k.convertToKairos(metrics[0]))
	expectMetrics = append(expectMetrics, k.convertToKairos(metrics[2]))

	expectByt, _ := json.Marshal(expectMetrics)

	errByt := []byte(`{\"errors\":[\"metric[0](name=Test1).tag[somedim].value may not be empty.\",` +
		`\"metric[2](name=Test3).tag[somedim].value may not be empty.\"]}`)

	assert.Equal(t, k.parseServerError(string(errByt), series), string(expectByt))
}
예제 #4
0
func TestSignalFxSanitation(t *testing.T) {
	s := getTestSignalfxHandler(12, 12, 12)

	m1 := metric.New(" Test= .me$tric ")
	m1.AddDimension("simple string", "simple string")
	m1.AddDimension("dot.string", "dot.string")
	m1.AddDimension("3.3", "3.3")
	m1.AddDimension("slash/string", "slash/string")
	m1.AddDimension("colon:string", "colon:string")
	m1.AddDimension("equal=string", "equal=string")
	datapoint1 := s.convertToProto(m1)

	m2 := metric.New("Test-_.metric")
	m2.AddDimension("simple_string", "simple_string")
	m2.AddDimension("dot_string", "dot.string")
	m2.AddDimension("3_3", "3.3")
	m2.AddDimension("slash_string", "slash/string")
	m2.AddDimension("colon-string", "colon-string")
	m2.AddDimension("equal-string", "equal-string")
	datapoint2 := s.convertToProto(m2)

	assert.Equal(t, datapoint1.GetMetric(), datapoint2.GetMetric(), "the two metrics should be the same")
	for i := 0; i < len(datapoint1.GetDimensions())-1; i++ {
		for j := i + 1; j < len(datapoint1.GetDimensions()); j++ {
			assert.NotEqual(t, datapoint1.GetDimensions()[i].GetKey(), datapoint1.GetDimensions()[j].GetKey(), "the two dimensions should be different")
		}
	}
}
예제 #5
0
func TestCollectorBlacklist(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)

	c := make(map[string]interface{})
	c["interval"] = 1
	c["metrics_blacklist"] = []string{"m[0-9]+$"}
	col := collector.New("Test")
	col.SetInterval(1)
	col.Configure(c)

	var wg sync.WaitGroup
	wg.Add(2)
	collectorStatChannel := make(chan metric.CollectorEmission)

	go func() {
		defer wg.Done()
		col.Channel() <- metric.New("m1")
		time.Sleep(time.Duration(2) * time.Second)
		col.Channel() <- metric.New("m2")
		time.Sleep(time.Duration(2) * time.Second)
		col.Channel() <- metric.New("metric3")
		close(col.Channel())
	}()
	collectorMetrics := map[string]uint64{}
	go func() {
		defer wg.Done()
		for collectorMetric := range collectorStatChannel {
			collectorMetrics[collectorMetric.Name] = collectorMetric.EmissionCount
		}
	}()
	readFromCollector(col, []handler.Handler{}, collectorStatChannel)
	wg.Wait()

	assert.Equal(t, uint64(1), collectorMetrics["Test"])
}
예제 #6
0
func TestSanitizeMetricDimensionValue(t *testing.T) {
	k := getTestKairosHandler(12, 13, 14)

	m1 := metric.New("Test")
	m1.AddDimension("some=dim", "valu=")
	s1 := k.convertToKairos(m1)

	m2 := metric.New("Test")
	m2.AddDimension("some-dim", "valu-")
	s2 := k.convertToKairos(m2)

	assert.Equal(t, s1, s2, "metric dimension should be sanitazed")
}
예제 #7
0
func TestSanitizeMetricName(t *testing.T) {
	k := getTestKairosHandler(12, 13, 14)

	m1 := metric.New("Test==:")
	m1.AddDimension("somedim", "value")
	s1 := k.convertToKairos(m1)

	m2 := metric.New("Test---")
	m2.AddDimension("somedim", "value")
	s2 := k.convertToKairos(m2)

	assert.Equal(t, s1, s2, "metric name should be sanitazed")
}
예제 #8
0
func TestAddDimensions(t *testing.T) {
	m1 := metric.New("TestMetric")
	m2 := metric.New("TestMetric")

	dimensions := map[string]string{
		"TestDimension":    "TestValue",
		"Dirty:=Dimension": "Dirty:=Value",
	}
	m1.AddDimension("TestDimension", "TestValue")
	m1.AddDimension("Dirty:=Dimension", "Dirty:=Value")
	m2.AddDimensions(dimensions)

	assert.Equal(t, m1, m2)
}
예제 #9
0
func procStatusPoint(name string, value float64, dimensions map[string]string) (m metric.Metric) {
	m = metric.New(name)
	m.Value = value
	m.AddDimension("collector", "ProcStatus")
	m.AddDimensions(dimensions)
	return m
}
예제 #10
0
func TestEmissionAndRecord(t *testing.T) {
	emitCalled := false

	callbackChannel := make(chan emissionTiming)
	emitFunc := func([]metric.Metric) bool {
		emitCalled = true
		return true
	}
	metrics := []metric.Metric{metric.New("example")}

	base := BaseHandler{}
	base.log = l.WithField("testing", "basehandler")
	go base.emitAndTime(metrics, emitFunc, callbackChannel)

	select {
	case timing := <-callbackChannel:
		assert.NotNil(t, timing)
		assert.Equal(t, 1, timing.metricsSent)
		assert.NotNil(t, timing.timestamp)
		assert.NotNil(t, timing.duration)
	case <-time.After(2 * time.Second):
		t.Fatal("Failed to read from the callback channel after 2 seconds")
	}

	assert.True(t, emitCalled)
	callbackChannel = nil
}
예제 #11
0
func TestHandlerRun(t *testing.T) {
	base := BaseHandler{}
	base.log = l.WithField("testing", "basehandler")
	base.interval = 1
	base.maxBufferSize = 1
	base.channel = make(chan metric.Metric)

	emitCalled := false
	emitFunc := func(metrics []metric.Metric) bool {
		assert.Equal(t, 1, len(metrics))
		emitCalled = true
		return true
	}

	// now we are waiting for some metrics
	go base.run(emitFunc)

	base.channel <- metric.New("testMetric")
	time.Sleep(1 * time.Second)
	assert.True(t, emitCalled)
	assert.Equal(t, 1, base.emissionTimes.Len())
	assert.Equal(t, uint64(1), base.metricsSent)
	assert.Equal(t, uint64(0), base.metricsDropped)
	assert.Equal(t, uint64(1), base.totalEmissions)
	assertEmpty(t, base.channel)
	base.channel = nil
}
예제 #12
0
func TestCollectorPrefix(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	c["prefix"] = "px."
	collector := collector.New("Test")
	collector.SetInterval(1)
	collector.Configure(c)

	collectorChannel := map[string]chan metric.Metric{
		"Test": make(chan metric.Metric),
	}

	testHandler := handler.New("Log")
	testHandler.SetCollectorChannels(collectorChannel)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		defer wg.Done()
		collector.Channel() <- metric.New("hello")
		close(collector.Channel())
	}()
	go func() {
		defer wg.Done()
		testMetric := <-collectorChannel["Test"]
		assert.Equal(t, "px.hello", testMetric.Name)
	}()
	readFromCollector(collector, []handler.Handler{testHandler})
	wg.Wait()
}
예제 #13
0
func TestWorkingGenericHTTP(t *testing.T) {
	// setup the server
	expectedResponse := "This should come back to me"
	server := buildServer(expectedResponse)
	defer server.Close()

	col := buildBaseHTTPCollector(server.URL)
	col.errHandler = func(err error) {
		testLog.Error("Should not have caused an error")
		t.FailNow()
	}

	col.rspHandler = func(rsp *http.Response) []metric.Metric {
		txt, _ := ioutil.ReadAll(rsp.Body)
		rsp.Body.Close()

		assert.Equal(t, expectedResponse, string(txt))
		return []metric.Metric{metric.New("junk")}
	}

	go col.Collect()
	m := <-col.Channel()

	assert.NotNil(t, m, "should have produced a single metric")
	assert.True(t, ensureEmpty(col.Channel()), "There should have only been a single metric")
}
예제 #14
0
func reportCollector(collector collector.Collector) {
	log.Warn(fmt.Sprintf("%s collector took too long to run, reporting incident!", collector.Name()))
	metric := metric.New("fullerite.collection_time_exceeded")
	metric.Value = 1
	metric.AddDimension("interval", fmt.Sprintf("%d", collector.Interval()))
	collector.Channel() <- metric
}
예제 #15
0
func TestSanitizeDimensionNameOverwriteCleanDirty(t *testing.T) {
	defaultDimensions := make(map[string]string)
	m := metric.New("TestMetric")
	m.AddDimension("Test-Dimension", "first value")
	m.AddDimension("Test=Dimension", "second value")
	assert := assert.New(t)

	value, ok := m.Dimensions["Test-Dimension"]
	assert.Equal("second value", value, "dimension value does not match")
	assert.True(ok)

	value, ok = m.Dimensions["Test=Dimension"]
	assert.False(ok)

	value, ok = m.GetDimensionValue("Test=Dimension")
	assert.Equal("second value", value, "dimension value does not match")
	assert.True(ok)
	value, ok = m.GetDimensionValue("Test-Dimension")
	assert.Equal("second value", value, "dimension value does not match")
	assert.True(ok)

	dimensions := m.GetDimensions(defaultDimensions)
	value, ok = dimensions["Test-Dimension"]
	assert.Equal("second value", value, "dimension value does not match")
	assert.True(ok)
	value, ok = dimensions["Test=Dimension"]
	assert.False(ok)

	assert.Equal(1, len(dimensions), "only 1 dimension should exist")
}
예제 #16
0
func TestSanitizeDimensionNameColon(t *testing.T) {
	defaultDimensions := make(map[string]string)
	m := metric.New("TestMetric")
	m.AddDimension("DirtyDimension:", "dimension value")
	assert := assert.New(t)

	value, ok := m.Dimensions["DirtyDimension-"]
	assert.Equal("dimension value", value, "dimension value does not match")
	assert.True(ok)

	value, ok = m.Dimensions["DirtyDimension:"]
	assert.False(ok)

	value, ok = m.GetDimensionValue("DirtyDimension:")
	assert.Equal("dimension value", value, "dimension value does not match")
	assert.True(ok)

	value, ok = m.GetDimensionValue("DirtyDimension-")
	assert.Equal("dimension value", value, "dimension value does not match")
	assert.True(ok)

	dimensions := m.GetDimensions(defaultDimensions)
	value, ok = dimensions["DirtyDimension:"]
	assert.False(ok)

	value, ok = dimensions["DirtyDimension-"]
	assert.Equal("dimension value", value, "dimension value does not match")
	assert.True(ok)
}
예제 #17
0
파일: test.go 프로젝트: jaxxstorm/fullerite
// Collect produces some random test metrics.
func (t Test) Collect() {
	metric := metric.New(t.metricName)
	metric.Value = rand.Float64()
	metric.AddDimension("testing", "yes")
	t.Channel() <- metric
	t.log.Debug(metric)
}
예제 #18
0
func procStatusPoint(name string, value float64, dimensions map[string]string, metricType string) (m metric.Metric) {
	m = metric.New(name)
	m.Value = value
	m.AddDimensions(dimensions)
	m.MetricType = metricType
	return m
}
예제 #19
0
func TestHandlerRun(t *testing.T) {
	var mu sync.Mutex
	base := BaseHandler{}
	base.log = l.WithField("testing", "basehandler_run")
	base.interval = 1
	base.maxBufferSize = 1
	base.channel = make(chan metric.Metric)

	emitCalled := false
	emitFunc := func(metrics []metric.Metric) bool {
		assert.Equal(t, 1, len(metrics))
		mu.Lock()
		defer mu.Unlock()
		emitCalled = true
		return true
	}

	// now we are waiting for some metrics
	go base.run(emitFunc)

	base.channel <- metric.New("testMetric")
	time.Sleep(1 * time.Second)
	mu.Lock()
	assert.True(t, emitCalled)
	mu.Unlock()
	assert.Equal(t, 1, base.GetEmissionTimesLen())
	assert.Equal(t, uint64(1), atomic.LoadUint64(&base.metricsSent))
	assert.Equal(t, uint64(0), atomic.LoadUint64(&base.metricsDropped))
	assert.Equal(t, uint64(1), atomic.LoadUint64(&base.totalEmissions))
	base.channel <- metric.Metric{}
}
예제 #20
0
func emitTestMetric(conn net.Conn) {
	var metrics []metric.Metric
	metrics = append(metrics, metric.New("test"))
	b, _ := json.Marshal(metrics)
	fmt.Fprintf(conn, string(b)+"\n")
	fmt.Fprintf(conn, string(b)+"\n")
}
예제 #21
0
func TestGetDimensionValueNotFound(t *testing.T) {
	m := metric.New("TestMetric")
	value, ok := m.GetDimensionValue("TestDimension")

	assert := assert.New(t)
	assert.Equal(value, "", "non-existing value should be empty")
	assert.Equal(ok, false, "should return false")
}
예제 #22
0
파일: test.go 프로젝트: EvanKrall/fullerite
// Collect produces some random test metrics.
func (t Test) Collect() {
	metric := metric.New(t.metricName)
	metric.Value = t.generator()
	metric.AddDimension("testing", "yes")
	time.Sleep(3 * time.Second)
	t.Channel() <- metric
	t.log.Debug(metric)
}
예제 #23
0
func TestAddDimension(t *testing.T) {
	m := metric.New("TestMetric")
	m.AddDimension("TestDimension", "test value")

	assert := assert.New(t)
	assert.Equal(len(m.Dimensions), 1, "should have 1 dimension")
	assert.Equal(m.Dimensions["TestDimension"], "test value")
}
예제 #24
0
// buildMetric creates the metric and set the correct metricType
func (m *MesosSlaveStats) buildMetric(name string, value float64) metric.Metric {
	s := metric.New("mesos." + name)
	s.Value = value
	if _, exists := mesosSlaveCumulativeCountersList[name]; exists {
		s.MetricType = metric.CumulativeCounter
	}
	return s
}
예제 #25
0
func TestGetDimensionValueFound(t *testing.T) {
	m := metric.New("TestMetric")
	m.AddDimension("TestDimension", "test value")
	value, ok := m.GetDimensionValue("TestDimension")

	assert := assert.New(t)
	assert.Equal(value, "test value", "test value does not match")
	assert.Equal(ok, true, "should succeed")
}
예제 #26
0
func TestGetDimensionsWithDimensions(t *testing.T) {
	defaultDimensions := make(map[string]string)
	defaultDimensions["DefaultDim"] = "default value"
	m := metric.New("TestMetric")
	m.AddDimension("TestDimension", "test value")

	numDimensions := len(m.GetDimensions(defaultDimensions))
	assert.Equal(t, numDimensions, 2, "dimensions length should be 2")
}
예제 #27
0
func TestNewMetric(t *testing.T) {
	m := metric.New("TestMetric")

	assert := assert.New(t)
	assert.Equal(m.Name, "TestMetric")
	assert.Equal(m.Value, 0.0, "default value should be 0.0")
	assert.Equal(m.MetricType, "gauge", "should be a Gauge metric")
	assert.NotEqual(len(m.Dimensions), 1, "should have one dimension")
}
예제 #28
0
func (hook *LogErrorHook) reportErrors(entry *logrus.Entry) {
	metric := metric.New("fullerite.collector_errors")
	metric.Value = 1
	if val, exists := entry.Data["collector"]; exists {
		metric.AddDimension("collector", val.(string))
	}
	hook.metricsChannel <- metric
	return
}
예제 #29
0
func TestKairosDimensionsOverwriting(t *testing.T) {
	s := getTestKairosHandler(12, 12, 12)

	m1 := metric.New("Test")
	m1.AddDimension("some=dim", "first value")
	m1.AddDimension("some-dim", "second value")
	datapoint := s.convertToKairos(m1)

	assert.Equal(t, len(datapoint.Tags), 1, "the two metrics should be the same")
}
예제 #30
0
// buildMetric Build a fullerite metric.
func buildMetric(k string, v float64) metric.Metric {
	m := metric.New("mesos." + k)
	m.Value = v

	if _, exists := mesosMasterCumulativeCountersList[k]; exists {
		m.MetricType = metric.CumulativeCounter
	}

	return m
}