Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Humanize reported durations #2915

Merged
merged 4 commits into from
Nov 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions client/app/scripts/utils/__tests__/string-utils-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import moment from 'moment';


describe('StringUtils', () => {
const StringUtils = require('../string-utils');
Expand Down Expand Up @@ -29,4 +31,20 @@ describe('StringUtils', () => {
expect(f('0.24.3.4')).toBe('000.024.003.004');
});
});

describe('humanizedRoundedDownDuration', () => {
const f = StringUtils.humanizedRoundedDownDuration;

it('it should return the humanized duration', () => {
expect(f(moment.duration(0))).toBe('now');
expect(f(moment.duration(0.9 * 1000))).toBe('now');
expect(f(moment.duration(1 * 1000))).toBe('1 second');
expect(f(moment.duration(8.62 * 60 * 1000))).toBe('8 minutes');
expect(f(moment.duration(14.99 * 60 * 60 * 1000))).toBe('14 hours');
expect(f(moment.duration(5.2 * 24 * 60 * 60 * 1000))).toBe('5 days');
expect(f(moment.duration(11.8 * 30 * 24 * 60 * 60 * 1000))).toBe('11 months');
expect(f(moment.duration(12.8 * 30 * 24 * 60 * 60 * 1000))).toBe('1 year');
expect(f(moment.duration(9.4 * 12 * 30 * 24 * 60 * 60 * 1000))).toBe('9 years');
});
});
});
25 changes: 24 additions & 1 deletion client/app/scripts/utils/string-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ export function ipToPaddedString(value) {
return value.match(/\d+/g).map(padToThreeDigits).join('.');
}

// Doing the manual parsing because `duration.humanize()` would sometimes round up the period,
// while we always want a rounded down value for consistency with other values sent by backend.
export function humanizedRoundedDownDuration(duration) {
let humanizedDuration = 'now';
['second', 'minute', 'hour', 'day', 'month', 'year'].forEach((period) => {
const durationAsPeriod = Math.floor(duration.as(period));
if (durationAsPeriod > 0) {
const pluralEnding = ((durationAsPeriod !== 11 && (durationAsPeriod % 10) === 1) ? '' : 's');
humanizedDuration = `${durationAsPeriod} ${period}${pluralEnding}`;
}
});
return humanizedDuration;
}

