Merge pull request #1377 from weaveworks/1322-probe-name-and-version

Report hostname and version in probe struct, and version in host node.
This commit is contained in:
Paul Bellamy
2016-04-26 10:48:04 +01:00
9 changed files with 51 additions and 83 deletions

View File

@@ -1,7 +1,7 @@
.PHONY: all deps static clean client-lint client-test client-sync backend frontend shell lint
# If you can use Docker without being root, you can `make SUDO= <target>`
SUDO=$(shell (echo "$$DOCKER_HOST" | grep "tcp://" >/dev/null) || echo "sudo -E")
SUDO=$(shell docker info >/dev/null 2>&1 || echo "sudo -E")
DOCKERHUB_USER=weaveworks
SCOPE_EXE=prog/scope
SCOPE_IMAGE=$(DOCKERHUB_USER)/scope

View File

@@ -2,9 +2,11 @@ package app
import (
"net/http"
"time"
"golang.org/x/net/context"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/report"
)
@@ -20,6 +22,13 @@ func makeRawReportHandler(rep Reporter) CtxHandlerFunc {
}
}
type probeDesc struct {
ID string `json:"id"`
Hostname string `json:"hostname"`
Version string `json:"version"`
LastSeen time.Time `json:"lastSeen"`
}
// Probe handler
func makeProbeHandler(rep Reporter) CtxHandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
@@ -28,9 +37,17 @@ func makeProbeHandler(rep Reporter) CtxHandlerFunc {
respondWith(w, http.StatusInternalServerError, err.Error())
return
}
result := []report.Probe{}
for _, p := range rpt.Probes {
result = append(result, p)
result := []probeDesc{}
for _, n := range rpt.Host.Nodes {
id, _ := n.Latest.Lookup(report.ControlProbeID)
hostname, _ := n.Latest.Lookup(host.HostName)
version, dt, _ := n.Latest.LookupEntry(host.ScopeVersion)
result = append(result, probeDesc{
ID: id,
Hostname: hostname,
Version: version,
LastSeen: dt,
})
}
respondWith(w, http.StatusOK, result)
}

View File

