func migrateTagMetadata(db *bolt.DB, data database.DataAccess) error { migrated, err := isMigrated(db, "metadata") if err != nil { return err } if !migrated { slog.Info("Migrating metadata to new database format") type Metavalue struct { Time time.Time Value interface{} } metadata := make(map[metadata.Metakey]*Metavalue) if err := decode(db, "metadata", &metadata); err == nil { for k, v := range metadata { err = data.Metadata().PutTagMetadata(k.TagSet(), k.Name, fmt.Sprint(v.Value), v.Time) if err != nil { return err } } err = deleteKey(db, "metadata") if err != nil { return err } } err = setMigrated(db, "metadata") if err != nil { return err } } return nil }
func migrateIncidents(db *bolt.DB, data database.DataAccess) error { migrated, err := isMigrated(db, "incidents") if err != nil { return err } if migrated { return nil } slog.Info("migrating incidents") incidents := map[uint64]*models.Incident{} if err := decode(db, "incidents", &incidents); err != nil { return err } max := uint64(0) for k, v := range incidents { data.Incidents().UpdateIncident(k, v) if k > max { max = k } } if err = data.Incidents().SetMaxId(max); err != nil { return err } if err = setMigrated(db, "incidents"); err != nil { return err } return nil }
func migrateSearch(db *bolt.DB, data database.DataAccess) error { migrated, err := isMigrated(db, "search") if err != nil { return err } if !migrated { slog.Info("Migrating Search data to new database format") type duple struct{ A, B string } type present map[string]int64 type qmap map[duple]present type smap map[string]present metric := qmap{} if err := decode(db, "metric", &metric); err == nil { for k, v := range metric { for metric, time := range v { data.Search().AddMetricForTag(k.A, k.B, metric, time) } } } else { return err } tagk := smap{} if err := decode(db, "tagk", &tagk); err == nil { for metric, v := range tagk { for tk, time := range v { data.Search().AddTagKeyForMetric(metric, tk, time) } data.Search().AddMetric(metric, time.Now().Unix()) } } else { return err } tagv := qmap{} if err := decode(db, "tagv", &tagv); err == nil { for k, v := range tagv { for val, time := range v { data.Search().AddTagValue(k.A, k.B, val, time) data.Search().AddTagValue(database.Search_All, k.B, val, time) } } } else { return err } err = setMigrated(db, "search") if err != nil { return err } } return nil }
func migrateSilence(db *bolt.DB, data database.DataAccess) error { migrated, err := isMigrated(db, "silence") if err != nil { return err } if migrated { return nil } slog.Info("migrating silence") silence := map[string]*models.Silence{} if err := decode(db, "silence", &silence); err != nil { return err } for _, v := range silence { v.TagString = v.Tags.Tags() data.Silence().AddSilence(v) } if err = setMigrated(db, "silence"); err != nil { return err } return nil }
func migrateMetricMetadata(db *bolt.DB, data database.DataAccess) error { migrated, err := isMigrated(db, "metadata-metric") if err != nil { return err } if !migrated { slog.Info("Migrating metric metadata to new database format") type MetadataMetric struct { Unit string `json:",omitempty"` Type string `json:",omitempty"` Description string } mms := map[string]*MetadataMetric{} if err := decode(db, "metadata-metric", &mms); err == nil { for name, mm := range mms { if mm.Description != "" { err = data.Metadata().PutMetricMetadata(name, "desc", mm.Description) if err != nil { return err } } if mm.Unit != "" { err = data.Metadata().PutMetricMetadata(name, "unit", mm.Unit) if err != nil { return err } } if mm.Type != "" { err = data.Metadata().PutMetricMetadata(name, "rate", mm.Type) if err != nil { return err } } } err = setMigrated(db, "metadata-metric") if err != nil { return err } } } return nil }
func migrateOldDataToRedis(db *bolt.DB, data database.DataAccess) error { // metadata-metric migrated, err := isMigrated(db, "metadata-metric") if err != nil { return err } if !migrated { type MetadataMetric struct { Unit string `json:",omitempty"` Type string `json:",omitempty"` Description string } slog.Info("Migrating metric metadata to new database format") mms := map[string]*MetadataMetric{} if err := decode(db, "metadata-metric", &mms); err == nil { for name, mm := range mms { if mm.Description != "" { err = data.PutMetricMetadata(name, "desc", mm.Description) if err != nil { return err } } if mm.Unit != "" { err = data.PutMetricMetadata(name, "unit", mm.Unit) if err != nil { return err } } if mm.Type != "" { err = data.PutMetricMetadata(name, "rate", mm.Type) if err != nil { return err } } } err = setMigrated(db, "metadata-metric") if err != nil { return err } } } //metadata migrated, err = isMigrated(db, "metadata") if err != nil { return err } if !migrated { slog.Info("Migrating metadata to new database format") type Metavalue struct { Time time.Time Value interface{} } metadata := make(map[metadata.Metakey]*Metavalue) if err := decode(db, "metadata", &metadata); err == nil { for k, v := range metadata { err = data.PutTagMetadata(k.TagSet(), k.Name, fmt.Sprint(v.Value), v.Time) if err != nil { return err } } err = deleteKey(db, "metadata") if err != nil { return err } } err = setMigrated(db, "metadata") if err != nil { return err } } return nil }
func migrateState(db *bolt.DB, data database.DataAccess) error { migrated, err := isMigrated(db, "state") if err != nil { return err } if migrated { return nil } //redefine the structs as they were when we gob encoded them type Result struct { *expr.Result Expr string } mResult := func(r *Result) *models.Result { if r == nil || r.Result == nil { return &models.Result{} } v, _ := valueToFloat(r.Result.Value) return &models.Result{ Computations: r.Result.Computations, Value: models.Float(v), Expr: r.Expr, } } type Event struct { Warn, Crit *Result Status models.Status Time time.Time Unevaluated bool IncidentId uint64 } type State struct { *Result History []Event Actions []models.Action Touched time.Time Alert string Tags string Group opentsdb.TagSet Subject string Body string EmailBody []byte EmailSubject []byte Attachments []*models.Attachment NeedAck bool Open bool Forgotten bool Unevaluated bool LastLogTime time.Time } type OldStates map[models.AlertKey]*State slog.Info("migrating state") states := OldStates{} if err := decode(db, "status", &states); err != nil { return err } for ak, state := range states { if len(state.History) == 0 { continue } var thisId uint64 events := []Event{} addIncident := func(saveBody bool) error { if thisId == 0 || len(events) == 0 || state == nil { return nil } incident := NewIncident(ak) incident.Expr = state.Expr incident.NeedAck = state.NeedAck incident.Open = state.Open incident.Result = mResult(state.Result) incident.Unevaluated = state.Unevaluated incident.Start = events[0].Time incident.Id = int64(thisId) incident.Subject = state.Subject if saveBody { incident.Body = state.Body } for _, ev := range events { incident.CurrentStatus = ev.Status mEvent := models.Event{ Crit: mResult(ev.Crit), Status: ev.Status, Time: ev.Time, Unevaluated: ev.Unevaluated, Warn: mResult(ev.Warn), } incident.Events = append(incident.Events, mEvent) if ev.Status > incident.WorstStatus { incident.WorstStatus = ev.Status } if ev.Status > models.StNormal { incident.LastAbnormalStatus = ev.Status incident.LastAbnormalTime = ev.Time.UTC().Unix() } } for _, ac := range state.Actions { if ac.Time.Before(incident.Start) { continue } incident.Actions = append(incident.Actions, ac) if ac.Time.After(incident.Events[len(incident.Events)-1].Time) && ac.Type == models.ActionClose { incident.End = &ac.Time break } } if err := data.State().ImportIncidentState(incident); err != nil { return err } return nil } //essentially a rle algorithm to assign events to incidents for _, e := range state.History { if e.Status > models.StUnknown { continue } if e.IncidentId == 0 { //include all non-assigned incidents up to the next non-match events = append(events, e) continue } if thisId == 0 { thisId = e.IncidentId events = append(events, e) } if e.IncidentId != thisId { if err := addIncident(false); err != nil { return err } thisId = e.IncidentId events = []Event{e} } else { events = append(events, e) } } if err := addIncident(true); err != nil { return err } } if err = setMigrated(db, "state"); err != nil { return err } return nil }