// Formats metadata values. Add a key to the `formatters` obj
// that matches the `dataType` of the field. You must return an Object
// with the keys `value` and `title` defined.
Expand All @@ -99,7 +113,16 @@ export function formatDataType(field, referenceTimestampStr = null) {
value: timestamp.from(referenceTimestamp),
title: timestamp.utc().toISOString()
};
}
},
duration(durationSecondsString) {
const duration = moment.duration(Number(durationSecondsString), 'seconds');
const humanizedDuration = humanizedRoundedDownDuration(duration);

return {
value: humanizedDuration,
title: humanizedDuration,
};
},
};
const format = formatters[field.dataType];
return format
Expand Down
8 changes: 4 additions & 4 deletions probe/awsecs/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ const (
var (
taskMetadata = report.MetadataTemplates{
Cluster: {ID: Cluster, Label: "Cluster", From: report.FromLatest, Priority: 0},
CreatedAt: {ID: CreatedAt, Label: "Created At", From: report.FromLatest, Priority: 1, Datatype: "datetime"},
CreatedAt: {ID: CreatedAt, Label: "Created At", From: report.FromLatest, Priority: 1, Datatype: report.DateTime},
TaskFamily: {ID: TaskFamily, Label: "Family", From: report.FromLatest, Priority: 2},
}
serviceMetadata = report.MetadataTemplates{
Cluster: {ID: Cluster, Label: "Cluster", From: report.FromLatest, Priority: 0},
CreatedAt: {ID: CreatedAt, Label: "Created At", From: report.FromLatest, Priority: 1, Datatype: "datetime"},
ServiceDesiredCount: {ID: ServiceDesiredCount, Label: "Desired Tasks", From: report.FromLatest, Priority: 2, Datatype: "number"},
ServiceRunningCount: {ID: ServiceRunningCount, Label: "Running Tasks", From: report.FromLatest, Priority: 3, Datatype: "number"},
CreatedAt: {ID: CreatedAt, Label: "Created At", From: report.FromLatest, Priority: 1, Datatype: report.DateTime},
ServiceDesiredCount: {ID: ServiceDesiredCount, Label: "Desired Tasks", From: report.FromLatest, Priority: 2, Datatype: report.Number},
ServiceRunningCount: {ID: ServiceRunningCount, Label: "Running Tasks", From: report.FromLatest, Priority: 3, Datatype: report.Number},
}
)

Expand Down
4 changes: 2 additions & 2 deletions probe/docker/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,12 @@ func (c *container) GetNode() report.Node {
controls := c.controlsMap()

if !c.container.State.Paused && c.container.State.Running {
uptime := (mtime.Now().Sub(c.container.State.StartedAt) / time.Second) * time.Second
uptimeSeconds := int(mtime.Now().Sub(c.container.State.StartedAt) / time.Second)
networkMode := ""
if c.container.HostConfig != nil {
networkMode = c.container.HostConfig.NetworkMode
}
latest[ContainerUptime] = uptime.String()
latest[ContainerUptime] = strconv.Itoa(uptimeSeconds)
latest[ContainerRestartCount] = strconv.Itoa(c.container.RestartCount)
latest[ContainerNetworkMode] = networkMode
}
Expand Down
5 changes: 3 additions & 2 deletions probe/docker/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package docker_test

import (
"net"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -58,7 +59,7 @@ func TestContainer(t *testing.T) {

// Now see if we go them
{
uptime := (now.Sub(startTime) / time.Second) * time.Second
uptimeSeconds := int(now.Sub(startTime) / time.Second)
controls := map[string]report.NodeControlData{
docker.UnpauseContainer: {Dead: true},
docker.RestartContainer: {Dead: false},
Expand All @@ -79,7 +80,7 @@ func TestContainer(t *testing.T) {
"docker_label_foo2": "bar2",
"docker_container_state": "running",
"docker_container_state_human": c.Container().State.String(),
"docker_container_uptime": uptime.String(),
"docker_container_uptime": strconv.Itoa(uptimeSeconds),
"docker_env_FOO": "secret-bar",
}).WithLatestControls(
controls,
Expand Down
6 changes: 3 additions & 3 deletions probe/docker/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ var (
ImageName: {ID: ImageName, Label: "Image", From: report.FromLatest, Priority: 1},
ContainerCommand: {ID: ContainerCommand, Label: "Command", From: report.FromLatest, Priority: 2},
ContainerStateHuman: {ID: ContainerStateHuman, Label: "State", From: report.FromLatest, Priority: 3},
ContainerUptime: {ID: ContainerUptime, Label: "Uptime", From: report.FromLatest, Priority: 4},
ContainerUptime: {ID: ContainerUptime, Label: "Uptime", From: report.FromLatest, Priority: 4, Datatype: report.Duration},
ContainerRestartCount: {ID: ContainerRestartCount, Label: "Restart #", From: report.FromLatest, Priority: 5},
ContainerNetworks: {ID: ContainerNetworks, Label: "Networks", From: report.FromSets, Priority: 6},
ContainerIPs: {ID: ContainerIPs, Label: "IPs", From: report.FromSets, Priority: 7},
ContainerPorts: {ID: ContainerPorts, Label: "Ports", From: report.FromSets, Priority: 8},
ContainerCreated: {ID: ContainerCreated, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 9},
ContainerCreated: {ID: ContainerCreated, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 9},
ContainerID: {ID: ContainerID, Label: "ID", From: report.FromLatest, Truncate: 12, Priority: 10},
}

Expand All @@ -47,7 +47,7 @@ var (
}

ContainerImageMetadataTemplates = report.MetadataTemplates{
report.Container: {ID: report.Container, Label: "# Containers", From: report.FromCounters, Datatype: "number", Priority: 2},
report.Container: {ID: report.Container, Label: "# Containers", From: report.FromCounters, Datatype: report.Number, Priority: 2},
}

ContainerTableTemplates = report.TableTemplates{
Expand Down
5 changes: 3 additions & 2 deletions probe/host/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package host
import (
"fmt"
"runtime"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -37,7 +38,7 @@ const (
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},
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},
Expand Down Expand Up @@ -130,7 +131,7 @@ func (r *Reporter) Report() (report.Report, error) {
HostName: r.hostName,
OS: runtime.GOOS,
KernelVersion: kernel,
Uptime: uptime.String(),
Uptime: strconv.Itoa(int(uptime / time.Second)), // uptime in seconds
ScopeVersion: r.version,
}).
WithSets(report.MakeSets().
Expand Down
4 changes: 2 additions & 2 deletions probe/host/reporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestReporter(t *testing.T) {
host.CPUUsage: report.MakeSingletonMetric(timestamp, 30.0).WithMax(100.0),
host.MemoryUsage: report.MakeSingletonMetric(timestamp, 60.0).WithMax(100.0),
}
uptime = "278h55m43s"
uptime = "3600" // one hour
kernel = "release version"
_, ipnet, _ = net.ParseCIDR(network)
)
Expand All @@ -51,7 +51,7 @@ func TestReporter(t *testing.T) {
}()
host.GetKernelReleaseAndVersion = func() (string, string, error) { return release, version, nil }
host.GetLoad = func(time.Time) report.Metrics { return metrics }
host.GetUptime = func() (time.Duration, error) { return time.ParseDuration(uptime) }
host.GetUptime = func() (time.Duration, error) { return time.Hour, nil }
host.GetCPUUsagePercent = func() (float64, float64) { return 30.0, 100.0 }
host.GetMemoryUsageBytes = func() (float64, float64) { return 60.0, 100.0 }
host.GetLocalNetworks = func() ([]*net.IPNet, error) { return []*net.IPNet{ipnet}, nil }
Expand Down
52 changes: 26 additions & 26 deletions probe/kubernetes/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,77 +29,77 @@ const (
var (
PodMetadataTemplates = report.MetadataTemplates{
State: {ID: State, Label: "State", From: report.FromLatest, Priority: 2},
IP: {ID: IP, Label: "IP", From: report.FromLatest, Datatype: "ip", Priority: 3},
report.Container: {ID: report.Container, Label: "# Containers", From: report.FromCounters, Datatype: "number", Priority: 4},
IP: {ID: IP, Label: "IP", From: report.FromLatest, Datatype: report.IP, Priority: 3},
report.Container: {ID: report.Container, Label: "# Containers", From: report.FromCounters, Datatype: report.Number, Priority: 4},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 5},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 6},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 6},
RestartCount: {ID: RestartCount, Label: "Restart #", From: report.FromLatest, Priority: 7},
}

PodMetricTemplates = docker.ContainerMetricTemplates

ServiceMetadataTemplates = report.MetadataTemplates{
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
PublicIP: {ID: PublicIP, Label: "Public IP", From: report.FromLatest, Datatype: "ip", Priority: 4},
IP: {ID: IP, Label: "Internal IP", From: report.FromLatest, Datatype: "ip", Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 6},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 3},
PublicIP: {ID: PublicIP, Label: "Public IP", From: report.FromLatest, Datatype: report.IP, Priority: 4},
IP: {ID: IP, Label: "Internal IP", From: report.FromLatest, Datatype: report.IP, Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: report.Number, Priority: 6},
}

ServiceMetricTemplates = PodMetricTemplates

DeploymentMetadataTemplates = report.MetadataTemplates{
NodeType: {ID: NodeType, Label: "Type", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: "number", Priority: 4},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: "number", Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 6},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: report.Number, Priority: 4},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: report.Number, Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: report.Number, Priority: 6},
Strategy: {ID: Strategy, Label: "Strategy", From: report.FromLatest, Priority: 7},
}

DeploymentMetricTemplates = ReplicaSetMetricTemplates

ReplicaSetMetadataTemplates = report.MetadataTemplates{
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: "number", Priority: 4},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: "number", Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 6},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: report.Number, Priority: 4},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: report.Number, Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: report.Number, Priority: 6},
}

