123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package micro
- import (
- "crypto/md5"
- "encoding/binary"
- "hash"
- "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
- machineCode []byte
- }
- reporterPayload struct {
- OS uint8
- Cpus uint8
- Memory uint16
- Data []byte
- }
- )
- func (r *Reporter) getMachineCode() []byte {
- var (
- b []byte
- err error
- encoder hash.Hash
- inters []net.Interface
- )
- //get network hard addr
- if inters, err = net.Interfaces(); err == nil {
- for _, inter := range inters {
- if inter.HardwareAddr != nil {
- b = inter.HardwareAddr
- break
- }
- }
- }
- b = append(b, byte(runtime.NumCPU()))
- encoder = md5.New()
- encoder.Write(b)
- return encoder.Sum(nil)
- }
- 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) //KB
- return
- }
- func (r *Reporter) Marshal(payload *reporterPayload) (buf []byte) {
- var (
- dl uint8
- cl uint8
- )
- dl = uint8(len(payload.Data))
- cl = uint8(len(r.machineCode))
- buf = make([]byte, 6+int(dl)+int(cl))
- buf[0] = payload.OS
- buf[1] = payload.Cpus
- buf[2] = cl
- buf[3] = dl
- binary.BigEndian.PutUint16(buf[4:6], payload.Memory)
- copy(buf[6:6+cl], r.machineCode)
- copy(buf[6+cl:], 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 r.machineCode == nil {
- r.machineCode = r.getMachineCode()
- }
- 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
- }
|