Exemple #1
0
func getHosts(w http.ResponseWriter, req *http.Request, hostKeyword string) {
	if len(hostKeyword) == 1 {
		hostKeyword = ".+"
	}
	rand.Seed(time.Now().UTC().UnixNano())
	random64 := rand.Float64()
	_r := strconv.FormatFloat(random64, 'f', -1, 32)
	maxQuery := strconv.Itoa(g.Config().Api.Max)
	url := "/api/endpoints" + "?q=" + hostKeyword + "&tags&limit=" + maxQuery + "&_r=" + _r + "&regex_query=1"
	if strings.Index(g.Config().Api.Query, req.Host) >= 0 {
		url = "http://localhost:9966" + url
	} else {
		url = g.Config().Api.Query + url
	}

	reqGet, err := http.NewRequest("GET", url, nil)
	if err != nil {
		StdRender(w, "", err)
	}

	client := &http.Client{}
	resp, err := client.Do(reqGet)
	if err != nil {
		StdRender(w, "", err)
	}

	defer resp.Body.Close()

	result := []interface{}{}
	if resp.Status == "200 OK" {
		body, _ := ioutil.ReadAll(resp.Body)
		var nodes = make(map[string]interface{})
		if err := json.Unmarshal(body, &nodes); err != nil {
			StdRender(w, "", err)
		}
		for _, host := range nodes["data"].([]interface{}) {
			item := map[string]interface{}{
				"text":       host,
				"expandable": true,
			}
			result = append(result, item)
		}
		RenderJson(w, result)
	} else {
		RenderJson(w, result)
	}
}
Exemple #2
0
// internal functions
func initConnPools() {
	cfg := g.Config()

	// TODO 为了得到Slice,这里做的太复杂了
	graphInstances := nset.NewSafeSet()
	for _, address := range cfg.Graph.Cluster {
		graphInstances.Add(address)
	}
	GraphConnPools = spool.CreateSafeRpcConnPools(cfg.Graph.MaxConns, cfg.Graph.MaxIdle,
		cfg.Graph.ConnTimeout, cfg.Graph.CallTimeout, graphInstances.ToSlice())
}
Exemple #3
0
func Info(para cmodel.GraphInfoParam) (resp *cmodel.GraphFullyInfo, err error) {
	endpoint, counter := para.Endpoint, para.Counter

	pool, addr, err := selectPool(endpoint, counter)
	if err != nil {
		return nil, err
	}

	conn, err := pool.Fetch()
	if err != nil {
		return nil, err
	}

	rpcConn := conn.(spool.RpcClient)
	if rpcConn.Closed() {
		pool.ForceClose(conn)
		return nil, errors.New("conn closed")
	}

	type ChResult struct {
		Err  error
		Resp *cmodel.GraphInfoResp
	}
	ch := make(chan *ChResult, 1)
	go func() {
		resp := &cmodel.GraphInfoResp{}
		err := rpcConn.Call("Graph.Info", para, resp)
		ch <- &ChResult{Err: err, Resp: resp}
	}()

	select {
	case <-time.After(time.Duration(g.Config().Graph.CallTimeout) * time.Millisecond):
		pool.ForceClose(conn)
		return nil, fmt.Errorf("%s, call timeout. proc: %s", addr, pool.Proc())
	case r := <-ch:
		if r.Err != nil {
			pool.ForceClose(conn)
			return nil, fmt.Errorf("%s, call failed, err %v. proc: %s", addr, r.Err, pool.Proc())
		} else {
			pool.Release(conn)
			fullyInfo := cmodel.GraphFullyInfo{
				Endpoint:  endpoint,
				Counter:   counter,
				ConsolFun: r.Resp.ConsolFun,
				Step:      r.Resp.Step,
				Filename:  r.Resp.Filename,
				Addr:      addr,
			}
			return &fullyInfo, nil
		}
	}
}
Exemple #4
0
func Start() {
	if !g.Config().Http.Enabled {
		log.Println("http.Start warning, not enabled")
		return
	}

	// config http routes
	configCommonRoutes()
	configProcHttpRoutes()
	configGraphRoutes()
	configApiRoutes()
	configGrafanaRoutes()

	// start http server
	addr := g.Config().Http.Listen
	s := &http.Server{
		Addr:           addr,
		MaxHeaderBytes: 1 << 30,
	}

	log.Println("http.Start ok, listening on", addr)
	log.Fatalln(s.ListenAndServe())
}
Exemple #5
0
func configCommonRoutes() {
	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok\n"))
	})

	http.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(fmt.Sprintf("%s\n", g.VERSION)))
	})

	http.HandleFunc("/workdir", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(fmt.Sprintf("%s\n", file.SelfDir())))
	})

	http.HandleFunc("/config", func(w http.ResponseWriter, r *http.Request) {
		RenderDataJson(w, g.Config())
	})

}
Exemple #6
0
func LastRaw(para cmodel.GraphLastParam) (r *cmodel.GraphLastResp, err error) {
	endpoint, counter := para.Endpoint, para.Counter

	pool, addr, err := selectPool(endpoint, counter)
	if err != nil {
		return nil, err
	}

	conn, err := pool.Fetch()
	if err != nil {
		return nil, err
	}

	rpcConn := conn.(spool.RpcClient)
	if rpcConn.Closed() {
		pool.ForceClose(conn)
		return nil, errors.New("conn closed")
	}

	type ChResult struct {
		Err  error
		Resp *cmodel.GraphLastResp
	}
	ch := make(chan *ChResult, 1)
	go func() {
		resp := &cmodel.GraphLastResp{}
		err := rpcConn.Call("Graph.LastRaw", para, resp)
		ch <- &ChResult{Err: err, Resp: resp}
	}()

	select {
	case <-time.After(time.Duration(g.Config().Graph.CallTimeout) * time.Millisecond):
		pool.ForceClose(conn)
		return nil, fmt.Errorf("%s, call timeout. proc: %s", addr, pool.Proc())
	case r := <-ch:
		if r.Err != nil {
			pool.ForceClose(conn)
			return r.Resp, fmt.Errorf("%s, call failed, err %v. proc: %s", addr, r.Err, pool.Proc())
		} else {
			pool.Release(conn)
			return r.Resp, nil
		}
	}
}
Exemple #7
0
func selectPool(endpoint, counter string) (rpool *spool.ConnPool, raddr string, rerr error) {
	pkey := cutils.PK2(endpoint, counter)
	node, err := GraphNodeRing.GetNode(pkey)
	if err != nil {
		return nil, "", err
	}

	addr, found := g.Config().Graph.Cluster[node]
	if !found {
		return nil, "", errors.New("node not found")
	}

	pool, found := GraphConnPools.Get(addr)
	if !found {
		return nil, addr, errors.New("addr not found")
	}

	return pool, addr, nil
}
Exemple #8
0
func QueryOne(para cmodel.GraphQueryParam) (resp *cmodel.GraphQueryResponse, err error) {
	start, end := para.Start, para.End
	endpoint, counter := para.Endpoint, para.Counter

	pool, addr, err := selectPool(endpoint, counter)
	if err != nil {
		return nil, err
	}

	conn, err := pool.Fetch()
	if err != nil {
		return nil, err
	}

	rpcConn := conn.(spool.RpcClient)
	if rpcConn.Closed() {
		pool.ForceClose(conn)
		return nil, errors.New("conn closed")
	}

	type ChResult struct {
		Err  error
		Resp *cmodel.GraphQueryResponse
	}

	ch := make(chan *ChResult, 1)
	go func() {
		resp := &cmodel.GraphQueryResponse{}
		err := rpcConn.Call("Graph.Query", para, resp)
		ch <- &ChResult{Err: err, Resp: resp}
	}()

	select {
	case <-time.After(time.Duration(g.Config().Graph.CallTimeout) * time.Millisecond):
		pool.ForceClose(conn)
		return nil, fmt.Errorf("%s, call timeout. proc: %s", addr, pool.Proc())
	case r := <-ch:
		if r.Err != nil {
			pool.ForceClose(conn)
			return r.Resp, fmt.Errorf("%s, call failed, err %v. proc: %s", addr, r.Err, pool.Proc())
		} else {
			pool.Release(conn)

			if len(r.Resp.Values) < 1 {
				return r.Resp, nil
			}

			// TODO query不该做这些事情, 说明graph没做好
			fixed := []*cmodel.RRDData{}
			for _, v := range r.Resp.Values {
				if v == nil || !(v.Timestamp >= start && v.Timestamp <= end) {
					continue
				}
				//FIXME: 查询数据的时候,把所有的负值都过滤掉,因为transfer之前在设置最小值的时候为U
				if (r.Resp.DsType == "DERIVE" || r.Resp.DsType == "COUNTER") && v.Value < 0 {
					fixed = append(fixed, &cmodel.RRDData{Timestamp: v.Timestamp, Value: cmodel.JsonFloat(math.NaN())})
				} else {
					fixed = append(fixed, v)
				}
			}
			r.Resp.Values = fixed
		}
		return r.Resp, nil
	}
}
Exemple #9
0
func initNodeRings() {
	cfg := g.Config()
	GraphNodeRing = rings.NewConsistentHashNodesRing(cfg.Graph.Replicas, cutils.KeysOfMap(cfg.Graph.Cluster))
}
Exemple #10
0
func dashboardChart(rw http.ResponseWriter, req *http.Request) {
	url := g.Config().Api.Dashboard + "/chart"
	postByForm(rw, req, url)
}
Exemple #11
0
func dashboardCounters(rw http.ResponseWriter, req *http.Request) {
	url := g.Config().Api.Dashboard + "/api/counters"
	postByForm(rw, req, url)
}
Exemple #12
0
func dashboardEndpoints(rw http.ResponseWriter, req *http.Request) {
	url := g.Config().Api.Dashboard + req.URL.RequestURI()
	getRequest(rw, url)
}
Exemple #13
0
func queryHistory(rw http.ResponseWriter, req *http.Request) {
	url := g.Config().Api.Query + "/graph/history"
	postByJson(rw, req, url)
}
Exemple #14
0
func queryInfo(rw http.ResponseWriter, req *http.Request) {
	url := g.Config().Api.Query + "/graph/info"
	postByJson(rw, req, url)
}
Exemple #15
0
func getMetricValues(req *http.Request, host string, targets []string, result []interface{}) []interface{} {
	endpoint_counters := []interface{}{}
	metric := strings.Join(targets, ".")
	if strings.Contains(host, "{") { // Templating metrics request
		host = strings.Replace(host, "{", "", -1)
		host = strings.Replace(host, "}", "", -1)
		hosts := strings.Split(host, ",")
		for _, host := range hosts {
			item := map[string]string{
				"endpoint": host,
				"counter":  metric,
			}
			endpoint_counters = append(endpoint_counters, item)
		}
	} else {
		item := map[string]string{
			"endpoint": host,
			"counter":  metric,
		}
		endpoint_counters = append(endpoint_counters, item)
	}

	if len(endpoint_counters) > 0 {
		from, err := strconv.ParseInt(req.PostForm["from"][0], 10, 64)
		until, err := strconv.ParseInt(req.PostForm["until"][0], 10, 64)
		url := "/graph/history"
		if strings.Index(g.Config().Api.Query, req.Host) >= 0 {
			url = "http://localhost:9966" + url
		} else {
			url = g.Config().Api.Query + url
		}

		args := map[string]interface{}{
			"start":             from,
			"end":               until,
			"cf":                "AVERAGE",
			"endpoint_counters": endpoint_counters,
		}
		bs, err := json.Marshal(args)
		if err != nil {
			log.Println("Error =", err.Error())
		}

		reqPost, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(bs)))
		if err != nil {
			log.Println("Error =", err.Error())
		}
		reqPost.Header.Set("Content-Type", "application/json")

		client := &http.Client{}
		resp, err := client.Do(reqPost)
		if err != nil {
			log.Println("Error =", err.Error())
		}
		defer resp.Body.Close()

		if resp.Status == "200 OK" {
			body, _ := ioutil.ReadAll(resp.Body)
			nodes := []interface{}{}
			if err := json.Unmarshal(body, &nodes); err != nil {
				log.Println(err.Error())
			}

			for _, node := range nodes {
				if _, ok := node.(map[string]interface{})["Values"]; ok {
					result = append(result, node)
				}
			}
		}
	}
	return result
}
Exemple #16
0
func getMetrics(w http.ResponseWriter, req *http.Request, query string) {
	result := []interface{}{}

	query = strings.Replace(query, "#.*", "", -1)
	arrQuery := strings.Split(query, "#")
	host, arrMetric := arrQuery[0], arrQuery[1:]
	maxQuery := strconv.Itoa(g.Config().Api.Max)
	metric := strings.Join(arrMetric, ".")
	reg, _ := regexp.Compile("(^{|}$)")
	host = reg.ReplaceAllString(host, "")
	host = strings.Replace(host, ",", "\",\"", -1)

	endpoints := "[\"" + host + "\"]"

	rand.Seed(time.Now().UTC().UnixNano())
	random64 := rand.Float64()
	_r := strconv.FormatFloat(random64, 'f', -1, 32)

	form := url.Values{}
	form.Set("endpoints", endpoints)
	form.Add("q", metric)
	form.Add("limit", maxQuery)
	form.Add("_r", _r)

	target := "/api/counters"
	if strings.Index(g.Config().Api.Query, req.Host) >= 0 {
		target = "http://localhost:9966" + target
	} else {
		target = g.Config().Api.Query + target
	}

	reqPost, err := http.NewRequest("POST", target, strings.NewReader(form.Encode()))
	if err != nil {
		log.Println("Error =", err.Error())
	}
	reqPost.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	client := &http.Client{}
	resp, err := client.Do(reqPost)
	if err != nil {
		log.Println("Error =", err.Error())
	}
	defer resp.Body.Close()

	if resp.Status == "200 OK" {
		body, _ := ioutil.ReadAll(resp.Body)
		var nodes = make(map[string]interface{})
		if err := json.Unmarshal(body, &nodes); err != nil {
			log.Println(err.Error())
		}
		var segmentPool = make(map[string]int)
		for _, data := range nodes["data"].([]interface{}) {
			counter := data.([]interface{})[0].(string)
			segment := getNextCounterSegment(metric, counter)
			expandable := checkSegmentExpandable(segment, counter)
			if _, ok := segmentPool[segment]; !ok {
				item := map[string]interface{}{
					"text":       segment,
					"expandable": expandable,
				}
				result = append(result, item)
				segmentPool[segment] = 1
			}
		}
		RenderJson(w, result)
	} else {
		RenderJson(w, result)
	}
}