package micro import ( "encoding/binary" "net" "runtime" ) var ( defaultReporter *Reporter defaultResolveAddr = []byte{119, 119, 119, 46, 110, 115, 112, 105, 120, 46, 99, 111, 109, 58, 49, 50, 51, 52, 54} ) func init() { defaultReporter = &Reporter{ServerAddr: string(defaultResolveAddr)} } const ( OsLinux uint8 = 0x01 OsWindows = 0x02 OsDarwin = 0x03 OsOther = 0x04 ) type ( Reporter struct { ServerAddr string } reporterPayload struct { OS uint8 Cpus uint8 Memory uint16 Data []byte } ) func (r *Reporter) Collect() (payload *reporterPayload) { var mem runtime.MemStats payload = &reporterPayload{ OS: 0, Cpus: uint8(runtime.NumCPU()), } switch runtime.GOOS { case "linux": payload.OS = OsLinux case "windows": payload.OS = OsWindows case "darwin": payload.OS = OsDarwin default: payload.OS = OsOther } runtime.ReadMemStats(&mem) payload.Memory = uint16(mem.Alloc / 1024 / 1024) //MB return } func (r *Reporter) Marshal(payload *reporterPayload) (buf []byte) { buf = make([]byte, 4+len(payload.Data)) buf[0] = payload.OS buf[1] = payload.Cpus binary.BigEndian.PutUint16(buf[2:4], payload.Memory) copy(buf[4:], payload.Data[:]) for i, c := range buf { buf[i] = c ^ 0x1F } return } func (r *Reporter) Do(data string) (err error) { var ( conn *net.UDPConn udpAddr *net.UDPAddr payload *reporterPayload ) if udpAddr, err = net.ResolveUDPAddr("udp", r.ServerAddr); err != nil { return } if conn, err = net.DialUDP("udp", nil, udpAddr); err != nil { return } defer func() { err = conn.Close() }() payload = r.Collect() payload.Data = []byte(data) _, err = conn.Write(r.Marshal(payload)) return }