alertmanager/provider/sql.go

176 lines
3.4 KiB
Go
Raw Normal View History

2015-10-06 09:41:34 +00:00
package provider
import (
"database/sql"
"encoding/json"
"github.com/cznic/ql"
"github.com/prometheus/common/model"
"github.com/prometheus/alertmanager/types"
)
func init() {
ql.RegisterDriver()
}
type SQLSilences struct {
db *sql.DB
}
func (s *SQLSilences) Close() error {
return s.db.Close()
}
2015-10-06 10:36:33 +00:00
func NewSQLSilences(file string) (*SQLSilences, error) {
db, err := sql.Open("ql", file)
2015-10-06 09:41:34 +00:00
if err != nil {
return nil, err
}
tx, err := db.Begin()
if err != nil {
return nil, err
}
if _, err := tx.Exec(createSilencesTable); err != nil {
tx.Rollback()
return nil, err
}
tx.Commit()
return &SQLSilences{db: db}, nil
}
const createSilencesTable = `
CREATE TABLE IF NOT EXISTS silences (
matchers string,
2015-10-06 10:10:42 +00:00
starts_at time,
2015-10-06 09:41:34 +00:00
ends_at time,
created_at time,
created_by string,
comment string
);
CREATE INDEX IF NOT EXISTS silences_start ON silences (starts_at);
CREATE INDEX IF NOT EXISTS silences_end ON silences (ends_at);
CREATE INDEX IF NOT EXISTS silences_id ON silences (id());
2015-10-06 09:41:34 +00:00
`
func (s *SQLSilences) Mutes(lset model.LabelSet) bool {
sils, err := s.All()
if err != nil {
log.Errorf("retrieving silences failed: %s", err)
// In doubt, do not silence anything.
return false
}
for _, sil := range sils {
if sil.Mutes(lset) {
return true
}
}
2015-10-06 09:41:34 +00:00
return false
}
func (s *SQLSilences) All() ([]*types.Silence, error) {
2015-10-06 10:10:42 +00:00
rows, err := s.db.Query(`SELECT id(), matchers, starts_at, ends_at, created_at, created_by, comment FROM silences ORDER BY starts_at DESC`)
2015-10-06 09:41:34 +00:00
if err != nil {
return nil, err
}
defer rows.Close()
var silences []*types.Silence
for rows.Next() {
var (
sil model.Silence
2015-10-06 10:10:42 +00:00
matchers string
2015-10-06 09:41:34 +00:00
)
2015-10-06 10:10:42 +00:00
if err := rows.Scan(&sil.ID, &matchers, &sil.StartsAt, &sil.EndsAt, &sil.CreatedAt, &sil.CreatedBy, &sil.Comment); err != nil {
2015-10-06 09:41:34 +00:00
return nil, err
}
if err := json.Unmarshal([]byte(matchers), &sil.Matchers); err != nil {
return nil, err
}
silences = append(silences, types.NewSilence(&sil))
2015-10-06 09:41:34 +00:00
}
if err := rows.Err(); err != nil {
return nil, err
}
return silences, nil
}
func (s *SQLSilences) Set(sil *types.Silence) (uint64, error) {
mb, err := json.Marshal(sil.Silence.Matchers)
2015-10-06 09:41:34 +00:00
if err != nil {
return 0, err
}
tx, err := s.db.Begin()
if err != nil {
return 0, err
}
2015-10-06 10:10:42 +00:00
res, err := tx.Exec(`INSERT INTO silences VALUES ($1, $2, $3, $4, $5, $6)`,
2015-10-06 09:41:34 +00:00
string(mb),
sil.StartsAt,
sil.EndsAt,
2015-10-06 10:10:42 +00:00
sil.CreatedAt,
2015-10-06 09:41:34 +00:00
sil.CreatedBy,
sil.Comment,
)
if err != nil {
tx.Rollback()
return 0, err
}
sid, err := res.LastInsertId()
if err != nil {
tx.Rollback()
return 0, err
}
tx.Commit()
return uint64(sid), nil
}
func (s *SQLSilences) Del(sid uint64) error {
tx, err := s.db.Begin()
if err != nil {
return err
}
if _, err := tx.Exec(`DELETE FROM silences WHERE id() == $1`, sid); err != nil {
tx.Rollback()
return err
}
tx.Commit()
2015-10-06 09:41:34 +00:00
return nil
}
func (s *SQLSilences) Get(sid uint64) (*types.Silence, error) {
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 string
)
err := row.Scan(&sil.ID, &matchers, &sil.StartsAt, &sil.EndsAt, &sil.CreatedAt, &sil.CreatedBy, &sil.Comment)
if err == sql.ErrNoRows {
return nil, ErrNotFound
}
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(matchers), &sil.Matchers); err != nil {
return nil, err
}
return types.NewSilence(&sil), nil
2015-10-06 09:41:34 +00:00
}