func main() { flag.Parse() if *bosunServer == "" || *tsdbServer == "" { log.Fatal("must specify both bosun and tsdb server") } log.Println("listen on", *listenAddr) log.Println("relay to bosun at", *bosunServer) log.Println("relay to tsdb at", *tsdbServer) if *toDenormalize != "" { var err error denormalizationRules, err = denormalize.ParseDenormalizationRules(*toDenormalize) if err != nil { log.Fatal(err) } } runtime.GOMAXPROCS(runtime.NumCPU()) tsdbURL := &url.URL{ Scheme: "http", Host: *tsdbServer, } u := url.URL{ Scheme: "http", Host: *tsdbServer, Path: "/api/put", } tsdbPutURL = u.String() bosunURL := &url.URL{ Scheme: "http", Host: *bosunServer, } u = url.URL{ Scheme: "http", Host: *bosunServer, Path: "/api/index", } bosunIndexURL = u.String() tsdbProxy := httputil.NewSingleHostReverseProxy(tsdbURL) http.Handle("/api/put", &relayProxy{ ReverseProxy: tsdbProxy, }) http.Handle("/api/metadata/put", httputil.NewSingleHostReverseProxy(bosunURL)) http.Handle("/", tsdbProxy) log.Fatal(http.ListenAndServe(*listenAddr, nil)) }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) var err error myHost, err = os.Hostname() if err != nil || myHost == "" { myHost = "tsdbrelay" } flag.Parse() if *bosunServer == "" || *tsdbServer == "" { log.Fatal("must specify both bosun and tsdb server") } log.Println("listen on", *listenAddr) log.Println("relay to bosun at", *bosunServer) log.Println("relay to tsdb at", *tsdbServer) if *toDenormalize != "" { var err error denormalizationRules, err = denormalize.ParseDenormalizationRules(*toDenormalize) if err != nil { log.Fatal(err) } } tsdbURL := &url.URL{ Scheme: "http", Host: *tsdbServer, } u := url.URL{ Scheme: "http", Host: *tsdbServer, Path: "/api/put", } tsdbPutURL = u.String() bosunURL := &url.URL{ Scheme: "http", Host: *bosunServer, } u = url.URL{ Scheme: "http", Host: *bosunServer, Path: "/api/index", } bosunIndexURL = u.String() if *secondaryRelays != "" { for _, rUrl := range strings.Split(*secondaryRelays, ",") { u = url.URL{ Scheme: "http", Host: rUrl, Path: "/api/put", } relayPutUrls = append(relayPutUrls, u.String()) } } tsdbProxy := util.NewSingleHostProxy(tsdbURL) bosunProxy := util.NewSingleHostProxy(bosunURL) rp := &relayProxy{ TSDBProxy: tsdbProxy, BosunProxy: bosunProxy, } http.HandleFunc("/api/put", func(w http.ResponseWriter, r *http.Request) { rp.relayPut(w, r, true) }) http.HandleFunc("/api/metadata/put", func(w http.ResponseWriter, r *http.Request) { rp.relayMetadata(w, r) }) http.Handle("/", tsdbProxy) log.Fatal(http.ListenAndServe(*listenAddr, nil)) }
func main() { flag.Parse() if *tsdbHost == "" { flag.PrintDefaults() log.Fatal("host must be supplied") } putUrl := (&url.URL{Scheme: "http", Host: *tsdbHost, Path: "api/put"}).String() if *ruleFlag == "" { flag.PrintDefaults() log.Fatal("rule must be supplied") } rules, err := denormalize.ParseDenormalizationRules(*ruleFlag) if err != nil { log.Fatal(err) } if len(rules) > 1 { log.Fatal("Please specify only one rule") } var rule *denormalize.DenormalizationRule var metric string for k, v := range rules { metric = k rule = v } query := &opentsdb.Query{Metric: metric, Aggregator: "avg"} query.Tags, err = queryForAggregateTags(query) if err != nil { log.Fatal(err) } startDate, err := opentsdb.ParseTime(*start) if err != nil { log.Fatal(err) } endDate := time.Now().UTC() if *end != "" { endDate, err = opentsdb.ParseTime(*end) if err != nil { log.Fatal(err) } } backfill := func(batchStart, batchEnd time.Time) (err error) { startTimeString := batchStart.Format(opentsdb.TSDBTimeFormat) endTimeString := batchEnd.Format(opentsdb.TSDBTimeFormat) defer func() { if err != nil { log.Fatalf("Error on batch %s - %s. %v \n", startTimeString, endTimeString, err) } }() req := opentsdb.Request{Start: startTimeString, End: endTimeString, Queries: []*opentsdb.Query{query}} resp, err := req.Query(*tsdbHost) if err != nil { return err } dps := []*opentsdb.DataPoint{} for _, r := range resp { for t, p := range r.DPS { timeStamp, err := strconv.ParseInt(t, 10, 64) if err != nil { return err } dp := &opentsdb.DataPoint{ Timestamp: timeStamp, Metric: r.Metric, Tags: r.Tags, Value: p, } err = rule.Translate(dp) if err != nil { return err } dps = append(dps, dp) } } fmt.Printf("%s - %s: %d dps\n", startTimeString, endTimeString, len(dps)) total := 0 for len(dps) > 0 { count := len(dps) if len(dps) > *batchSize { count = *batchSize } putResp, err := collect.SendDataPoints(dps[:count], putUrl) if err != nil { return err } defer putResp.Body.Close() if putResp.StatusCode != 204 { return fmt.Errorf("Non 204 status code from opentsdb: %d", putResp.StatusCode) } dps = dps[count:] total += count } fmt.Printf("Relayed %d data points.\n", total) return nil } // walk backwards a day at a time curEnd := endDate for curEnd.After(startDate) { curStart := curEnd.Add(-24 * time.Hour) if curStart.Before(startDate) { curStart = startDate } backfill(curStart, curEnd) curEnd = curEnd.Add(-24 * time.Hour) } }