func (s *Schedule) save() { if s.db == nil { return } s.Lock("Save") store := map[string]interface{}{ dbMetric: s.Search.Read.Metric, dbTagk: s.Search.Read.Tagk, dbTagv: s.Search.Read.Tagv, dbMetricTags: s.Search.Read.MetricTags, dbNotifications: s.Notifications, dbSilence: s.Silence, dbStatus: s.status, dbMetadata: s.Metadata, dbIncidents: s.Incidents, } tostore := make(map[string][]byte) for name, data := range store { f := new(bytes.Buffer) gz := gzip.NewWriter(f) cw := &counterWriter{w: gz} enc := gob.NewEncoder(cw) if err := enc.Encode(data); err != nil { slog.Errorf("error saving %s: %v", name, err) s.Unlock() return } if err := gz.Flush(); err != nil { slog.Errorf("gzip flush error saving %s: %v", name, err) } if err := gz.Close(); err != nil { slog.Errorf("gzip close error saving %s: %v", name, err) } tostore[name] = f.Bytes() slog.Infof("wrote %s: %v", name, conf.ByteSize(cw.written)) collect.Put("statefile.size", opentsdb.TagSet{"object": name}, cw.written) } s.Unlock() err := s.db.Update(func(tx *bolt.Tx) error { b, err := tx.CreateBucketIfNotExists([]byte(dbBucket)) if err != nil { return err } for name, data := range tostore { if err := b.Put([]byte(name), data); err != nil { return err } } return nil }) if err != nil { slog.Errorf("save db update error: %v", err) return } fi, err := os.Stat(s.Conf.StateFile) if err == nil { collect.Put("statefile.size", opentsdb.TagSet{"object": "total"}, fi.Size()) } slog.Infoln("save to db complete") }
c.Macros[name] = &m } // Note: Funcs that can error should return a pointer. In the error case the pointer // should be non-nil. The exception to this is when a string is returned, in which case // the string format of the error should be returned. This allows for error handling within // templates for information that is helpful but not stricly necessary var defaultFuncs = ttemplate.FuncMap{ "bytes": func(v interface{}) string { switch v := v.(type) { case string: f, err := strconv.ParseFloat(v, 64) if err != nil { return err.Error() } return conf.ByteSize(f).String() case int: return conf.ByteSize(v).String() case float64: return conf.ByteSize(v).String() case expr.Number: return conf.ByteSize(v).String() case expr.Scalar: return conf.ByteSize(v).String() } return fmt.Errorf("unexpected type passed to bytes function: %T (%v)", v, v).Error() }, "pct": func(i interface{}) string { return fmt.Sprintf("%.2f%%", i) }, "replace": strings.Replace,
for _, p := range pairs { if _, ok := m.Pairs.([]nodePair); !ok { //bad m.Pairs = []nodePair{} } m.Pairs = append(m.Pairs.([]nodePair), p) // bad } c.at(s) c.Macros[name] = &m } var defaultFuncs = ttemplate.FuncMap{ "bytes": func(v interface{}) (conf.ByteSize, error) { switch v := v.(type) { case string: f, err := strconv.ParseFloat(v, 64) return conf.ByteSize(f), err case int: return conf.ByteSize(v), nil case float64: return conf.ByteSize(v), nil case expr.Number: return conf.ByteSize(v), nil case expr.Scalar: return conf.ByteSize(v), nil } return conf.ByteSize(0), fmt.Errorf("unexpected type: %T (%v)", v, v) }, "pct": func(i interface{}) string { return fmt.Sprintf("%.2f%%", i) }, "replace": strings.Replace,