func socketTelnetHandle(conn net.Conn) { defer conn.Close() items := []*cmodel.MetaData{} buf := bufio.NewReader(conn) cfg := g.Config() timeout := time.Duration(cfg.Socket.Timeout) * time.Second for { conn.SetReadDeadline(time.Now().Add(timeout)) line, err := buf.ReadString('\n') if err != nil { break } line = strings.Trim(line, "\n") if line == "quit" { break } if line == "" { continue } t := strings.Fields(line) if len(t) < 2 { continue } cmd := t[0] if cmd != "update" { continue } item, err := convertLine2MetaData(t[1:]) if err != nil { continue } items = append(items, item) } // statistics proc.SocketRecvCnt.IncrBy(int64(len(items))) proc.RecvCnt.IncrBy(int64(len(items))) if cfg.Graph.Enabled { sender.Push2GraphSendQueue(items, cfg.Graph.Migrating) } if cfg.Judge.Enabled { sender.Push2JudgeSendQueue(items) } if cfg.Influxdb.Enabled { sender.Push2TsdbSendQueue(items) } return }
// 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.Influxdb.Enabled { sender.Push2TsdbSendQueue(items) } if cfg.Judge.Enabled { sender.Push2JudgeSendQueue(items) } reply.Message = "ok" reply.Total = len(args) reply.Latency = (time.Now().UnixNano() - start.UnixNano()) / 1000000 return nil }