// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
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)) } } }
// 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 }
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 }
// 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 }
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) } } } }
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)) } }