func init() { if client, err := db.Client(); err != nil { glog.Errorln(err) } else { defer db.Release(client) { if len(config.Cfg.Metrics.AddScript) > 0 { if addSha, err = client.Cmd("SCRIPT", "LOAD", config.Cfg.Metrics.AddScript).Str(); err != nil { glog.Errorln(err) } else { glog.Infoln("ADD SHA", addSha) } } if len(config.Cfg.Metrics.GetScript) > 0 { if getSha, err = client.Cmd("SCRIPT", "LOAD", config.Cfg.Metrics.GetScript).Str(); err != nil { glog.Errorln(err) } else { glog.Infoln("GET SHA", getSha) } } if len(config.Cfg.Metrics.TtlScript) > 0 { if ttlSha, err = client.Cmd("SCRIPT", "LOAD", config.Cfg.Metrics.TtlScript).Str(); err != nil { glog.Errorln(err) } else { glog.Infoln("TTL SHA", ttlSha) } } } } }
/* * Get queries for metrics which matches to the key pattern (e.g.: status.*) * * [ * {"target": "status.200", "datapoints": [[1720.0, 1370846820], ...], }, * {"target": "status.204", "datapoints": [[1.0, 1370846820], ..., ]} * ] */ func Get(key string, from int64, to int64, maxDataPoints int) (ms []*Metrics) { var js []byte var data []map[string]interface{} if client, err := db.Client(); err != nil { glog.Errorln(err) } else { defer db.Release(client) if js, err = client.Cmd("EVALSHA", getSha, 1, key, from, to).Bytes(); err != nil { glog.Warningln(err) if js, err = client.Cmd("EVAL", config.Cfg.Metrics.GetScript, 1, key, from, to).Bytes(); err != nil { glog.Errorln(err) } } if err = json.Unmarshal(js, &data); err != nil { glog.Errorln(err) } } for _, d := range data { m := new(Metrics) m.Key = key if target, ok := d["target"].(string); ok { m.Target = target } datapoints, ok := d["datapoints"].([]interface{}) if !ok { datapoints = make([]interface{}, 0) } if config.Cfg.Metrics.ConsolidationStep < 1 || len(config.Cfg.Metrics.ConsolidationFunc) < 1 { for _, dp := range datapoints { if pt := makePt(dp); pt[1] != nil { m.Datapoints = append(m.Datapoints, pt) } } } else { step := consolidationStep(from, to, config.Cfg.Metrics.ConsolidationStep, maxDataPoints) m.Datapoints = consolidateBy(datapoints, from, to, step, config.Cfg.Metrics.ConsolidationFunc) } ms = append(ms, m) } return }
func Add(key string, value string, timestamp int64) { if client, err := db.Client(); err != nil { glog.Errorln(err) } else { defer db.Release(client) if r := client.Cmd("EVALSHA", addSha, 1, key, value, timestamp); r.Err != nil { glog.Warningln(r.Err) if r = client.Cmd("EVAL", config.Cfg.Metrics.AddScript, 1, key, value, timestamp); r.Err != nil { glog.Errorln(r.Err) } } else { glog.Infof("[OK: %v]\t(%s %s)|%d", r, key, value, timestamp) } } }
func init() { // Max log file size - rotate log file if exceed 10MB glog.MaxSize = 10 * 1024 * 1024 var f = flag.String("f", "config.json", "read configuration from file") flag.StringVar(&Pprof.Cpu, "cpuprofile", "", "write cpu profile to file") flag.StringVar(&Pprof.Mem, "memprofile", "", "write memory profile to this file") flag.Parse() if cfg, err := ioutil.ReadFile(*f); err != nil { glog.Errorln(err) return } else { if err := json.Unmarshal(cfg, &Cfg); err != nil { glog.Fatal(err) } glog.Infof("%v", string(cfg)) } dir := filepath.Dir(*f) + "/" if script, err := ioutil.ReadFile(dir + Cfg.Metrics.AddScript); err != nil { glog.Errorln(err) Cfg.Metrics.AddScript = "" } else { Cfg.Metrics.AddScript = string(script) } if script, err := ioutil.ReadFile(dir + Cfg.Metrics.GetScript); err != nil { glog.Errorln(err) Cfg.Metrics.GetScript = "" } else { Cfg.Metrics.GetScript = string(script) } if script, err := ioutil.ReadFile(dir + Cfg.Metrics.TtlScript); err != nil { glog.Errorln(err) Cfg.Metrics.TtlScript = "" } else { Cfg.Metrics.TtlScript = string(script) } }
func Ttl(from int64, to int64) { if client, err := db.Client(); err != nil { glog.Errorln(err) } else { t0 := time.Now() defer db.Release(client) if r := client.Cmd("EVALSHA", ttlSha, 1, "*", from, to); r.Err != nil { glog.Warningln(r.Err) if r = client.Cmd("EVAL", config.Cfg.Metrics.TtlScript, 1, "*", from, to); r.Err != nil { glog.Errorln(r.Err) } } else { t1 := time.Now() glog.Infof("ZREMRANGEBYSCORE(%d, %d): %v in %v", from, to, r, t1.Sub(t0)) } } }
func main() { if config.Pprof.Cpu != "" { // Start Cpu Profiler f, err := os.Create(config.Pprof.Cpu) if err != nil { glog.Fatal(err) } defer f.Close() pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } ln, err := net.Listen("tcp", config.Cfg.Listener.Addr) if err != nil { glog.Fatalln(err) } glog.Infoln("ListenAndServe", config.Cfg.Listener.Addr) go func() { for { conn, err := ln.Accept() if err != nil { glog.Errorln(err) continue } go handle(conn) } }() // Handle SIGINT and SIGTERM. sig := make(chan os.Signal) signal.Notify(sig, os.Interrupt, os.Kill) glog.Errorf("Syscall: %v - Exit\n", <-sig) if config.Pprof.Mem != "" { // Start Mem Profiler f, err := os.Create(config.Pprof.Mem) if err != nil { glog.Fatal(err) } pprof.WriteHeapProfile(f) f.Close() } }
// Handle TCP Connections func handle(conn net.Conn) { glog.Infof("Connection: %s -> %s\n", conn.RemoteAddr(), conn.LocalAddr()) defer func() { glog.Infof("Closing connection: %s\n", conn.RemoteAddr()) conn.Close() glog.Flush() }() scanner := bufio.NewScanner(conn) for scanner.Scan() { if m := strings.Split(scanner.Text(), " "); len(m) > 2 { if ts, err := strconv.ParseInt(m[2], 10, 0); err != nil { glog.Warningln(err) continue } else { metrics.Add(m[0], m[1], ts) } } } if err := scanner.Err(); err != nil { glog.Errorln(err) } }