예제 #1
0
// All returns all existing silences.
func (s *Silences) All() ([]*types.Silence, error) {
	var res []*types.Silence

	err := s.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bktSilences)
		c := b.Cursor()

		for k, v := c.First(); k != nil; k, v = c.Next() {
			var ms model.Silence
			if err := json.Unmarshal(v, &ms); err != nil {
				return err
			}
			ms.ID = binary.BigEndian.Uint64(k)

			if err := json.Unmarshal(v, &ms); err != nil {
				return err
			}

			res = append(res, types.NewSilence(&ms))
		}

		return nil
	})

	return res, err
}
예제 #2
0
// Get implements the Silences interface.
func (s *Silences) Get(sid uint64) (*types.Silence, error) {
	dbmtx.Lock()
	defer dbmtx.Unlock()

	row := s.db.QueryRow(`
		SELECT id, matchers, starts_at, ends_at, created_at, created_by, comment
		FROM silences
		WHERE id == $1
	`, sid)

	var (
		sil      model.Silence
		matchers []byte
	)
	err := row.Scan(
		&sil.ID,
		&matchers,
		&sil.StartsAt,
		&sil.EndsAt,
		&sil.CreatedAt,
		&sil.CreatedBy,
		&sil.Comment,
	)
	if err == sql.ErrNoRows {
		return nil, provider.ErrNotFound
	}
	if err != nil {
		return nil, err
	}
	if err := json.Unmarshal(matchers, &sil.Matchers); err != nil {
		return nil, err
	}

	return types.NewSilence(&sil), nil
}
예제 #3
0
// Get implements the Silences interface.
func (s *MemSilences) Get(id uint64) (*types.Silence, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	sil, ok := s.silences[id]
	if !ok {
		return nil, ErrNotFound
	}
	return types.NewSilence(sil), nil
}
예제 #4
0
// All implements the Silences interface.
func (s *MemSilences) All() ([]*types.Silence, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	var sils []*types.Silence
	for _, sil := range s.silences {
		sils = append(sils, types.NewSilence(sil))
	}
	return sils, nil
}
예제 #5
0
// Mutes implements the Muter interface.
func (s *MemSilences) Mutes(lset model.LabelSet) bool {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	for _, sil := range s.silences {
		if types.NewSilence(sil).Mutes(lset) {
			return true
		}
	}
	return false
}
예제 #6
0
func TestSilencesSet(t *testing.T) {
	var (
		t0 = time.Now()
		t1 = t0.Add(10 * time.Minute)
		t2 = t0.Add(20 * time.Minute)
		// t3 = t0.Add(30 * time.Minute)
	)

	var cases = []struct {
		insert *types.Silence
	}{
		{
			insert: types.NewSilence(&model.Silence{
				Matchers: []*model.Matcher{
					{Name: "key", Value: "val"},
				},
				StartsAt:  t0,
				EndsAt:    t2,
				CreatedAt: t1,
				CreatedBy: "user",
				Comment:   "test comment",
			}),
		},
	}

	dir, err := ioutil.TempDir("", "silences_test")
	if err != nil {
		t.Fatal(err)
	}

	silences, err := NewSilences(dir, nil)
	if err != nil {
		t.Fatal(err)
	}

	for _, c := range cases {
		uid, err := silences.Set(c.insert)
		if err != nil {
			t.Fatalf("Insert failed: %s", err)
		}
		c.insert.ID = uid

		sil, err := silences.Get(uid)
		if err != nil {
			t.Fatalf("Getting failed: %s", err)
		}

		if silencesEqual(sil, c.insert) {
			t.Errorf("Unexpected silence")
			t.Fatalf(pretty.Compare(sil, c.insert))
		}
	}
}
예제 #7
0
// All implements the Silences interface.
func (s *Silences) All() ([]*types.Silence, error) {
	dbmtx.Lock()
	defer dbmtx.Unlock()

	rows, err := s.db.Query(`
		SELECT id, matchers, starts_at, ends_at, created_at, created_by, comment
		FROM silences 
		ORDER BY starts_at DESC
	`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var silences []*types.Silence

	for rows.Next() {
		var (
			sil      model.Silence
			matchers []byte
		)

		if err := rows.Scan(
			&sil.ID,
			&matchers,
			&sil.StartsAt,
			&sil.EndsAt,
			&sil.CreatedAt,
			&sil.CreatedBy,
			&sil.Comment,
		); err != nil {
			return nil, err
		}

		if err := json.Unmarshal(matchers, &sil.Matchers); err != nil {
			return nil, err
		}

		silences = append(silences, types.NewSilence(&sil))
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	return silences, nil
}
예제 #8
0
func (s *Silences) initCache() error {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	err := s.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bktSilences)
		c := b.Cursor()

		for k, v := c.First(); k != nil; k, v = c.Next() {
			var ms model.Silence
			if err := json.Unmarshal(v, &ms); err != nil {
				return err
			}
			// The ID is duplicated in the value and always equal
			// to the stored key.
			s.cache[ms.ID] = types.NewSilence(&ms)
		}

		return nil
	})
	return err
}
예제 #9
0
// Get a silence associated with a fingerprint.
func (s *Silences) Get(uid uint64) (*types.Silence, error) {
	var sil *types.Silence

	err := s.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bktSilences)

		k := make([]byte, 8)
		binary.BigEndian.PutUint64(k, uid)

		v := b.Get(k)
		if v == nil {
			return provider.ErrNotFound
		}
		var ms model.Silence

		if err := json.Unmarshal(v, &ms); err != nil {
			return err
		}
		sil = types.NewSilence(&ms)

		return nil
	})
	return sil, err
}
예제 #10
0
func TestSilencesMutes(t *testing.T) {
	var (
		t0 = time.Now()
		t1 = t0.Add(10 * time.Minute)
		t2 = t0.Add(20 * time.Minute)
		t3 = t0.Add(30 * time.Minute)
	)

	// All silences are active for the time of the test. Time restriction
	// testing is covered for the Mutes() method of the Silence type.
	insert := []*types.Silence{
		types.NewSilence(&model.Silence{
			Matchers: []*model.Matcher{
				{Name: "key", Value: "val"},
			},
			StartsAt:  t0,
			EndsAt:    t2,
			CreatedAt: t1,
			CreatedBy: "user",
			Comment:   "test comment",
		}),
		types.NewSilence(&model.Silence{
			Matchers: []*model.Matcher{
				{Name: "key2", Value: "val2.*", IsRegex: true},
			},
			StartsAt:  t0,
			EndsAt:    t2,
			CreatedAt: t1,
			CreatedBy: "user2",
			Comment:   "test comment",
		}),
		types.NewSilence(&model.Silence{
			Matchers: []*model.Matcher{
				{Name: "key", Value: "val2"},
			},
			StartsAt:  t0,
			EndsAt:    t3,
			CreatedAt: t3,
			CreatedBy: "user",
			Comment:   "another test comment",
		}),
	}

	dir, err := ioutil.TempDir("", "silences_test")
	if err != nil {
		t.Fatal(err)
	}

	silences, err := NewSilences(dir, types.NewMarker())
	if err != nil {
		t.Fatal(err)
	}

	for _, sil := range insert {
		uid, err := silences.Set(sil)
		if err != nil {
			t.Fatalf("Insert failed: %s", err)
		}
		sil.ID = uid
	}

	tests := []struct {
		lset  model.LabelSet
		match bool
	}{
		{
			lset: model.LabelSet{
				"foo": "bar",
				"bar": "foo",
			},
			match: false,
		},
		{
			lset: model.LabelSet{
				"key": "val",
				"bar": "foo",
			},
			match: true,
		},
		{
			lset: model.LabelSet{
				"foo": "bar",
				"key": "val2",
			},
			match: true,
		},
		{
			lset: model.LabelSet{
				"key2": "bar",
				"bar":  ":$foo",
			},
			match: false,
		},
		{
			lset: model.LabelSet{
				"key2": "val2",
				"bar":  "foo",
			},
			match: true,
		},
		{
			lset: model.LabelSet{
				"key2": "val2 foo",
				"bar":  "foo",
			},
			match: true,
		},
	}

	for i, test := range tests {
		if b := silences.Mutes(test.lset); b != test.match {
			t.Errorf("Unexpected mute result: %d", i)
			t.Fatalf("Expected %v, got %v", test.match, b)
		} else {
			if _, wasSilenced := silences.mk.Silenced(test.lset.Fingerprint()); wasSilenced != b {
				t.Fatalf("Marker was not set correctly: %d", i)
			}
		}
	}
}
예제 #11
0
func TestSilencesAll(t *testing.T) {
	var (
		t0 = time.Now()
		t1 = t0.Add(10 * time.Minute)
		t2 = t0.Add(20 * time.Minute)
		t3 = t0.Add(30 * time.Minute)
	)

	insert := []*types.Silence{
		types.NewSilence(&model.Silence{
			Matchers: []*model.Matcher{
				{Name: "key", Value: "val"},
			},
			StartsAt:  t0,
			EndsAt:    t2,
			CreatedAt: t1,
			CreatedBy: "user",
			Comment:   "test comment",
		}),
		types.NewSilence(&model.Silence{
			Matchers: []*model.Matcher{
				{Name: "key", Value: "val"},
				{Name: "key2", Value: "val2.*", IsRegex: true},
			},
			StartsAt:  t1,
			EndsAt:    t2,
			CreatedAt: t1,
			CreatedBy: "user2",
			Comment:   "test comment",
		}),
		types.NewSilence(&model.Silence{
			Matchers: []*model.Matcher{
				{Name: "key", Value: "val"},
			},
			StartsAt:  t2,
			EndsAt:    t3,
			CreatedAt: t3,
			CreatedBy: "user",
			Comment:   "another test comment",
		}),
	}

	dir, err := ioutil.TempDir("", "silences_test")
	if err != nil {
		t.Fatal(err)
	}

	silences, err := NewSilences(dir, nil)
	if err != nil {
		t.Fatal(err)
	}

	for _, sil := range insert {
		uid, err := silences.Set(sil)
		if err != nil {
			t.Fatalf("Insert failed: %s", err)
		}
		sil.ID = uid
	}

	res, err := silences.All()
	if err != nil {
		t.Fatalf("Retrieval failed: %s", err)
	}

	if silenceListEqual(res, insert) {
		t.Errorf("Unexpected result")
		t.Fatalf(pretty.Compare(res, insert))
	}
}