Пример #1
0
func mustLabelMatcher(mt metric.MatchType, name model.LabelName, val model.LabelValue) *metric.LabelMatcher {
	m, err := metric.NewLabelMatcher(mt, name, val)
	if err != nil {
		panic(err)
	}
	return m
}
Пример #2
0
func BenchmarkGetFingerprintsForNotEqualMatcher1000(b *testing.B) {
	numSeries := 1000
	samples := make(clientmodel.Samples, 0, numSeries)
	for i := 0; i < numSeries; i++ {
		samples = append(samples, &clientmodel.Sample{
			Metric: clientmodel.Metric{
				clientmodel.MetricNameLabel: "testmetric",
				"instance":                  clientmodel.LabelValue(fmt.Sprint("instance_", i)),
			},
			Value:     1,
			Timestamp: clientmodel.TimestampFromTime(time.Date(2000, 0, 0, 0, 0, 0, 0, time.UTC)),
		})
	}

	s := NewMemorySeriesStorage(MemorySeriesOptions{})
	if err := s.AppendSamples(samples); err != nil {
		b.Fatal(err)
	}

	m, err := metric.NewLabelMatcher(metric.NotEqual, "instance", "foo")
	if err != nil {
		b.Fatal(err)
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.GetFingerprintsForLabelMatchers(metric.LabelMatchers{m})
	}
}
Пример #3
0
func newLabelMatcher(matchTypeStr string, name clientmodel.LabelName, value clientmodel.LabelValue) (*metric.LabelMatcher, error) {
	matchTypes := map[string]metric.MatchType{
		"=":  metric.Equal,
		"!=": metric.NotEqual,
		"=~": metric.RegexMatch,
		"!~": metric.RegexNoMatch,
	}
	matchType, ok := matchTypes[matchTypeStr]
	if !ok {
		return nil, fmt.Errorf("Invalid label matching operator \"%v\"", matchTypeStr)
	}
	return metric.NewLabelMatcher(matchType, name, value)
}
Пример #4
0
// vectorSelector parses a new (instant) vector selector.
//
//		<metric_identifier> [<label_matchers>]
//		[<metric_identifier>] <label_matchers>
//
func (p *parser) vectorSelector(name string) *VectorSelector {
	const ctx = "metric selector"

	var matchers metric.LabelMatchers
	// Parse label matching if any.
	if t := p.peek(); t.typ == itemLeftBrace {
		matchers = p.labelMatchers(itemEQL, itemNEQ, itemEQLRegex, itemNEQRegex)
	}
	// Metric name must not be set in the label matchers and before at the same time.
	if name != "" {
		for _, m := range matchers {
			if m.Name == model.MetricNameLabel {
				p.errorf("metric name must not be set twice: %q or %q", name, m.Value)
			}
		}
		// Set name label matching.
		matchers = append(matchers, &metric.LabelMatcher{
			Type:  metric.Equal,
			Name:  model.MetricNameLabel,
			Value: model.LabelValue(name),
		})
	}

	if len(matchers) == 0 {
		p.errorf("vector selector must contain label matchers or metric name")
	}
	// A vector selector must contain at least one non-empty matcher to prevent
	// implicit selection of all metrics (e.g. by a typo).
	notEmpty := false
	for _, lm := range matchers {
		// Matching changes the inner state of the regex and causes reflect.DeepEqual
		// to return false, which break tests.
		// Thus, we create a new label matcher for this testing.
		lm, err := metric.NewLabelMatcher(lm.Type, lm.Name, lm.Value)
		if err != nil {
			p.error(err)
		}
		if !lm.Match("") {
			notEmpty = true
			break
		}
	}
	if !notEmpty {
		p.errorf("vector selector must contain at least one non-empty matcher")
	}

	return &VectorSelector{
		Name:          name,
		LabelMatchers: matchers,
	}
}
Пример #5
0
// vectorSelector parses a new (instant) vector selector.
//
//		<metric_identifier> [<label_matchers>]
//		[<metric_identifier>] <label_matchers>
//
func (p *parser) vectorSelector(name string) *VectorSelector {
	var matchers metric.LabelMatchers
	// Parse label matching if any.
	if t := p.peek(); t.typ == itemLeftBrace {
		matchers = p.labelMatchers(itemEQL, itemNEQ, itemEQLRegex, itemNEQRegex)
	}
	// Metric name must not be set in the label matchers and before at the same time.
	if name != "" {
		for _, m := range matchers {
			if m.Name == model.MetricNameLabel {
				p.errorf("metric name must not be set twice: %q or %q", name, m.Value)
			}
		}
		// Set name label matching.
		m, err := metric.NewLabelMatcher(metric.Equal, model.MetricNameLabel, model.LabelValue(name))
		if err != nil {
			panic(err) // Must not happen with metric.Equal.
		}
		matchers = append(matchers, m)
	}

	if len(matchers) == 0 {
		p.errorf("vector selector must contain label matchers or metric name")
	}
	// A vector selector must contain at least one non-empty matcher to prevent
	// implicit selection of all metrics (e.g. by a typo).
	notEmpty := false
	for _, lm := range matchers {
		if !lm.MatchesEmptyString() {
			notEmpty = true
			break
		}
	}
	if !notEmpty {
		p.errorf("vector selector must contain at least one non-empty matcher")
	}

	return &VectorSelector{
		Name:          name,
		LabelMatchers: matchers,
	}
}
Пример #6
0
// labelMatchers parses a set of label matchers.
//
//		'{' [ <labelname> <match_op> <match_string>, ... ] '}'
//
func (p *parser) labelMatchers(operators ...itemType) metric.LabelMatchers {
	const ctx = "label matching"

	matchers := metric.LabelMatchers{}

	p.expect(itemLeftBrace, ctx)

	// Check if no matchers are provided.
	if p.peek().typ == itemRightBrace {
		p.next()
		return matchers
	}

	for {
		label := p.expect(itemIdentifier, ctx)

		op := p.next().typ
		if !op.isOperator() {
			p.errorf("expected label matching operator but got %s", op)
		}
		var validOp = false
		for _, allowedOp := range operators {
			if op == allowedOp {
				validOp = true
			}
		}
		if !validOp {
			p.errorf("operator must be one of %q, is %q", operators, op)
		}

		val := trimOne(p.expect(itemString, ctx).val)

		// Map the item to the respective match type.
		var matchType metric.MatchType
		switch op {
		case itemEQL:
			matchType = metric.Equal
		case itemNEQ:
			matchType = metric.NotEqual
		case itemEQLRegex:
			matchType = metric.RegexMatch
		case itemNEQRegex:
			matchType = metric.RegexNoMatch
		default:
			p.errorf("item %q is not a metric match type", op)
		}

		m, err := metric.NewLabelMatcher(
			matchType,
			model.LabelName(label.val),
			model.LabelValue(val),
		)
		if err != nil {
			p.error(err)
		}

		matchers = append(matchers, m)

		// Terminate list if last matcher.
		if p.peek().typ != itemComma {
			break
		}
		p.next()
	}

	p.expect(itemRightBrace, ctx)

	return matchers
}
Пример #7
0
func TestMatches(t *testing.T) {
	storage, closer := NewTestStorage(t, 1)
	defer closer.Close()

	samples := make([]*model.Sample, 100)
	fingerprints := make(model.Fingerprints, 100)

	for i := range samples {
		metric := model.Metric{
			model.MetricNameLabel: model.LabelValue(fmt.Sprintf("test_metric_%d", i)),
			"label1":              model.LabelValue(fmt.Sprintf("test_%d", i/10)),
			"label2":              model.LabelValue(fmt.Sprintf("test_%d", (i+5)/10)),
			"all":                 "const",
		}
		samples[i] = &model.Sample{
			Metric:    metric,
			Timestamp: model.Time(i),
			Value:     model.SampleValue(i),
		}
		fingerprints[i] = metric.FastFingerprint()
	}
	for _, s := range samples {
		storage.Append(s)
	}
	storage.WaitForIndexing()

	newMatcher := func(matchType metric.MatchType, name model.LabelName, value model.LabelValue) *metric.LabelMatcher {
		lm, err := metric.NewLabelMatcher(matchType, name, value)
		if err != nil {
			t.Fatalf("error creating label matcher: %s", err)
		}
		return lm
	}

	var matcherTests = []struct {
		matchers metric.LabelMatchers
		expected model.Fingerprints
	}{
		{
			matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "x")},
			expected: model.Fingerprints{},
		},
		{
			matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "test_0")},
			expected: fingerprints[:10],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", "test_0"),
				newMatcher(metric.Equal, "label2", "test_1"),
			},
			expected: fingerprints[5:10],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "x"),
			},
			expected: fingerprints,
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "test_0"),
			},
			expected: fingerprints[10:],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.NotEqual, "label1", "test_1"),
				newMatcher(metric.NotEqual, "label1", "test_2"),
			},
			expected: fingerprints[30:],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", ""),
			},
			expected: fingerprints[:0],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.Equal, "label1", ""),
			},
			expected: fingerprints[:0],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.Equal, "label2", ""),
			},
			expected: fingerprints[:0],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.Equal, "not_existant", ""),
			},
			expected: fingerprints[10:],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.RegexMatch, "label1", `test_[3-5]`),
			},
			expected: fingerprints[30:60],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.RegexNoMatch, "label1", `test_[3-5]`),
			},
			expected: append(append(model.Fingerprints{}, fingerprints[:30]...), fingerprints[60:]...),
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.RegexMatch, "label1", `test_[3-5]`),
				newMatcher(metric.RegexMatch, "label2", `test_[4-6]`),
			},
			expected: fingerprints[35:60],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.RegexMatch, "label1", `test_[3-5]`),
				newMatcher(metric.NotEqual, "label2", `test_4`),
			},
			expected: append(append(model.Fingerprints{}, fingerprints[30:35]...), fingerprints[45:60]...),
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", `nonexistent`),
				newMatcher(metric.RegexMatch, "label2", `test`),
			},
			expected: model.Fingerprints{},
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", `test_0`),
				newMatcher(metric.RegexMatch, "label2", `nonexistent`),
			},
			expected: model.Fingerprints{},
		},
	}

	for _, mt := range matcherTests {
		res := storage.MetricsForLabelMatchers(mt.matchers...)
		if len(mt.expected) != len(res) {
			t.Fatalf("expected %d matches for %q, found %d", len(mt.expected), mt.matchers, len(res))
		}
		for fp1 := range res {
			found := false
			for _, fp2 := range mt.expected {
				if fp1 == fp2 {
					found = true
					break
				}
			}
			if !found {
				t.Errorf("expected fingerprint %s for %q not in result", fp1, mt.matchers)
			}
		}
	}
}
Пример #8
0
func BenchmarkLabelMatching(b *testing.B) {
	s, closer := NewTestStorage(b, 1)
	defer closer.Close()

	h := fnv.New64a()
	lbl := func(x int) model.LabelValue {
		h.Reset()
		h.Write([]byte(fmt.Sprintf("%d", x)))
		return model.LabelValue(fmt.Sprintf("%d", h.Sum64()))
	}

	M := 32
	met := model.Metric{}
	for i := 0; i < M; i++ {
		met["label_a"] = lbl(i)
		for j := 0; j < M; j++ {
			met["label_b"] = lbl(j)
			for k := 0; k < M; k++ {
				met["label_c"] = lbl(k)
				for l := 0; l < M; l++ {
					met["label_d"] = lbl(l)
					s.Append(&model.Sample{
						Metric:    met.Clone(),
						Timestamp: 0,
						Value:     1,
					})
				}
			}
		}
	}
	s.WaitForIndexing()

	newMatcher := func(matchType metric.MatchType, name model.LabelName, value model.LabelValue) *metric.LabelMatcher {
		lm, err := metric.NewLabelMatcher(matchType, name, value)
		if err != nil {
			b.Fatalf("error creating label matcher: %s", err)
		}
		return lm
	}

	var matcherTests = []metric.LabelMatchers{
		{
			newMatcher(metric.Equal, "label_a", lbl(1)),
		},
		{
			newMatcher(metric.Equal, "label_a", lbl(3)),
			newMatcher(metric.Equal, "label_c", lbl(3)),
		},
		{
			newMatcher(metric.Equal, "label_a", lbl(3)),
			newMatcher(metric.Equal, "label_c", lbl(3)),
			newMatcher(metric.NotEqual, "label_d", lbl(3)),
		},
		{
			newMatcher(metric.Equal, "label_a", lbl(3)),
			newMatcher(metric.Equal, "label_b", lbl(3)),
			newMatcher(metric.Equal, "label_c", lbl(3)),
			newMatcher(metric.NotEqual, "label_d", lbl(3)),
		},
		{
			newMatcher(metric.RegexMatch, "label_a", ".+"),
		},
		{
			newMatcher(metric.Equal, "label_a", lbl(3)),
			newMatcher(metric.RegexMatch, "label_a", ".+"),
		},
		{
			newMatcher(metric.Equal, "label_a", lbl(1)),
			newMatcher(metric.RegexMatch, "label_c", "("+lbl(3)+"|"+lbl(10)+")"),
		},
		{
			newMatcher(metric.Equal, "label_a", lbl(3)),
			newMatcher(metric.Equal, "label_a", lbl(4)),
			newMatcher(metric.RegexMatch, "label_c", "("+lbl(3)+"|"+lbl(10)+")"),
		},
	}

	b.ReportAllocs()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		benchLabelMatchingRes = map[model.Fingerprint]metric.Metric{}
		for _, mt := range matcherTests {
			benchLabelMatchingRes = s.MetricsForLabelMatchers(mt...)
		}
	}
	// Stop timer to not count the storage closing.
	b.StopTimer()
}
Пример #9
0
func GetFingerprintsForLabelSetTests(p metric.Persistence, t test.Tester) {
	metrics := []clientmodel.Metric{
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "get",
			"result":                    "success",
		},
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "get",
			"result":                    "failure",
		},
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "post",
			"result":                    "success",
		},
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "post",
			"result":                    "failure",
		},
	}

	newTestLabelMatcher := func(matchType metric.MatchType, name clientmodel.LabelName, value clientmodel.LabelValue) *metric.LabelMatcher {
		m, err := metric.NewLabelMatcher(matchType, name, value)
		if err != nil {
			t.Fatalf("Couldn't create label matcher: %v", err)
		}
		return m
	}

	scenarios := []struct {
		in         metric.LabelMatchers
		outIndexes []int
	}{
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
			},
			outIndexes: []int{0, 1, 2, 3},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "non_existent_metric"),
			},
			outIndexes: []int{},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "non_existent_metric"),
				newTestLabelMatcher(metric.Equal, "result", "success"),
			},
			outIndexes: []int{},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.Equal, "result", "success"),
			},
			outIndexes: []int{0, 2},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.NotEqual, "result", "success"),
			},
			outIndexes: []int{1, 3},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.RegexMatch, "result", "foo|success|bar"),
			},
			outIndexes: []int{0, 2},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.RegexNoMatch, "result", "foo|success|bar"),
			},
			outIndexes: []int{1, 3},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.RegexNoMatch, "result", "foo|success|bar"),
				newTestLabelMatcher(metric.RegexMatch, "method", "os"),
			},
			outIndexes: []int{3},
		},
	}

	for _, m := range metrics {
		testAppendSamples(p, &clientmodel.Sample{
			Value:     0,
			Timestamp: 0,
			Metric:    m,
		}, t)
	}

	for i, s := range scenarios {
		actualFps, err := p.GetFingerprintsForLabelMatchers(s.in)
		if err != nil {
			t.Fatalf("%d. Couldn't get fingerprints for label matchers: %v", i, err)
		}

		expectedFps := clientmodel.Fingerprints{}
		for _, i := range s.outIndexes {
			fp := &clientmodel.Fingerprint{}
			fp.LoadFromMetric(metrics[i])
			expectedFps = append(expectedFps, fp)
		}

		sort.Sort(actualFps)
		sort.Sort(expectedFps)

		if len(actualFps) != len(expectedFps) {
			t.Fatalf("%d. Got %d fingerprints; want %d", i, len(actualFps), len(expectedFps))
		}

		for j, actualFp := range actualFps {
			if !actualFp.Equal(expectedFps[j]) {
				t.Fatalf("%d.%d. Got fingerprint %v; want %v", i, j, actualFp, expectedFps[j])
			}
		}
	}
}
Пример #10
0
func TestMatches(t *testing.T) {
	storage, closer := NewTestStorage(t, 2)
	defer closer.Close()

	storage.archiveHighWatermark = 90
	samples := make([]*model.Sample, 100)
	fingerprints := make(model.Fingerprints, 100)

	for i := range samples {
		metric := model.Metric{
			model.MetricNameLabel: model.LabelValue(fmt.Sprintf("test_metric_%d", i)),
			"label1":              model.LabelValue(fmt.Sprintf("test_%d", i/10)),
			"label2":              model.LabelValue(fmt.Sprintf("test_%d", (i+5)/10)),
			"all":                 "const",
		}
		samples[i] = &model.Sample{
			Metric:    metric,
			Timestamp: model.Time(i),
			Value:     model.SampleValue(i),
		}
		fingerprints[i] = metric.FastFingerprint()
	}
	for _, s := range samples {
		storage.Append(s)
	}
	storage.WaitForIndexing()

	// Archive every tenth metric.
	for i, fp := range fingerprints {
		if i%10 != 0 {
			continue
		}
		s, ok := storage.fpToSeries.get(fp)
		if !ok {
			t.Fatal("could not retrieve series for fp", fp)
		}
		storage.fpLocker.Lock(fp)
		storage.persistence.archiveMetric(fp, s.metric, s.firstTime(), s.lastTime)
		storage.fpLocker.Unlock(fp)
	}

	newMatcher := func(matchType metric.MatchType, name model.LabelName, value model.LabelValue) *metric.LabelMatcher {
		lm, err := metric.NewLabelMatcher(matchType, name, value)
		if err != nil {
			t.Fatalf("error creating label matcher: %s", err)
		}
		return lm
	}

	var matcherTests = []struct {
		matchers metric.LabelMatchers
		expected model.Fingerprints
	}{
		{
			matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "x")},
			expected: model.Fingerprints{},
		},
		{
			matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "test_0")},
			expected: fingerprints[:10],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", "test_0"),
				newMatcher(metric.Equal, "label2", "test_1"),
			},
			expected: fingerprints[5:10],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "x"),
			},
			expected: fingerprints,
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "test_0"),
			},
			expected: fingerprints[10:],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.NotEqual, "label1", "test_1"),
				newMatcher(metric.NotEqual, "label1", "test_2"),
			},
			expected: fingerprints[30:],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", ""),
			},
			expected: fingerprints[:0],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.Equal, "label1", ""),
			},
			expected: fingerprints[:0],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.Equal, "label2", ""),
			},
			expected: fingerprints[:0],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.NotEqual, "label1", "test_0"),
				newMatcher(metric.Equal, "not_existant", ""),
			},
			expected: fingerprints[10:],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.RegexMatch, "label1", `test_[3-5]`),
			},
			expected: fingerprints[30:60],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "all", "const"),
				newMatcher(metric.RegexNoMatch, "label1", `test_[3-5]`),
			},
			expected: append(append(model.Fingerprints{}, fingerprints[:30]...), fingerprints[60:]...),
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.RegexMatch, "label1", `test_[3-5]`),
				newMatcher(metric.RegexMatch, "label2", `test_[4-6]`),
			},
			expected: fingerprints[35:60],
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.RegexMatch, "label1", `test_[3-5]`),
				newMatcher(metric.NotEqual, "label2", `test_4`),
			},
			expected: append(append(model.Fingerprints{}, fingerprints[30:35]...), fingerprints[45:60]...),
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", `nonexistent`),
				newMatcher(metric.RegexMatch, "label2", `test`),
			},
			expected: model.Fingerprints{},
		},
		{
			matchers: metric.LabelMatchers{
				newMatcher(metric.Equal, "label1", `test_0`),
				newMatcher(metric.RegexMatch, "label2", `nonexistent`),
			},
			expected: model.Fingerprints{},
		},
	}

	for _, mt := range matcherTests {
		res := storage.MetricsForLabelMatchers(
			model.Earliest, model.Latest,
			mt.matchers...,
		)
		if len(mt.expected) != len(res) {
			t.Fatalf("expected %d matches for %q, found %d", len(mt.expected), mt.matchers, len(res))
		}
		for fp1 := range res {
			found := false
			for _, fp2 := range mt.expected {
				if fp1 == fp2 {
					found = true
					break
				}
			}
			if !found {
				t.Errorf("expected fingerprint %s for %q not in result", fp1, mt.matchers)
			}
		}
		// Smoketest for from/through.
		if len(storage.MetricsForLabelMatchers(
			model.Earliest, -10000,
			mt.matchers...,
		)) > 0 {
			t.Error("expected no matches with 'through' older than any sample")
		}
		if len(storage.MetricsForLabelMatchers(
			10000, model.Latest,
			mt.matchers...,
		)) > 0 {
			t.Error("expected no matches with 'from' newer than any sample")
		}
		// Now the tricky one, cut out something from the middle.
		var (
			from    model.Time = 25
			through model.Time = 75
		)
		res = storage.MetricsForLabelMatchers(
			from, through,
			mt.matchers...,
		)
		expected := model.Fingerprints{}
		for _, fp := range mt.expected {
			i := 0
			for ; fingerprints[i] != fp && i < len(fingerprints); i++ {
			}
			if i == len(fingerprints) {
				t.Fatal("expected fingerprint does not exist")
			}
			if !model.Time(i).Before(from) && !model.Time(i).After(through) {
				expected = append(expected, fp)
			}
		}
		if len(expected) != len(res) {
			t.Errorf("expected %d range-limited matches for %q, found %d", len(expected), mt.matchers, len(res))
		}
		for fp1 := range res {
			found := false
			for _, fp2 := range expected {
				if fp1 == fp2 {
					found = true
					break
				}
			}
			if !found {
				t.Errorf("expected fingerprint %s for %q not in range-limited result", fp1, mt.matchers)
			}
		}

	}
}
Пример #11
0
func TestReaderWriterDeadlockRegression(t *testing.T) {
	mp := runtime.GOMAXPROCS(2)
	defer func(mp int) {
		runtime.GOMAXPROCS(mp)
	}(mp)

	s := NewMemorySeriesStorage(MemorySeriesOptions{})
	lms := metric.LabelMatchers{}

	for i := 0; i < 100; i++ {
		lm, err := metric.NewLabelMatcher(metric.NotEqual, clientmodel.MetricNameLabel, "testmetric")
		if err != nil {
			t.Fatal(err)
		}
		lms = append(lms, lm)
	}

	wg := sync.WaitGroup{}
	wg.Add(2)

	start := time.Now()
	runDuration := 250 * time.Millisecond

	writer := func() {
		for time.Since(start) < runDuration {
			s.AppendSamples(clientmodel.Samples{
				&clientmodel.Sample{
					Metric: clientmodel.Metric{
						clientmodel.MetricNameLabel: "testmetric",
					},
					Value:     1,
					Timestamp: 0,
				},
			})
		}
		wg.Done()
	}

	reader := func() {
		for time.Since(start) < runDuration {
			s.GetFingerprintsForLabelMatchers(lms)
		}
		wg.Done()
	}

	go reader()
	go writer()

	allDone := make(chan struct{})
	go func() {
		wg.Wait()
		allDone <- struct{}{}
	}()

	select {
	case <-allDone:
		break
	case <-time.NewTimer(5 * time.Second).C:
		t.Fatalf("Deadlock timeout")
	}
}
Пример #12
0
func yyParse(yylex yyLexer) int {
	var yyn int
	var yylval yySymType
	var yyVAL yySymType
	yyS := make([]yySymType, yyMaxDepth)

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	yystate := 0
	yychar := -1
	yyp := -1
	goto yystack

ret0:
	return 0

ret1:
	return 1

yystack:
	/* put a state and value onto the stack */
	if yyDebug >= 4 {
		__yyfmt__.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate))
	}

	yyp++
	if yyp >= len(yyS) {
		nyys := make([]yySymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
	}
	yyS[yyp] = yyVAL
	yyS[yyp].yys = yystate

yynewstate:
	yyn = yyPact[yystate]
	if yyn <= yyFlag {
		goto yydefault /* simple state */
	}
	if yychar < 0 {
		yychar = yylex1(yylex, &yylval)
	}
	yyn += yychar
	if yyn < 0 || yyn >= yyLast {
		goto yydefault
	}
	yyn = yyAct[yyn]
	if yyChk[yyn] == yychar { /* valid shift */
		yychar = -1
		yyVAL = yylval
		yystate = yyn
		if Errflag > 0 {
			Errflag--
		}
		goto yystack
	}

yydefault:
	/* default state action */
	yyn = yyDef[yystate]
	if yyn == -2 {
		if yychar < 0 {
			yychar = yylex1(yylex, &yylval)
		}

		/* look through exception table */
		xi := 0
		for {
			if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			yyn = yyExca[xi+0]
			if yyn < 0 || yyn == yychar {
				break
			}
		}
		yyn = yyExca[xi+1]
		if yyn < 0 {
			goto ret0
		}
	}
	if yyn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			yylex.Error("syntax error")
			Nerrs++
			if yyDebug >= 1 {
				__yyfmt__.Printf("%s", yyStatname(yystate))
				__yyfmt__.Printf(" saw %s\n", yyTokname(yychar))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for yyp >= 0 {
				yyn = yyPact[yyS[yyp].yys] + yyErrCode
				if yyn >= 0 && yyn < yyLast {
					yystate = yyAct[yyn] /* simulate a shift of "error" */
					if yyChk[yystate] == yyErrCode {
						goto yystack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if yyDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
				}
				yyp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if yyDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %s\n", yyTokname(yychar))
			}
			if yychar == yyEofCode {
				goto ret1
			}
			yychar = -1
			goto yynewstate /* try again in the same state */
		}
	}

	/* reduction by production yyn */
	if yyDebug >= 2 {
		__yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
	}

	yynt := yyn
	yypt := yyp
	_ = yypt // guard against "declared and not used"

	yyp -= yyR2[yyn]
	yyVAL = yyS[yyp+1]

	/* consult goto table to find next state */
	yyn = yyR1[yyn]
	yyg := yyPgo[yyn]
	yyj := yyg + yyS[yyp].yys + 1

	if yyj >= yyLast {
		yystate = yyAct[yyg]
	} else {
		yystate = yyAct[yyj]
		if yyChk[yystate] != -yyn {
			yystate = yyAct[yyg]
		}
	}
	// dummy call; replaced with literal code
	switch yynt {

	case 5:
		//line parser.y:74
		{
			yylex.(*RulesLexer).parsedExpr = yyS[yypt-0].ruleNode
		}
	case 6:
		//line parser.y:79
		{
			rule, err := CreateRecordingRule(yyS[yypt-3].str, yyS[yypt-2].labelSet, yyS[yypt-0].ruleNode, yyS[yypt-4].boolean)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
			yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
		}
	case 7:
		//line parser.y:85
		{
			rule, err := CreateAlertingRule(yyS[yypt-9].str, yyS[yypt-7].ruleNode, yyS[yypt-6].str, yyS[yypt-4].labelSet, yyS[yypt-2].str, yyS[yypt-0].str)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
			yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
		}
	case 8:
		//line parser.y:93
		{
			yyVAL.str = "0s"
		}
	case 9:
		//line parser.y:95
		{
			yyVAL.str = yyS[yypt-0].str
		}
	case 10:
		//line parser.y:99
		{
			yyVAL.boolean = false
		}
	case 11:
		//line parser.y:101
		{
			yyVAL.boolean = true
		}
	case 12:
		//line parser.y:105
		{
			yyVAL.str = yyS[yypt-0].str
		}
	case 13:
		//line parser.y:107
		{
			yyVAL.str = yyS[yypt-0].str
		}
	case 14:
		//line parser.y:111
		{
			yyVAL.labelSet = clientmodel.LabelSet{}
		}
	case 15:
		//line parser.y:113
		{
			yyVAL.labelSet = yyS[yypt-1].labelSet
		}
	case 16:
		//line parser.y:115
		{
			yyVAL.labelSet = clientmodel.LabelSet{}
		}
	case 17:
		//line parser.y:118
		{
			yyVAL.labelSet = yyS[yypt-0].labelSet
		}
	case 18:
		//line parser.y:120
		{
			for k, v := range yyS[yypt-0].labelSet {
				yyVAL.labelSet[k] = v
			}
		}
	case 19:
		//line parser.y:124
		{
			yyVAL.labelSet = clientmodel.LabelSet{clientmodel.LabelName(yyS[yypt-2].str): clientmodel.LabelValue(yyS[yypt-0].str)}
		}
	case 20:
		//line parser.y:128
		{
			yyVAL.labelMatchers = metric.LabelMatchers{}
		}
	case 21:
		//line parser.y:130
		{
			yyVAL.labelMatchers = metric.LabelMatchers{}
		}
	case 22:
		//line parser.y:132
		{
			yyVAL.labelMatchers = yyS[yypt-1].labelMatchers
		}
	case 23:
		//line parser.y:136
		{
			yyVAL.labelMatchers = metric.LabelMatchers{yyS[yypt-0].labelMatcher}
		}
	case 24:
		//line parser.y:138
		{
			yyVAL.labelMatchers = append(yyVAL.labelMatchers, yyS[yypt-0].labelMatcher)
		}
	case 25:
		//line parser.y:142
		{
			var err error
			yyVAL.labelMatcher, err = newLabelMatcher(yyS[yypt-1].str, clientmodel.LabelName(yyS[yypt-2].str), clientmodel.LabelValue(yyS[yypt-0].str))
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 26:
		//line parser.y:150
		{
			yyVAL.str = "="
		}
	case 27:
		//line parser.y:152
		{
			yyVAL.str = yyS[yypt-0].str
		}
	case 28:
		//line parser.y:156
		{
			yyVAL.ruleNode = yyS[yypt-1].ruleNode
		}
	case 29:
		//line parser.y:158
		{
			var err error
			m, err := metric.NewLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, clientmodel.LabelValue(yyS[yypt-1].str))
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
			yyS[yypt-0].labelMatchers = append(yyS[yypt-0].labelMatchers, m)
			yyVAL.ruleNode = ast.NewVectorSelector(yyS[yypt-0].labelMatchers)
		}
	case 30:
		//line parser.y:166
		{
			var err error
			yyVAL.ruleNode, err = NewFunctionCall(yyS[yypt-3].str, yyS[yypt-1].ruleNodeSlice)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 31:
		//line parser.y:172
		{
			var err error
			yyVAL.ruleNode, err = NewFunctionCall(yyS[yypt-2].str, []ast.Node{})
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 32:
		//line parser.y:178
		{
			var err error
			yyVAL.ruleNode, err = NewMatrixSelector(yyS[yypt-3].ruleNode, yyS[yypt-1].str)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 33:
		//line parser.y:184
		{
			var err error
			yyVAL.ruleNode, err = NewVectorAggregation(yyS[yypt-5].str, yyS[yypt-3].ruleNode, yyS[yypt-1].labelNameSlice, yyS[yypt-0].boolean)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 34:
		//line parser.y:192
		{
			var err error
			yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 35:
		//line parser.y:198
		{
			var err error
			yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 36:
		//line parser.y:204
		{
			var err error
			yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
			if err != nil {
				yylex.Error(err.Error())
				return 1
			}
		}
	case 37:
		//line parser.y:210
		{
			yyVAL.ruleNode = ast.NewScalarLiteral(yyS[yypt-0].num)
		}
	case 38:
		//line parser.y:214
		{
			yyVAL.boolean = false
		}
	case 39:
		//line parser.y:216
		{
			yyVAL.boolean = true
		}
	case 40:
		//line parser.y:220
		{
			yyVAL.labelNameSlice = clientmodel.LabelNames{}
		}
	case 41:
		//line parser.y:222
		{
			yyVAL.labelNameSlice = yyS[yypt-1].labelNameSlice
		}
	case 42:
		//line parser.y:226
		{
			yyVAL.labelNameSlice = clientmodel.LabelNames{clientmodel.LabelName(yyS[yypt-0].str)}
		}
	case 43:
		//line parser.y:228
		{
			yyVAL.labelNameSlice = append(yyVAL.labelNameSlice, clientmodel.LabelName(yyS[yypt-0].str))
		}
	case 44:
		//line parser.y:232
		{
			yyVAL.ruleNodeSlice = []ast.Node{yyS[yypt-0].ruleNode}
		}
	case 45:
		//line parser.y:234
		{
			yyVAL.ruleNodeSlice = append(yyVAL.ruleNodeSlice, yyS[yypt-0].ruleNode)
		}
	case 46:
		//line parser.y:238
		{
			yyVAL.ruleNode = yyS[yypt-0].ruleNode
		}
	case 47:
		//line parser.y:240
		{
			yyVAL.ruleNode = ast.NewStringLiteral(yyS[yypt-0].str)
		}
	}
	goto yystack /* stack new state and value */
}