/
discovery.go
147 lines (136 loc) · 3.47 KB
/
discovery.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package huaweiapm
import (
"crypto/md5"
"fmt"
"github.com/go-chassis/huawei-apm/runtime"
"github.com/go-chassis/huawei-apm/thrift/gen-go/apm"
"github.com/go-mesh/openlogging"
"io"
"net"
"os"
"time"
)
const (
AgentVersion = "2.1.0"
)
var instance *apm.TDiscoveryInfo
func startDiscovery(disco *apm.TDiscoveryInfo) {
if err := client.ReportDiscoveryInfo(disco); err != nil {
openlogging.Error("can not report inventory: " + err.Error())
}
openlogging.Debug("report inventory success")
t, _ := time.ParseDuration(DefaultDiscoveryInterval)
ticker := time.Tick(t)
for {
select {
case <-ticker:
if err := client.ReportDiscoveryInfo(disco); err != nil {
openlogging.Error("can not report inventory: " + err.Error())
}
openlogging.Debug("report inventory success")
case stop := <-StopInventory:
if stop {
openlogging.Info("inventory stopped")
break
}
}
}
}
func GetDiscoveryInfo() *apm.TDiscoveryInfo {
return instance
}
//GetLocalIP 获得本机IP
func GetLocalIP() string {
addresses, err := net.InterfaceAddrs()
if err != nil {
return ""
}
for _, address := range addresses {
// Parse IP
var ip net.IP
if ip, _, err = net.ParseCIDR(address.String()); err != nil {
return ""
}
// Check if valid global unicast IPv4 address
if ip != nil && (ip.To4() != nil) && ip.IsGlobalUnicast() {
return ip.String()
}
}
return ""
}
//BuildTDiscoveryInfo create a APM instance info
//if you report this info to cloud, APM can discovery your process
//should report it every 5 mins
func BuildTDiscoveryInfo(opts Options) (*apm.TDiscoveryInfo, error) {
hostname := opts.Hostname
var err error
if hostname == "" {
hostname, err = os.Hostname()
if err != nil {
return nil, err
}
}
ip := opts.IP
if ip == "" {
ip = GetLocalIP()
}
if opts.MonitoringGroup == "" {
opts.MonitoringGroup = "default"
}
if opts.App == "" {
opts.App = opts.MonitoringGroup
}
if opts.Project == "" {
opts.Project = "default"
openlogging.Warn("project is empty")
}
pod, err := runtime.PodID()
if err != nil {
return nil, err
}
instance = &apm.TDiscoveryInfo{
Hostname: hostname,
IP: ip,
AgentId: NewResourceID(opts.Ports, pod),
Pid: int32(os.Getpid()),
ProjectId: opts.Project,
AppName: opts.MonitoringGroup,
ClusterKey: runtime.Cluster(),
ServiceType: opts.ServiceType,
DisplayName: opts.ServiceName,
PodId: pod,
Props: map[string]string{
"config.status": "true",
"agent.version": AgentVersion,
},
NamespaceName: runtime.Namespace(),
Created: time.Now().Unix(),
Updated: time.Now().Unix(),
Deleted: 0,
}
instance.CollectorId = instance.AgentId
instance.AppId = NewAppID(instance.ProjectId, instance.GetAppName())
instance.Tier = instance.DisplayName
openlogging.Debug(fmt.Sprintf("build inventory %s", instance))
return instance, nil
}
//NewResourceID generate unique md5 ID for a process
func NewResourceID(ports []string, podID string) string {
h := md5.New()
io.WriteString(h, NewRawResourceID(ports, podID))
return fmt.Sprintf("%x", h.Sum(nil))
}
func NewAppID(project, appName string) string {
h := md5.New()
io.WriteString(h, NewRawAppID(project, appName))
return fmt.Sprintf("%x", h.Sum(nil))
}
func NewRawAppID(project, appName string) string {
return project + "|" + "default" + "|" + appName
}
func NewRawResourceID(ports []string, podID string) string {
if len(ports) == 0 {
return fmt.Sprintf("%s0%d", podID, os.Getpid())
}
return podID + ports[0]
}