@@ -21,6 +21,7 @@ const (
Load1 = "load1"
CPUUsage = "host_cpu_usage_percent"
MemoryUsage = "host_mem_usage_bytes"
ScopeVersion = "host_scope_version"
)
// Exposed for testing.
@@ -39,6 +40,7 @@ var (
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{
@@ -53,18 +55,20 @@ type Reporter struct {
hostID string
hostName string
probeID string
version string
pipes controls.PipeClient
hostShellCmd []string
}
// NewReporter returns a Reporter which produces a report containing host
// topology for this host.
func NewReporter(hostID, hostName, probeID string, pipes controls.PipeClient) *Reporter {
func NewReporter(hostID, hostName, probeID, version string, pipes controls.PipeClient) *Reporter {
r := &Reporter{
hostID: hostID,
hostName: hostName,
probeID: probeID,
pipes: pipes,
version: version,
hostShellCmd: getHostShellCmd(),
}
r.registerControls()
@@ -125,16 +129,22 @@ func (r *Reporter) Report() (report.Report, error) {
memoryUsage, max := GetMemoryUsageBytes()
metrics[MemoryUsage] = report.MakeMetric().Add(now, memoryUsage).WithMax(max)
metadata := map[string]string{report.ControlProbeID: r.probeID}
rep.Host.AddNode(report.MakeNodeWith(report.MakeHostNodeID(r.hostID), map[string]string{
Timestamp: mtime.Now().UTC().Format(time.RFC3339Nano),
HostName: r.hostName,
OS: runtime.GOOS,
KernelVersion: kernel,
Uptime: uptime.String(),
}).WithSets(report.EmptySets.
Add(LocalNetworks, report.MakeStringSet(localCIDRs...)),
).WithMetrics(metrics).WithControls(ExecHost).WithLatests(metadata))
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: uptime.String(),
ScopeVersion: r.version,
}).
WithSets(report.EmptySets.
Add(LocalNetworks, report.MakeStringSet(localCIDRs...)),
).
WithMetrics(metrics).
WithControls(ExecHost),
)
rep.Host.Controls.AddControl(report.Control{
ID: ExecHost,

View File

@@ -18,7 +18,6 @@ func TestReporter(t *testing.T) {
network = "192.168.0.0/16"
hostID = "hostid"
hostname = "hostname"
probeID = "abcdeadbeef"
timestamp = time.Now()
metrics = report.Metrics{
host.Load1: report.MakeMetric().Add(timestamp, 1.0),
@@ -56,7 +55,7 @@ func TestReporter(t *testing.T) {
host.GetMemoryUsageBytes = func() (float64, float64) { return 60.0, 100.0 }
host.GetLocalNetworks = func() ([]*net.IPNet, error) { return []*net.IPNet{ipnet}, nil }
rpt, err := host.NewReporter(hostID, hostname, probeID, nil).Report()
rpt, err := host.NewReporter(hostID, hostname, "", "", nil).Report()
if err != nil {
t.Fatal(err)
}

View File

@@ -7,7 +7,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/armon/go-metrics"
"github.com/weaveworks/scope/common/mtime"
"github.com/weaveworks/scope/probe/appclient"
"github.com/weaveworks/scope/report"
)
@@ -18,7 +17,6 @@ const (
// Probe sits there, generating and publishing reports.
type Probe struct {
id string
spyInterval, publishInterval time.Duration
publisher *appclient.ReportPublisher
@@ -67,9 +65,11 @@ type Ticker interface {
}
// New makes a new Probe.
func New(id string, spyInterval, publishInterval time.Duration, publisher appclient.Publisher) *Probe {
func New(
spyInterval, publishInterval time.Duration,
publisher appclient.Publisher,
) *Probe {
result := &Probe{
id: id,
spyInterval: spyInterval,
publishInterval: publishInterval,
publisher: appclient.NewReportPublisher(publisher),
@@ -166,10 +166,6 @@ func (p *Probe) report() report.Report {
for i := 0; i < cap(reports); i++ {
result = result.Merge(<-reports)
}
result.Probes[p.id] = report.Probe{
ID: p.id,
LastSeen: mtime.Now(),
}
return result
}

View File

@@ -19,7 +19,7 @@ func TestApply(t *testing.T) {
endpointNode = report.MakeNodeWith(endpointNodeID, map[string]string{"5": "6"})
)
p := New("", 0, 0, nil)
p := New(0, 0, nil)
p.AddTagger(NewTopologyTagger())
r := report.MakeReport()
@@ -89,16 +89,11 @@ func TestProbe(t *testing.T) {
want.Service.Controls = nil
want.Host.Controls = nil
want.Overlay.Controls = nil
want.Endpoint.AddNode(node)
want.Probes[probeID] = report.Probe{
ID: probeID,
LastSeen: now,
}
pub := mockPublisher{make(chan report.Report, 10)}
p := New(probeID, 10*time.Millisecond, 100*time.Millisecond, pub)
p := New(10*time.Millisecond, 100*time.Millisecond, pub)
p.AddReporter(mockReporter{want})
p.Start()
defer p.Stop()

View File

@@ -117,9 +117,9 @@ func probeMain(flags probeFlags) {
endpointReporter := endpoint.NewReporter(hostID, hostName, flags.spyProcs, flags.useConntrack, scanner)
defer endpointReporter.Stop()
p := probe.New(probeID, flags.spyInterval, flags.publishInterval, clients)
p := probe.New(flags.spyInterval, flags.publishInterval, clients)
p.AddTicker(processCache)
hostReporter := host.NewReporter(hostID, hostName, probeID, clients)
hostReporter := host.NewReporter(hostID, hostName, probeID, version, clients)
defer hostReporter.Stop()
p.AddReporter(
endpointReporter,

View File

@@ -1,43 +0,0 @@
package report
import (
"time"
)
// Probes contains details of the probe(s) which generated a report.
type Probes map[string]Probe
// Copy produces a copy of the Probes
func (ps Probes) Copy() Probes {
result := Probes{}
for id, probe := range ps {
result[id] = probe.Copy()
}
return result
}
// Merge two sets of Probes, keeping the records with the latest LastSeen
func (ps Probes) Merge(other Probes) Probes {
result := ps.Copy()
for id, probe := range other {
o, ok := result[id]
if !ok || o.LastSeen.Before(probe.LastSeen) {
result[id] = probe
}
}
return result
}
// Probe is the details for a single probe that generated a report.
type Probe struct {
ID string `json:"id"`
LastSeen time.Time `json:"lastSeen"`
}
// Copy produces a copy of the Probe
func (p Probe) Copy() Probe {
return Probe{
ID: p.ID,
LastSeen: p.LastSeen,
}
}

View File

@@ -95,9 +95,6 @@ type Report struct {
// must be equal, but we don't require that equal reports have
// the same id.
ID string `deepequal:"skip"`
// Probes is the details of the probes who reported this report
Probes Probes
}
// MakeReport makes a clean report, ready to Merge() other reports into.
@@ -135,7 +132,6 @@ func MakeReport() Report {
Window: 0,
Plugins: xfer.MakePluginSpecs(),
ID: fmt.Sprintf("%d", rand.Int63()),
Probes: Probes{},
}
}
@@ -154,7 +150,6 @@ func (r Report) Copy() Report {
Window: r.Window,
Plugins: r.Plugins.Copy(),
ID: fmt.Sprintf("%d", rand.Int63()),
Probes: r.Probes.Copy(),
}
}
@@ -171,7 +166,6 @@ func (r Report) Merge(other Report) Report {
cp.Service = r.Service.Merge(other.Service)
cp.Overlay = r.Overlay.Merge(other.Overlay)
cp.Sampling = r.Sampling.Merge(other.Sampling)
cp.Probes = r.Probes.Merge(other.Probes)
cp.Window += other.Window
cp.Plugins = r.Plugins.Merge(other.Plugins)
return cp