Example #1
0
func (t *Translator) translateNode(node stats.NodeStats) ([]*v3.TimeSeries, error) {
	var timeSeries []*v3.TimeSeries

	monitoredLabels := map[string]string{
		"project_id":     t.project,
		"cluster_name":   t.cluster,
		"zone":           t.zone,
		"instance_id":    t.instanceID,
		"namespace_id":   "",
		"pod_id":         "machine",
		"container_name": "",
	}
	tsFactory := newTimeSeriesFactory(monitoredLabels, t.resolution)

	// Uptime. This is embedded: there's no nil check.
	now := time.Now()
	uptimePoint := &v3.Point{
		Interval: &v3.TimeInterval{
			EndTime:   now.Format(time.RFC3339),
			StartTime: now.Add(-1 * t.resolution).Format(time.RFC3339),
		},
		Value: &v3.TypedValue{
			DoubleValue: monitor.Float64Ptr(float64(time.Since(node.StartTime.Time).Seconds())),
		},
	}
	timeSeries = append(timeSeries, tsFactory.newTimeSeries(noLabels, uptimeMD, uptimePoint))

	// Memory stats.
	memTS, err := translateMemory(node.Memory, tsFactory)
	if err != nil {
		return nil, err
	}
	timeSeries = append(timeSeries, memTS...)

	// File-system stats.
	fsTS, err := translateFS("/", node.Fs, tsFactory)
	if err != nil {
		return nil, err
	}
	timeSeries = append(timeSeries, fsTS...)

	// CPU stats.
	cpuTS, err := translateCPU(node.CPU, tsFactory)
	if err != nil {
		return nil, err
	}
	timeSeries = append(timeSeries, cpuTS...)

	return timeSeries, nil
}
Example #2
0
// translateCPU creates all the TimeSeries for a give CPUStat.
func translateCPU(cpu *stats.CPUStats, tsFactory *timeSeriesFactory) ([]*v3.TimeSeries, error) {
	var timeSeries []*v3.TimeSeries

	// First check that all required information is present.
	if cpu == nil {
		return nil, fmt.Errorf("CPU information missing.")
	}
	if cpu.UsageNanoCores == nil {
		return nil, fmt.Errorf("UsageNanoCores missing from CPUStats %v", cpu)
	}
	if cpu.UsageCoreNanoSeconds == nil {
		return nil, fmt.Errorf("UsageCoreNanoSeconds missing from CPUStats %v", cpu)
	}

	// Total CPU utilization for all time. Convert from nanosec to sec.
	cpuTotalPoint := tsFactory.newPoint(&v3.TypedValue{
		DoubleValue:     monitor.Float64Ptr(float64(*cpu.UsageCoreNanoSeconds) / float64(1000*1000*1000)),
		ForceSendFields: []string{"DoubleValue"},
	}, cpu.Time.Time, usageTimeMD.MetricKind)
	timeSeries = append(timeSeries, tsFactory.newTimeSeries(noLabels, usageTimeMD, cpuTotalPoint))
	return timeSeries, nil
}
Example #3
0
func (t *Translator) translateContainers(pods []stats.PodStats) ([]*v3.TimeSeries, error) {
	var timeSeries []*v3.TimeSeries
	metricsSeen := make(map[string]time.Time)
	metrics := make(map[string][]*v3.TimeSeries)

	for _, pod := range pods {
		namespace := pod.PodRef.Namespace
		podID := pod.PodRef.Name
		// There can be duplicate data points for containers, so only
		// take the latest one.
		for _, container := range pod.Containers {
			containerName := container.Name
			// Check for duplicates
			if container.StartTime.Time.Before(metricsSeen[containerName]) || container.StartTime.Time.Equal(metricsSeen[containerName]) {
				continue
			}
			metricsSeen[containerName] = container.StartTime.Time
			var containerSeries []*v3.TimeSeries

			monitoredLabels := map[string]string{
				"project_id":     t.project,
				"cluster_name":   t.cluster,
				"zone":           t.zone,
				"instance_id":    t.instanceID,
				"namespace_id":   namespace,
				"pod_id":         podID,
				"container_name": containerName,
			}
			tsFactory := newTimeSeriesFactory(monitoredLabels, t.resolution)

			// Uptime. This is embedded: there's no nil check.
			now := time.Now()
			uptimePoint := &v3.Point{
				Interval: &v3.TimeInterval{
					EndTime:   now.Format(time.RFC3339),
					StartTime: container.StartTime.Time.Format(time.RFC3339),
				},
				Value: &v3.TypedValue{
					DoubleValue:     monitor.Float64Ptr(float64(time.Since(container.StartTime.Time).Seconds())),
					ForceSendFields: []string{"DoubleValue"},
				},
			}
			containerSeries = append(containerSeries, tsFactory.newTimeSeries(noLabels, uptimeMD, uptimePoint))

			// Memory stats.
			memTS, err := translateMemory(container.Memory, tsFactory)
			if err != nil {
				return nil, err
			}
			containerSeries = append(containerSeries, memTS...)

			// File-system stats.
			rootfsTS, err := translateFS("/", container.Rootfs, tsFactory)
			if err != nil {
				return nil, err
			}
			containerSeries = append(containerSeries, rootfsTS...)

			logfsTS, err := translateFS("logs", container.Logs, tsFactory)
			if err != nil {
				return nil, err
			}
			containerSeries = append(containerSeries, logfsTS...)

			// CPU stats.
			cpuTS, err := translateCPU(container.CPU, tsFactory)
			if err != nil {
				return nil, err
			}
			containerSeries = append(containerSeries, cpuTS...)

			metrics[containerName] = containerSeries
		}
	}

	// Flatten the deduplicated metrics.
	for _, containerSeries := range metrics {
		timeSeries = append(timeSeries, containerSeries...)
	}
	return timeSeries, nil
}