reporter.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package micro
  2. import (
  3. "crypto/md5"
  4. "encoding/binary"
  5. "git.nspix.com/golang/micro/helper/machineid"
  6. "hash"
  7. "net"
  8. "runtime"
  9. )
  10. var (
  11. defaultReporter *Reporter
  12. defaultResolveAddr = []byte{119, 119, 119, 46, 110, 115, 112, 105, 120, 46, 99, 111, 109, 58, 49, 50, 51, 52, 54}
  13. )
  14. func init() {
  15. defaultReporter = &Reporter{ServerAddr: string(defaultResolveAddr)}
  16. }
  17. const (
  18. OsLinux uint8 = 0x01
  19. OsWindows = 0x02
  20. OsDarwin = 0x03
  21. OsOther = 0x04
  22. )
  23. type (
  24. Reporter struct {
  25. ServerAddr string
  26. machineCode []byte
  27. }
  28. reporterPayload struct {
  29. OS uint8
  30. Cpus uint8
  31. Memory uint16
  32. Data []byte
  33. }
  34. )
  35. func (r *Reporter) getMachineCode() []byte {
  36. var (
  37. b []byte
  38. err error
  39. encoder hash.Hash
  40. inters []net.Interface
  41. )
  42. //get network hard addr
  43. if inters, err = net.Interfaces(); err == nil {
  44. for _, inter := range inters {
  45. if inter.HardwareAddr != nil {
  46. b = inter.HardwareAddr
  47. break
  48. }
  49. }
  50. }
  51. b = append(b, byte(runtime.NumCPU()))
  52. encoder = md5.New()
  53. encoder.Write(b)
  54. return encoder.Sum(nil)
  55. }
  56. func (r *Reporter) Collect() (payload *reporterPayload) {
  57. var mem runtime.MemStats
  58. payload = &reporterPayload{
  59. OS: 0,
  60. Cpus: uint8(runtime.NumCPU()),
  61. }
  62. switch runtime.GOOS {
  63. case "linux":
  64. payload.OS = OsLinux
  65. case "windows":
  66. payload.OS = OsWindows
  67. case "darwin":
  68. payload.OS = OsDarwin
  69. default:
  70. payload.OS = OsOther
  71. }
  72. runtime.ReadMemStats(&mem)
  73. payload.Memory = uint16(mem.Alloc / 1024) //KB
  74. return
  75. }
  76. func (r *Reporter) Marshal(payload *reporterPayload) (buf []byte) {
  77. var (
  78. dl uint8
  79. cl uint8
  80. )
  81. dl = uint8(len(payload.Data))
  82. cl = uint8(len(r.machineCode))
  83. buf = make([]byte, 6+int(dl)+int(cl))
  84. buf[0] = payload.OS
  85. buf[1] = payload.Cpus
  86. buf[2] = cl
  87. buf[3] = dl
  88. binary.BigEndian.PutUint16(buf[4:6], payload.Memory)
  89. copy(buf[6:6+cl], r.machineCode)
  90. copy(buf[6+cl:], payload.Data[:])
  91. for i, c := range buf {
  92. buf[i] = c ^ 0x1F
  93. }
  94. return
  95. }
  96. func (r *Reporter) Do(data string) (err error) {
  97. var (
  98. conn *net.UDPConn
  99. udpAddr *net.UDPAddr
  100. payload *reporterPayload
  101. machineCode string
  102. )
  103. if r.machineCode == nil {
  104. if machineCode, err = machineid.Code(); err != nil {
  105. r.machineCode = r.getMachineCode()
  106. } else {
  107. r.machineCode = []byte(machineCode)
  108. }
  109. }
  110. if udpAddr, err = net.ResolveUDPAddr("udp", r.ServerAddr); err != nil {
  111. return
  112. }
  113. if conn, err = net.DialUDP("udp", nil, udpAddr); err != nil {
  114. return
  115. }
  116. defer func() {
  117. err = conn.Close()
  118. }()
  119. payload = r.Collect()
  120. payload.Data = []byte(data)
  121. _, err = conn.Write(r.Marshal(payload))
  122. return
  123. }