ReplicaSetMetricTemplates = PodMetricTemplates

DaemonSetMetadataTemplates = report.MetadataTemplates{
NodeType: {ID: NodeType, Label: "Type", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: "number", Priority: 4},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 5},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 3},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: report.Number, Priority: 4},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: report.Number, Priority: 5},
}

DaemonSetMetricTemplates = PodMetricTemplates

StatefulSetMetadataTemplates = report.MetadataTemplates{
NodeType: {ID: NodeType, Label: "Type", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: "number", Priority: 4},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: "number", Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 6},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: report.Number, Priority: 4},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: report.Number, Priority: 5},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: report.Number, Priority: 6},
}

StatefulSetMetricTemplates = PodMetricTemplates

CronJobMetadataTemplates = report.MetadataTemplates{
NodeType: {ID: NodeType, Label: "Type", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: report.DateTime, Priority: 3},
Schedule: {ID: Schedule, Label: "Schedule", From: report.FromLatest, Priority: 4},
LastScheduled: {ID: LastScheduled, Label: "Last Scheduled", From: report.FromLatest, Datatype: "datetime", Priority: 5},
LastScheduled: {ID: LastScheduled, Label: "Last Scheduled", From: report.FromLatest, Datatype: report.DateTime, Priority: 5},
Suspended: {ID: Suspended, Label: "Suspended", From: report.FromLatest, Priority: 6},
ActiveJobs: {ID: ActiveJobs, Label: "# Jobs", From: report.FromLatest, Datatype: "number", Priority: 7},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 8},
ActiveJobs: {ID: ActiveJobs, Label: "# Jobs", From: report.FromLatest, Datatype: report.Number, Priority: 7},
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: report.Number, Priority: 8},
}

