Exemplo n.º 1
0
func (c ping_collector) CollectOnce() newcore.CollectResult {
	var (
		md       newcore.MultiDataPoint
		d        stats.Stats
		p        = fastping.NewPinger()
		rtt_chan = make(chan float64)
	)

	ip, err := net.ResolveIPAddr("ip4:icmp", c.config.Target)
	if err != nil {
		logging.Errorf("ping_collector: DNS resolve error: %v", err)
		return newcore.CollectResult{
			Collected: nil,
			Next:      time.Now().Add(c.interval),
			Err:       fmt.Errorf("ping_collector: DNS resolve error: %v", err),
		}
	}

	p.MaxRTT = c.timeout
	p.AddIPAddr(ip)
	p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
		rtt_chan <- float64(rtt.Nanoseconds() / 1000 / 1000)
	}

	go func() {
		for i := 0; i < c.config.Packets; i++ {
			err = p.Run()
			if err != nil {
				logging.Errorf("ping_collector run err: ", err)
			}
		}
		close(rtt_chan)
	}()

	for rtt := range rtt_chan {
		d.Update(rtt)
	}

	md = append(md, newcore.NewDP(c.prefix, fmt.Sprintf("%s.%s", c.config.Metric, "time_min"), d.Min(), c.tags, "", "", ""))
	md = append(md, newcore.NewDP(c.prefix, fmt.Sprintf("%s.%s", c.config.Metric, "time_max"), d.Max(), c.tags, "", "", ""))
	md = append(md, newcore.NewDP(c.prefix, fmt.Sprintf("%s.%s", c.config.Metric, "time_avg"), d.Mean(), c.tags, "", "", ""))

	std := d.SampleStandardDeviation()
	if math.IsNaN(std) {
		std = 0
	}
	md = append(md, newcore.NewDP(c.prefix, fmt.Sprintf("%s.%s", c.config.Metric, "time_mdev"), std, c.tags, "", "", ""))
	md = append(md, newcore.NewDP(c.prefix, fmt.Sprintf("%s.%s", c.config.Metric, "ip"), ip.IP.String(), c.tags, "", "", ""))

	lost_pct := float64((c.config.Packets-d.Count())/c.config.Packets) * 100
	md = append(md, newcore.NewDP(c.prefix, fmt.Sprintf("%s.%s", c.config.Metric, "lost_pct"), lost_pct, c.tags, "", "", ""))

	return newcore.CollectResult{
		Collected: md,
		Next:      time.Now().Add(c.interval),
		Err:       nil,
	}
}
Exemplo n.º 2
0
func handleExecuteQuery(rw http.ResponseWriter, req *http.Request) {
	startTime := time.Now()

	db, err := sql.Open("sqlite3", *dataSrc)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
		return
	}
	defer db.Close()

	var (
		request struct {
			Features    map[string]float64 `json:"features"`
			Geo         *geoData           `json:"geo"`
			MaxResults  int                `json:"maxResults"`
			MinScore    float64            `json:"minScore"`
			Modes       map[string]string  `json:"modes"`
			Profile     map[string]float64 `json:"profile"`
			Resolution  int                `json:"resolution"`
			SortAsc     bool               `json:"sortAsc"`
			SortKey     string             `json:"sortKey"`
			WalkingDist float64            `json:"walkingDist"`
		}

		response struct {
			Columns     map[string]*column `json:"columns"`
			Count       int                `json:"count"`
			MinScore    float64            `json:"minScore"`
			Records     []record           `json:"records"`
			ElapsedTime int64              `json:"elapsedTime"`
		}
	)

	if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
		return
	}

	var geo *geoData
	if request.Geo != nil {
		geo = &geoData{request.Geo.Latitude, request.Geo.Longitude}
	}

	allEntries, err := fetchRecords(db, queryContext{geo, request.Profile, request.WalkingDist})
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
		return
	}

	features := fixFeatures(request.Features)
	modes := fixModes(request.Modes)

	matchedEntries := findRecords(allEntries, features, modes, request.MinScore)
	sorter := recordSorter{entries: matchedEntries, key: request.SortKey, ascending: request.SortAsc}
	sorter.sort()

	var wg sync.WaitGroup
	wg.Add(len(features))

	response.Columns = make(map[string]*column)
	for name := range features {
		response.Columns[name] = new(column)

		go func(name string) {
			defer wg.Done()

			col := response.Columns[name]

			col.Bracket = bracket{Max: -1.0, Min: 1.0}
			col.Hints = project(allEntries, features, modes, name, request.MinScore, request.Resolution)
			col.Mode = modes[name].String()
			col.Steps = request.Resolution
			col.Value = features[name]

			var d stats.Stats
			for _, record := range matchedEntries {
				if feature, ok := record.features[name]; ok {
					d.Update(feature)
				}
			}

			if d.Count() > 0 {
				var dev float64
				if d.Count() > 1 {
					dev = d.SampleStandardDeviation() * 3
				}

				mean := d.Mean()

				col.Bracket.Max = math.Min(mean+dev, d.Max())
				col.Bracket.Min = math.Max(mean-dev, d.Min())
			}
		}(name)
	}

	wg.Wait()

	response.Count = len(matchedEntries)
	response.MinScore = request.MinScore
	response.ElapsedTime = time.Since(startTime).Nanoseconds()

	if len(matchedEntries) > request.MaxResults {
		response.Records = matchedEntries[:request.MaxResults]
	} else {
		response.Records = matchedEntries
	}

	js, err := json.Marshal(response)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
		return
	}

	rw.Header().Set("Content-Type", "application/json")
	rw.Write(js)
}