func translateMemory()

in kubelet-to-gcm/monitor/kubelet/translate.go [519:586]


func translateMemory(memory *stats.MemoryStats, tsFactory *timeSeriesFactory, startTime time.Time, memUsedMD *metricMetadata, memTotalMD *metricMetadata, pageFaultsMD *metricMetadata, component string) ([]*v3.TimeSeries, error) {
	var timeSeries []*v3.TimeSeries

	if memory == nil {
		return nil, fmt.Errorf("Memory information missing.")
	}

	// Only send page fault metric if start time is before current time. Right after container is started, kubelet can return start time == end time.
	if pageFaultsMD != nil && memory.Time.Time.After(startTime) {
		if memory.MajorPageFaults != nil {
			// Major page faults.
			majorPFPoint := tsFactory.newPoint(&v3.TypedValue{
				Int64Value:      monitor.Int64Ptr(int64(*memory.MajorPageFaults)),
				ForceSendFields: []string{"Int64Value"},
			}, startTime, memory.Time.Time, pageFaultsMD.MetricKind)
			timeSeries = append(timeSeries, tsFactory.newTimeSeries(majorPageFaultLabels, pageFaultsMD, majorPFPoint))
		}
		if memory.PageFaults != nil {
			// Minor page faults.
			minorPFPoint := tsFactory.newPoint(&v3.TypedValue{
				Int64Value:      monitor.Int64Ptr(int64(*memory.PageFaults - *memory.MajorPageFaults)),
				ForceSendFields: []string{"Int64Value"},
			}, startTime, memory.Time.Time, pageFaultsMD.MetricKind)
			timeSeries = append(timeSeries, tsFactory.newTimeSeries(minorPageFaultLabels, pageFaultsMD, minorPFPoint))
		}
	}

	if memUsedMD != nil {
		if memory.WorkingSetBytes == nil {
			return nil, fmt.Errorf("WorkingSetBytes information missing in MemoryStats %v", memory)
		}
		// Non-evictable memory.
		nonEvictMemPoint := tsFactory.newPoint(&v3.TypedValue{
			Int64Value:      monitor.Int64Ptr(int64(*memory.WorkingSetBytes)),
			ForceSendFields: []string{"Int64Value"},
		}, startTime, memory.Time.Time, memUsedMD.MetricKind)
		labels := map[string]string{"memory_type": "non-evictable"}
		if component != "" {
			labels["component"] = component
		}
		timeSeries = append(timeSeries, tsFactory.newTimeSeries(labels, memUsedMD, nonEvictMemPoint))

		if memory.UsageBytes != nil {
			// Evictable memory.
			evictMemPoint := tsFactory.newPoint(&v3.TypedValue{
				Int64Value:      monitor.Int64Ptr(int64(*memory.UsageBytes - *memory.WorkingSetBytes)),
				ForceSendFields: []string{"Int64Value"},
			}, startTime, memory.Time.Time, memUsedMD.MetricKind)
			labels = map[string]string{"memory_type": "evictable"}
			if component != "" {
				labels["component"] = component
			}
			timeSeries = append(timeSeries, tsFactory.newTimeSeries(labels, memUsedMD, evictMemPoint))
		}
	}

	if memTotalMD != nil {
		// Available memory. This may or may not be present, so don't fail if it's absent.
		if memory.AvailableBytes != nil {
			availableMemPoint := tsFactory.newPoint(&v3.TypedValue{
				Int64Value:      monitor.Int64Ptr(int64(*memory.AvailableBytes)),
				ForceSendFields: []string{"Int64Value"},
			}, startTime, memory.Time.Time, memTotalMD.MetricKind)
			timeSeries = append(timeSeries, tsFactory.newTimeSeries(noLabels, memTotalMD, availableMemPoint))
		}
	}
	return timeSeries, nil
}