/
reporter.go
156 lines (136 loc) · 4.51 KB
/
reporter.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
148
149
150
151
152
153
154
155
156
package host
import (
"fmt"
"runtime"
"strconv"
"sync"
"time"
"github.com/weaveworks/common/mtime"
"github.com/weaveworks/scope/probe/controls"
"github.com/weaveworks/scope/report"
)
// Keys for use in Node.Latest.
const (
Timestamp = report.Timestamp
HostName = report.HostName
LocalNetworks = report.HostLocalNetworks
OS = report.OS
KernelVersion = report.KernelVersion
Uptime = report.Uptime
Load1 = report.Load1
CPUUsage = report.HostCPUUsage
MemoryUsage = report.HostMemoryUsage
ScopeVersion = report.ScopeVersion
)
// Exposed for testing.
const (
ProcUptime = "/proc/uptime"
ProcLoad = "/proc/loadavg"
ProcStat = "/proc/stat"
ProcMemInfo = "/proc/meminfo"
)
// Exposed for testing.
var (
MetadataTemplates = report.MetadataTemplates{
KernelVersion: {ID: KernelVersion, Label: "Kernel version", From: report.FromLatest, Priority: 1},
Uptime: {ID: Uptime, Label: "Uptime", From: report.FromLatest, Priority: 2, Datatype: report.Duration},
HostName: {ID: HostName, Label: "Hostname", From: report.FromLatest, Priority: 11},
OS: {ID: OS, Label: "OS", From: report.FromLatest, Priority: 12},
LocalNetworks: {ID: LocalNetworks, Label: "Local networks", From: report.FromSets, Priority: 13},
ScopeVersion: {ID: ScopeVersion, Label: "Scope version", From: report.FromLatest, Priority: 14},
}
MetricTemplates = report.MetricTemplates{
CPUUsage: {ID: CPUUsage, Label: "CPU", Format: report.PercentFormat, Priority: 1},
MemoryUsage: {ID: MemoryUsage, Label: "Memory", Format: report.FilesizeFormat, Priority: 2},
Load1: {ID: Load1, Label: "Load (1m)", Format: report.DefaultFormat, Group: "load", Priority: 11},
}
)
// Reporter generates Reports containing the host topology.
type Reporter struct {
sync.RWMutex
hostID string
hostName string
probeID string
version string
pipes controls.PipeClient
hostShellCmd []string
handlerRegistry *controls.HandlerRegistry
pipeIDToTTY map[string]uintptr
}
// NewReporter returns a Reporter which produces a report containing host
// topology for this host.
func NewReporter(hostID, hostName, probeID, version string, pipes controls.PipeClient, handlerRegistry *controls.HandlerRegistry) *Reporter {
r := &Reporter{
hostID: hostID,
hostName: hostName,
probeID: probeID,
pipes: pipes,
version: version,
hostShellCmd: getHostShellCmd(),
handlerRegistry: handlerRegistry,
pipeIDToTTY: map[string]uintptr{},
}
r.registerControls()
return r
}
// Name of this reporter, for metrics gathering
func (*Reporter) Name() string { return "Host" }
// GetLocalNetworks is exported for mocking
var GetLocalNetworks = report.GetLocalNetworks
// Report implements Reporter.
func (r *Reporter) Report() (report.Report, error) {
var (
rep = report.MakeReport()
localCIDRs []string
)
localNets, err := GetLocalNetworks()
if err != nil {
return rep, nil
}
for _, localNet := range localNets {
localCIDRs = append(localCIDRs, localNet.String())
}
uptime, err := GetUptime()
if err != nil {
return rep, err
}
kernelRelease, kernelVersion, err := GetKernelReleaseAndVersion()
if err != nil {
return rep, err
}
kernel := fmt.Sprintf("%s %s", kernelRelease, kernelVersion)
rep.Host = rep.Host.WithMetadataTemplates(MetadataTemplates)
rep.Host = rep.Host.WithMetricTemplates(MetricTemplates)
now := mtime.Now()
metrics := GetLoad(now)
cpuUsage, max := GetCPUUsagePercent()
metrics[CPUUsage] = report.MakeSingletonMetric(now, cpuUsage).WithMax(max)
memoryUsage, max := GetMemoryUsageBytes()
metrics[MemoryUsage] = report.MakeSingletonMetric(now, memoryUsage).WithMax(max)
rep.Host.AddNode(
report.MakeNodeWith(report.MakeHostNodeID(r.hostID), map[string]string{
report.ControlProbeID: r.probeID,
Timestamp: mtime.Now().UTC().Format(time.RFC3339Nano),
HostName: r.hostName,
OS: runtime.GOOS,
KernelVersion: kernel,
Uptime: strconv.Itoa(int(uptime / time.Second)), // uptime in seconds
ScopeVersion: r.version,
}).
WithSets(report.MakeSets().
Add(LocalNetworks, report.MakeStringSet(localCIDRs...)),
).
WithMetrics(metrics).
WithLatestActiveControls(ExecHost),
)
rep.Host.Controls.AddControl(report.Control{
ID: ExecHost,
Human: "Exec shell",
Icon: "fa fa-terminal",
})
return rep, nil
}
// Stop stops the reporter.
func (r *Reporter) Stop() {
r.deregisterControls()
}