// 当 grp展开结果 与 host结果 存在冲突时, 优先选择 host结果 func GetMockCfgFromDB() map[string]*cmodel.NodataConfig { ret := make(map[string]*cmodel.NodataConfig) dbConn, err := GetDbConn("nodata.mockcfg") if err != nil { log.Println("db.get_conn error, mockcfg", err) return ret } q := fmt.Sprintf("SELECT id,name,obj,obj_type,metric,tags,dstype,step,mock FROM mockcfg") rows, err := dbConn.Query(q) if err != nil { log.Println("db.query error, mockcfg", err) return ret } defer rows.Close() for rows.Next() { t := MockCfg{} tags := "" err := rows.Scan(&t.Id, &t.Name, &t.Obj, &t.ObjType, &t.Metric, &tags, &t.Type, &t.Step, &t.Mock) if err != nil { log.Println("db.scan error, mockcfg", err) continue } t.Tags = cutils.DictedTagstring(tags) err = checkMockCfg(&t) if err != nil { log.Println("check mockcfg, error:", err) continue } endpoints := getEndpoint(t.ObjType, t.Obj) if len(endpoints) < 1 { continue } for _, ep := range endpoints { uuid := cutils.PK(ep, t.Metric, t.Tags) ncfg := cmodel.NewNodataConfig(t.Id, t.Name, t.ObjType, ep, t.Metric, t.Tags, t.Type, t.Step, t.Mock) val, found := ret[uuid] if !found { // so cute, it's the first one ret[uuid] = ncfg continue } if isSpuerNodataCfg(val, ncfg) { // val is spuer than ncfg, so drop ncfg log.Printf("nodata.mockcfg conflict, %s, used %s, drop %s", uuid, val.Name, ncfg.Name) } else { ret[uuid] = ncfg // overwrite the old one log.Printf("nodata.mockcfg conflict, %s, used %s, drop %s", uuid, ncfg.Name, val.Name) } } } return ret }
func configDebugRoutes() { http.HandleFunc("/count", func(w http.ResponseWriter, r *http.Request) { for i := 0; i < store.GraphItems.Size; i++ { keys := store.GraphItems.KeysByIndex(i) if len(keys) == 0 { w.Write([]byte(fmt.Sprintf("%d\n", 0))) return } oneHourAgo := time.Now().Unix() - 3600 count := 0 for _, checksum := range keys { item := store.GraphItems.First(checksum) if item == nil { continue } if item.Timestamp > oneHourAgo { count++ } } w.Write([]byte(fmt.Sprintf("%d\n", count))) } }) // 接收数据 endpoint metric ts step dstype value [tags] http.HandleFunc("/api/recv/", func(w http.ResponseWriter, r *http.Request) { urlParam := r.URL.Path[len("/api/recv/"):] args := strings.Split(urlParam, "/") argsLen := len(args) if !(argsLen == 6 || argsLen == 7) { RenderDataJson(w, "bad args") return } endpoint := args[0] metric := args[1] ts, _ := strconv.ParseInt(args[2], 10, 64) step, _ := strconv.ParseInt(args[3], 10, 32) dstype := args[4] value, _ := strconv.ParseFloat(args[5], 64) tags := make(map[string]string) if argsLen == 7 { tags = cutils.DictedTagstring(args[6]) } item := &cmodel.MetaData{ Endpoint: endpoint, Metric: metric, Timestamp: ts, Step: step, CounterType: dstype, Value: value, Tags: tags, } gitem, err := convert2GraphItem(item) if err != nil { RenderDataJson(w, err) return } api.HandleItems([]*cmodel.GraphItem{gitem}) RenderDataJson(w, "ok") }) }
// process new metric values func RecvMetricValues(args []*cmodel.MetricValue, reply *cmodel.TransferResponse, from string) error { start := time.Now() reply.Invalid = 0 items := []*cmodel.MetaData{} for _, v := range args { if v == nil { reply.Invalid += 1 continue } // 历史遗留问题. // 老版本agent上报的metric=kernel.hostname的数据,其取值为string类型,现在已经不支持了;所以,这里硬编码过滤掉 if v.Metric == "kernel.hostname" { reply.Invalid += 1 continue } if v.Metric == "" || v.Endpoint == "" { reply.Invalid += 1 continue } if v.Type != g.COUNTER && v.Type != g.GAUGE && v.Type != g.DERIVE { reply.Invalid += 1 continue } if v.Value == "" { reply.Invalid += 1 continue } if v.Step <= 0 { reply.Invalid += 1 continue } if len(v.Metric)+len(v.Tags) > 510 { reply.Invalid += 1 continue } // TODO 呵呵,这里需要再优雅一点 now := start.Unix() if v.Timestamp <= 0 || v.Timestamp > now*2 { v.Timestamp = now } fv := &cmodel.MetaData{ Metric: v.Metric, Endpoint: v.Endpoint, Timestamp: v.Timestamp, Step: v.Step, CounterType: v.Type, Tags: cutils.DictedTagstring(v.Tags), //TODO tags键值对的个数,要做一下限制 } valid := true var vv float64 var err error switch cv := v.Value.(type) { case string: vv, err = strconv.ParseFloat(cv, 64) if err != nil { valid = false } case float64: vv = cv case int64: vv = float64(cv) default: valid = false } if !valid { reply.Invalid += 1 continue } fv.Value = vv items = append(items, fv) } // statistics cnt := int64(len(items)) proc.RecvCnt.IncrBy(cnt) if from == "rpc" { proc.RpcRecvCnt.IncrBy(cnt) } else if from == "http" { proc.HttpRecvCnt.IncrBy(cnt) } cfg := g.Config() if cfg.Graph.Enabled { sender.Push2GraphSendQueue(items, cfg.Graph.Migrating) } if cfg.Judge.Enabled { sender.Push2JudgeSendQueue(items) } if cfg.Tsdb.Enabled { sender.Push2TsdbSendQueue(items) } reply.Message = "ok" reply.Total = len(args) reply.Latency = (time.Now().UnixNano() - start.UnixNano()) / 1000000 return nil }