CronJobMetricTemplates = PodMetricTemplates
Expand Down
6 changes: 3 additions & 3 deletions probe/process/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ const (
// Exposed for testing
var (
MetadataTemplates = report.MetadataTemplates{
PID: {ID: PID, Label: "PID", From: report.FromLatest, Datatype: "number", Priority: 1},
PID: {ID: PID, Label: "PID", From: report.FromLatest, Datatype: report.Number, Priority: 1},
Cmdline: {ID: Cmdline, Label: "Command", From: report.FromLatest, Priority: 2},
PPID: {ID: PPID, Label: "Parent PID", From: report.FromLatest, Datatype: "number", Priority: 3},
Threads: {ID: Threads, Label: "# Threads", From: report.FromLatest, Datatype: "number", Priority: 4},
PPID: {ID: PPID, Label: "Parent PID", From: report.FromLatest, Datatype: report.Number, Priority: 3},
Threads: {ID: Threads, Label: "# Threads", From: report.FromLatest, Datatype: report.Number, Priority: 4},
}

MetricTemplates = report.MetricTemplates{
Expand Down
8 changes: 4 additions & 4 deletions render/detailed/connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ const (
// Exported for testing
var (
NormalColumns = []Column{
{ID: portKey, Label: portLabel, Datatype: "number"},
{ID: countKey, Label: countLabel, Datatype: "number", DefaultSort: true},
{ID: portKey, Label: portLabel, Datatype: report.Number},
{ID: countKey, Label: countLabel, Datatype: report.Number, DefaultSort: true},
}
InternetColumns = []Column{
{ID: remoteKey, Label: remoteLabel},
{ID: portKey, Label: portLabel, Datatype: "number"},
{ID: countKey, Label: countLabel, Datatype: "number", DefaultSort: true},
{ID: portKey, Label: portLabel, Datatype: report.Number},
{ID: countKey, Label: countLabel, Datatype: report.Number, DefaultSort: true},
}
)

Expand Down
Loading