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
}