in collector/receiver/prometheusreceiver/internal/transaction.go [82:137]
func (t *transaction) Append(ref storage.SeriesRef, ls labels.Labels, atMs int64, val float64) (storage.SeriesRef, error) {
select {
case <-t.ctx.Done():
return 0, errTransactionAborted
default:
}
if len(t.externalLabels) != 0 {
ls = append(ls, t.externalLabels...)
sort.Sort(ls)
}
if t.isNew {
if err := t.initTransaction(ls); err != nil {
return 0, err
}
}
// Any datapoint with duplicate labels MUST be rejected per:
// * https://github.com/open-telemetry/wg-prometheus/issues/44
// * https://github.com/open-telemetry/opentelemetry-collector/issues/3407
// as Prometheus rejects such too as of version 2.16.0, released on 2020-02-13.
if dupLabel, hasDup := ls.HasDuplicateLabelNames(); hasDup {
return 0, fmt.Errorf("invalid sample: non-unique label names: %q", dupLabel)
}
metricName := ls.Get(model.MetricNameLabel)
if metricName == "" {
return 0, errMetricNameNotFound
}
// See https://www.prometheus.io/docs/concepts/jobs_instances/#automatically-generated-labels-and-time-series
// up: 1 if the instance is healthy, i.e. reachable, or 0 if the scrape failed.
// But it can also be a staleNaN, which is inserted when the target goes away.
if metricName == scrapeUpMetricName && val != 1.0 && !value.IsStaleNaN(val) {
if val == 0.0 {
t.logger.Warn("Failed to scrape Prometheus endpoint",
zap.Int64("scrape_timestamp", atMs),
zap.Stringer("target_labels", ls))
} else {
t.logger.Warn("The 'up' metric contains invalid value",
zap.Float64("value", val),
zap.Int64("scrape_timestamp", atMs),
zap.Stringer("target_labels", ls))
}
}
// For the `target_info` metric we need to convert it to resource attributes.
if metricName == targetMetricName {
return 0, t.AddTargetInfo(ls)
}
curMF := t.getOrCreateMetricFamily(metricName)
return 0, curMF.addSeries(t.getSeriesRef(ls, curMF.mtype), metricName, ls, atMs, val)
}