예제 #1
0
파일: main.go 프로젝트: bytedance/bosun
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))
}
예제 #2
0
파일: main.go 프로젝트: rajder/bosun
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))
}
예제 #3
0
파일: main.go 프로젝트: eswdd/bosun
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)
	}
}