func()

in pkg/export/series_cache.go [341:474]


func (c *seriesCache) populate(ref storage.SeriesRef, entry *seriesCacheEntry, externalLabels labels.Labels, getMetadata MetadataFunc) error {
	if entry.lset.IsEmpty() {
		entry.lset = c.getLabelsByRef(ref)
		if entry.lset.IsEmpty() {
			return errors.New("series reference invalid")
		}
		entry.dropped = !c.matchers.Matches(entry.lset)
	}
	if entry.dropped {
		return nil
	}
	// Break the series into resource and metric labels.
	resource, metricLabels, err := extractResource(externalLabels, entry.lset)
	if err != nil {
		return fmt.Errorf("extracting resource for series %s failed: %w", entry.lset, err)
	}

	// Remove the __name__ label as it becomes the metric type in the GCM time series.
	metricLabelsBuilder := labels.NewBuilder(metricLabels)
	metricLabelsBuilder.Del(labels.MetricName)
	metricLabels = metricLabelsBuilder.Labels()

	// Drop series with too many labels.
	// TODO: remove once field limit is lifted in the GCM API.
	if metricLabels.Len() > maxLabelCount {
		return fmt.Errorf("metric labels %s exceed the limit of %d", metricLabels, maxLabelCount)
	}

	var (
		metricName     = entry.lset.Get("__name__")
		baseMetricName = metricName
		suffix         metricSuffix
	)
	metadata, ok := getMetadata(metricName)
	if !ok {
		// The full name didn't turn anything up. Check again in case it's a summary
		// or histogram without the metric name suffix. If the underlying target
		// returned the OpenMetrics format, counter metadata is also stored with the
		// _total suffix stripped.
		var ok bool
		if baseMetricName, suffix, ok = splitMetricSuffix(metricName); ok {
			metadata, ok = getMetadata(baseMetricName)
		}
		if !ok {
			return fmt.Errorf("no metadata found for metric name %q", metricName)
		}
	}
	// Handle label modifications for histograms early so we don't build the label map twice.
	// We have to remove the 'le' label which defines the bucket boundary.
	if metadata.Type == textparse.MetricTypeHistogram {
		metricLabelsBuilder := labels.NewBuilder(metricLabels)
		metricLabelsBuilder.Del(labels.BucketLabel)
		metricLabels = metricLabelsBuilder.Labels()
	}

	newSeries := func(mtype string, kind metric_pb.MetricDescriptor_MetricKind, vtype metric_pb.MetricDescriptor_ValueType) hashedSeries {
		s := &monitoring_pb.TimeSeries{
			Resource:   resource,
			Metric:     &metric_pb.Metric{Type: mtype, Labels: metricLabels.Map()},
			MetricKind: kind,
			ValueType:  vtype,
		}
		return hashedSeries{hash: hashSeries(s), proto: s}
	}
	var protos cachedProtos

	switch metadata.Type {
	case textparse.MetricTypeCounter:
		protos.cumulative = newSeries(
			c.getMetricType(metricName, gcmMetricSuffixCounter, gcmMetricSuffixNone),
			metric_pb.MetricDescriptor_CUMULATIVE,
			metric_pb.MetricDescriptor_DOUBLE)

	case textparse.MetricTypeGauge:
		protos.gauge = newSeries(
			c.getMetricType(metricName, gcmMetricSuffixGauge, gcmMetricSuffixNone),
			metric_pb.MetricDescriptor_GAUGE,
			metric_pb.MetricDescriptor_DOUBLE)

	case textparse.MetricTypeUnknown:
		protos.gauge = newSeries(
			c.getMetricType(metricName, gcmMetricSuffixUnknown, gcmMetricSuffixNone),
			metric_pb.MetricDescriptor_GAUGE,
			metric_pb.MetricDescriptor_DOUBLE)
		protos.cumulative = newSeries(
			c.getMetricType(metricName, gcmMetricSuffixUnknown, gcmMetricSuffixCounter),
			metric_pb.MetricDescriptor_CUMULATIVE,
			metric_pb.MetricDescriptor_DOUBLE)

	case textparse.MetricTypeSummary:
		switch suffix {
		case metricSuffixSum:
			protos.cumulative = newSeries(
				c.getMetricType(metricName, gcmMetricSuffixSummary, gcmMetricSuffixCounter),
				metric_pb.MetricDescriptor_CUMULATIVE,
				metric_pb.MetricDescriptor_DOUBLE)

		case metricSuffixCount:
			protos.cumulative = newSeries(
				c.getMetricType(metricName, gcmMetricSuffixSummary, gcmMetricSuffixNone),
				metric_pb.MetricDescriptor_CUMULATIVE,
				metric_pb.MetricDescriptor_DOUBLE)

		case metricSuffixNone: // Actual quantiles.
			protos.gauge = newSeries(
				c.getMetricType(metricName, gcmMetricSuffixSummary, gcmMetricSuffixNone),
				metric_pb.MetricDescriptor_GAUGE,
				metric_pb.MetricDescriptor_DOUBLE)

		default:
			return fmt.Errorf("unexpected metric name suffix %q for metric %q", suffix, metricName)
		}

	case textparse.MetricTypeHistogram:
		protos.cumulative = newSeries(
			c.getMetricType(baseMetricName, gcmMetricSuffixHistogram, gcmMetricSuffixNone),
			metric_pb.MetricDescriptor_CUMULATIVE,
			metric_pb.MetricDescriptor_DISTRIBUTION)

	default:
		return fmt.Errorf("unexpected metric type %s for metric %q", metadata.Type, metricName)
	}

	c.pool.release(entry.protos.gauge.proto)
	c.pool.release(entry.protos.cumulative.proto)
	c.pool.intern(protos.gauge.proto)
	c.pool.intern(protos.cumulative.proto)

	entry.protos = protos
	entry.metadata = metadata
	entry.suffix = suffix

	return nil
}