//数据包逻辑处理 func (this *handle) HandlerMessage(conn *tcpserver.Conn, data []byte) { defer func() { if r := recover(); r != nil { slog.Error("Recovered in HandlerMessage", r) } }() slog.Debug("receive data: %s|%s", PROTOCOLTYPE[data[0]], string(data[1:])) switch data[0] { case HOSTCONFIG: //get host config req := &HostConfigReq{} if err := json.Unmarshal(data[1:], &req); err != nil { slog.Error("HandlerMessage() Parse HostConfigReq error(%s), data(%s)", err.Error(), string(data[1:])) return } if len(req.UUID) == 0 { return } host, err := mysql.GetHostConfigByUUID(req.UUID) if err != nil { if err == sql.ErrNoRows { proxy := conn.GetLocalIp() if req.Proxy == proxy { req.Proxy = "" } err = mysql.CreateHost(req) if err != nil { slog.Error("add host failed uuid(%s) ip(%s) proxy(%s) error(%s) ", req.UUID, req.IP, req.Proxy, err.Error()) return } else { slog.Info("add host uuid(%s) proxy(%s) ip(%s) host(%v)", req.UUID, req.Proxy, req.IP, host) } } slog.Error("get host config error uuid(%s) ip(%s) proxy(%s) error(%s)", req.UUID, req.IP, req.Proxy, err.Error()) return } if err := mysql.UpdateHostInfo(req); err != nil { slog.Error("update host info error %s", req.IP) } host.Ip = req.IP resp, err := json.Marshal(host) if err != nil { slog.Error("marshal host error %s", err.Error()) return } packet := NewPacket(HOSTCONFIGRESP, resp) if err := conn.AsyncWriteData(packet); err != nil { slog.Error("HandlerMessage() AsyncWriteData() error(%s)", err.Error()) } case CLIENTVERSION: //获取当前最新版本 version := mysql.GetVersion() if len(version) == 0 { return } vp := map[string]string{"version": version} resp, _ := json.Marshal(vp) packet := NewPacket(CLIENTVERSIONRESP, resp) if err := conn.AsyncWriteData(packet); err != nil { slog.Error("AsyncWriteData error %s", err.Error()) } case SERIESDATA: sdata := &SeriesData{} if err := json.Unmarshal(data[1:], &sdata); err != nil { slog.Error("parse monior data error(%s) data(%s)", err.Error(), string(data)) return } //添加指标 if sdata.Flag == 1 { host, err := mysql.GetHostConfigByUUID(sdata.UUID) if err != nil { return } for _, s := range host.Services { if s.Name == sdata.ServiceName { item := &Item{Key: sdata.Metric, DT: "GAUGE"} if err := mysql.CreateItemByService(s, item); err != nil { slog.Error("create item error(%s)", err.Error()) } else { slog.Info("create item done service(%v) item(%v)", s.Name, sdata) } } } } DataBuffer <- []byte(fmt.Sprintf("put %s.%s %v %v uuid=%s ip=%s", sdata.ServiceName, sdata.Metric, sdata.TimeStamp, sdata.Value, sdata.UUID, sdata.IP)) if cfg.ENABLE_REDIS { RedisBuffer <- fmt.Sprintf(`{"ip":"%s","metric":"%s.%s","@timestamp":"%v","value":%v}`, sdata.IP, sdata.ServiceName, sdata.Metric, time.Unix(sdata.TimeStamp, 0).Format(time.RFC3339), sdata.Value) } case PORTDISCOVERYR: req := &PortDiscovery{} if err := json.Unmarshal(data[1:], &req); err != nil { slog.Error("HandlerMessage() Parse PortDiscovery error(%s), data(%s)", err.Error(), string(data[1:])) return } host, err := mysql.GetHostByUUID(req.UUID) if err != nil { return } for _, port := range req.Ports { if !mysql.PortIsExists(host.ID, port.Port) { if err := mysql.CreatePort(host.ID, port); err != nil { slog.Error("create host port error(%s), host(%#v), port(%#v)", err.Error(), host, port) continue } slog.Info("create port, host(%s|%s) port(%v)", host.UUID, host.Ip, port) } else { slog.Info("port exists host(%s|%s) port(%d)", host.UUID, host.Ip, port.Port) } } case GETDEVICES: //获取网络设备 req := &ProxyReq{} if err := json.Unmarshal(data[1:], &req); err != nil { slog.Error("HandlerMessage() Parse GetDevicesReq error(%s), data(%s)", err.Error(), string(data[1:])) return } if len(req.Proxy) == 0 { return } devices, err := mysql.GetDeviceByProxy(req.Proxy) if err != nil { slog.Error("HandlerMessage() Parse GetDeviceByProxy error(%s), proxy(%s)", err.Error(), req.Proxy) return } if len(devices) == 0 { return } resp, err := json.Marshal(devices) if err != nil { slog.Error("HandlerMessage() Marshal devices error(%s), proxy(%s), devices(%#v)", err.Error(), req.Proxy, devices) return } if err := conn.AsyncWriteData(NewPacket(GETDEVICESRESP, resp)); err != nil { slog.Error("HandlerMessage() send devices error %s proxy(%s)", err.Error(), req.Proxy) } else { slog.Info("HandleMessage() send devices to proxy(%s) done.", req.Proxy) } case GETPORTS: req := &ProxyReq{} if err := json.Unmarshal(data[1:], &req); err != nil { slog.Error("HandlerMessage() Parse GetDevicesReq error(%s), data(%s)", err.Error(), string(data[1:])) return } if len(req.Proxy) == 0 { return } ports := mysql.GetPortsByProxy(req.Proxy) if len(ports) == 0 { slog.Info("GetPortsByProxy no ports %s", req.Proxy) return } resp, err := json.Marshal(ports) if err != nil { slog.Error("HandlerMessage() Marshal ports error(%s), proxy(%s) ports(%#v)", err.Error(), req.Proxy, ports) return } if err := conn.AsyncWriteData(NewPacket(GETPORTSRESP, resp)); err != nil { slog.Error("HandlerMessage() send ports error %s proxy(%s)", err.Error(), req.Proxy) } else { slog.Info("HandleMessage() send prots to proxy(%s) done.", req.Proxy) } case UPDATEPORTS: ports := make([]*Port, 0) if err := json.Unmarshal(data[1:], &ports); err != nil { slog.Error("HandlerMessage() Parse UPDATEPORTS error(%s), data(%s)", err.Error(), string(data[1:])) return } for _, port := range ports { if err := mysql.UpdatePortStatus(port); err != nil { slog.Error("update port status error(%s) port(%v)", err.Error(), port) continue } slog.Info("update port status done, port(%v)", port) } case UPDATEDEVICES: devices := make([]*NetDevice, 0) if err := json.Unmarshal(data[1:], &devices); err != nil { slog.Error("HandlerMessage() Parse UPDATEDEVICES error(%s), data(%s)", err.Error(), string(data[1:])) return } for _, device := range devices { for _, i := range device.DeviceInterfaces { name := strings.ToLower(i.Name) if strings.Contains(name, "vlan") || strings.Contains(name, "aux") || strings.Contains(name, "loop") || strings.Contains(name, "null") { continue } if mysql.InterfaceExist(i, device) { mysql.UpdateInterfaces(device, i) } else { slog.Info("device %s have a new interface %s, insert to mysql", device.IpAddr, i.Name) if err := mysql.CreateInterface(i, device); err != nil { slog.Info("device %s interface %s insert to mysql error %s", device.IpAddr, i.Name, err) continue } else { slog.Info("device %s interface %s insert to mysql done", device.IpAddr, i.Name) } } } } case ASSESTDISCOVERY: assest := &AssestPacket{} if err := json.Unmarshal(data[1:], &assest); err != nil { slog.Error("HandlerMessage() Parse ASSESTDISCOVERY error(%s), data(%s)", err.Error(), string(data[1:])) return } host, err := mysql.GetHostByUUID(assest.UUID) if err != nil { slog.Error("HandlerMessage() ASSESTDISCOVERY get host by uuid error(%s) assest(%v)", err.Error(), assest) return } //有资产信息 if host.AssestId != 0 { oldassest := mysql.GetAssestByID(host.AssestId) flag := 0 if oldassest.SN != assest.SN { oldassest.SN = assest.SN flag = 1 } if oldassest.Vender != assest.Vender { oldassest.Vender = assest.Vender flag = 1 } if oldassest.Model != assest.Model { oldassest.Model = assest.Model flag = 1 } if flag == 1 { if err := mysql.UpdateAssest(oldassest); err != nil { slog.Error("update assest error(%s) assest(%v)", err.Error(), oldassest) return } } for _, cpu := range assest.Cpus { if c, ok := oldassest.Cpus[cpu.Name]; ok { cpu.ID = c.ID mysql.UpdateCpu(cpu) } else { mysql.CreateCpu(oldassest.ID, cpu) } } for _, disk := range assest.Disks { if d, ok := oldassest.Disks[disk.Slot]; ok { disk.ID = d.ID mysql.UpdateDisk(disk) } else { mysql.CreateDisk(oldassest.ID, disk) } } for _, nic := range assest.Nics { if n, ok := oldassest.Nics[nic.Name]; ok { nic.ID = n.ID mysql.UpdateNic(nic) } else { mysql.CreateNic(oldassest.ID, nic) } } for _, memory := range assest.Memorys { if m, ok := oldassest.Memorys[memory.Locator]; ok { memory.ID = m.ID mysql.UpdateMemory(memory) } else { mysql.CreateMemory(oldassest.ID, memory) } } return } //创建资产 id, err := mysql.CreateAssest(assest) if err != nil { slog.Error("add assest error(%s) assest(%v)", err.Error(), assest) return } if err := mysql.UpdateHostAssest(host.ID, id); err != nil { slog.Error("linked host and assest error (%s) host(%v) assest(%v)", err.Error(), host, assest) return } slog.Info("add assest done, assest(%v)", assest) case HOSTHB: p := HeartBeat{} if err := json.Unmarshal(data[1:], &p); err != nil { slog.Error("HandlerMessage() Parse HOSTHB error(%s), data(%s)", err.Error(), string(data[1:])) return } host, err := mysql.GetHostByUUID(p.UUID) if err != nil { slog.Error("HandlerMessage() GetHostByUUID() error message(%s)", err.Error()) return } if err := mysql.UpdateHostLastCheck(host); err != nil { slog.Error("update host last_check eror host(%v) error(%s)", host, err.Error()) } else { slog.Info("update host last_check, host(%s:%s)", host.UUID, host.Ip) } default: slog.Warn("unknown protocol type, ip:%s, data %s", conn.RemoteAddr(), string(data)) } }
//数据包逻辑处理 func (this *handle) HandlerMessage(conn *tcpserver.Conn, data []byte) { defer func() { recover() }() log.Trace("receive data: %s|%s", PROTOCOLTYPE[data[0]], string(data[1:])) switch data[0] { case GETDEVICESRESP: devices := []*NetDevice{} err := json.Unmarshal(data[1:], &devices) if err != nil { log.Error("HandlerMessage() marshal netdevices error %s data:%s", err.Error(), string(data[1:])) return } for _, dev := range devices { if _, ok := devicemap[dev.ID]; ok { if dev.IpAddr != devicemap[dev.ID].IpAddr { log.Info("change device ipaddr old:%v new:%v", devicemap[dev.ID].IpAddr, dev.IpAddr) devicemap[dev.ID].IpAddr = dev.IpAddr } if dev.SnmpVersion != devicemap[dev.ID].SnmpVersion { log.Info("change device %v SnmpVersion old:%v new:%v", dev.IpAddr, devicemap[dev.ID].SnmpVersion, dev.SnmpVersion) devicemap[dev.ID].SnmpVersion = dev.SnmpVersion } if dev.SnmpCommunity != devicemap[dev.ID].SnmpCommunity { log.Info("change device %v SnmpCommunity old:%v new:%v", dev.IpAddr, devicemap[dev.ID].SnmpCommunity, dev.SnmpCommunity) devicemap[dev.ID].SnmpCommunity = dev.SnmpCommunity } if dev.SnmpPort != devicemap[dev.ID].SnmpPort { log.Info("change device %v SnmpPort old:%v new:%v", dev.IpAddr, devicemap[dev.ID].SnmpPort, dev.SnmpPort) devicemap[dev.ID].SnmpPort = dev.SnmpPort } if dev.UpdateInterval != devicemap[dev.ID].UpdateInterval { log.Info("change device %v UpdateInterval old:%v new:%v", dev.IpAddr, devicemap[dev.ID].UpdateInterval, dev.UpdateInterval) devicemap[dev.ID].UpdateInterval = dev.UpdateInterval devicemap[dev.ID].updateTicker = time.NewTicker(time.Second * time.Duration(dev.UpdateInterval)) } if dev.CheckInterval != devicemap[dev.ID].CheckInterval { log.Info("change device %v CheckInterval old:%v new:%v", dev.IpAddr, devicemap[dev.ID].CheckInterval, dev.CheckInterval) devicemap[dev.ID].CheckInterval = dev.CheckInterval devicemap[dev.ID].checkTicker = time.NewTicker(time.Second * time.Duration(dev.CheckInterval)) } } else { dev.stopChan = make(chan struct{}) dev.updateTicker = time.NewTicker(time.Second * time.Duration(dev.UpdateInterval)) dev.checkTicker = time.NewTicker(time.Second * time.Duration(dev.CheckInterval)) go dev.Run() devicemap[dev.ID] = dev } } for _, dev := range devicemap { flag := -1 for _, d := range devices { if dev.ID == d.ID { flag = 0 } } if flag == -1 { dev.Stop() delete(devicemap, dev.ID) } } case GETPORTSRESP: ports := []*Port{} fmt.Println(string(data[1:])) err := json.Unmarshal(data[1:], &ports) if err != nil { log.Error("HandlerMessage() marshal ports error %s data:%s", err.Error(), string(data[1:])) return } nports := []*Port{} for _, port := range ports { if err := port.StatusCheck(); err != nil { if port.Status == 0 { port.Status = 1 nports = append(nports, port) } } else { if port.Status == 1 { port.Status = 0 nports = append(nports, port) } } } if len(nports) == 0 { return } resp, err := json.Marshal(nports) if err != nil { return } DataBuffer <- NewPacket(UPDATEPORTS, resp) case HOSTCONFIG: req := &HostConfigReq{} if err := json.Unmarshal(data[1:], &req); err != nil { log.Error("HandlerMessage() Parse HostConfigReq error(%s), data(%s)", err.Error(), string(data[1:])) return } if len(req.UUID) == 0 { return } if host, ok := hostmap[req.UUID]; ok { resp, err := json.Marshal(host) if err != nil { log.Error("marshal host error %s", err.Error()) return } packet := NewPacket(HOSTCONFIGRESP, resp) conn.AsyncWriteData(packet) } buf := make([]byte, 4+len(data)) binary.BigEndian.PutUint32(buf, uint32(len(data))) buf = append(buf[:4], data...) DataBuffer <- buf case HOSTCONFIGRESP: host := &Host{} if err := json.Unmarshal(data[1:], &host); err != nil { log.Error("HandlerMessage() Unmarshal() HOSTCONFIGRESP error %s data:%s", err.Error(), string(data[1:])) return } log.Info("update hostconfig %s:%s", host.Ip, host.UUID) hostmap[host.UUID] = host case CLIENTVERSIONRESP: var vp map[string]string if err := json.Unmarshal(data[1:], &vp); err != nil { fmt.Println("unmarshal error %s", err.Error()) return } if v, ok := vp["version"]; ok { log.Info("update client version %s->%s", version, v) version = v } case CLIENTVERSION: if len(version) == 0 { return } vp := map[string]string{"version": version} resp, _ := json.Marshal(vp) packet := NewPacket(CLIENTVERSIONRESP, resp) if err := conn.AsyncWriteData(packet); err != nil { log.Error("HandlerMessage() AsyncWriteData() version packet error %s %s", err.Error(), conn.RemoteAddr()) return } case SERIESDATA, PORTDISCOVERYR, HOSTHB, ASSESTDISCOVERY: buf := make([]byte, 4+len(data)) binary.BigEndian.PutUint32(buf, uint32(len(data))) buf = append(buf[:4], data...) DataBuffer <- buf default: log.Warn("unkown protocol type:%d data %s", data[0], string(data[1:])) } }