001package io.prometheus.metrics.model.snapshots; 002 003import io.prometheus.metrics.annotations.StableApi; 004import io.prometheus.metrics.config.EscapingScheme; 005import java.util.ArrayList; 006import java.util.Collection; 007import java.util.List; 008import javax.annotation.Nullable; 009 010/** Immutable snapshot of an Info metric. */ 011@StableApi 012public final class InfoSnapshot extends MetricSnapshot { 013 014 /** 015 * To create a new {@link InfoSnapshot}, you can either call the constructor directly or use the 016 * builder with {@link InfoSnapshot#builder()}. 017 * 018 * @param metadata the metric name in metadata must not include the {@code _info} suffix. See 019 * {@link MetricMetadata} for more naming conventions. The metadata must not have a unit. 020 * @param data the constructor will create a sorted copy of the collection. 021 */ 022 public InfoSnapshot(MetricMetadata metadata, Collection<InfoDataPointSnapshot> data) { 023 this(metadata, data, false); 024 if (metadata.hasUnit()) { 025 throw new IllegalArgumentException("An Info metric cannot have a unit."); 026 } 027 } 028 029 private InfoSnapshot( 030 MetricMetadata metadata, Collection<InfoDataPointSnapshot> data, boolean internal) { 031 super(metadata, data, internal); 032 } 033 034 @SuppressWarnings("unchecked") 035 @Override 036 public List<InfoDataPointSnapshot> getDataPoints() { 037 return (List<InfoDataPointSnapshot>) dataPoints; 038 } 039 040 @SuppressWarnings("unchecked") 041 @Override 042 MetricSnapshot escape( 043 EscapingScheme escapingScheme, List<? extends DataPointSnapshot> dataPointSnapshots) { 044 return new InfoSnapshot( 045 getMetadata().escape(escapingScheme), 046 (List<InfoSnapshot.InfoDataPointSnapshot>) dataPointSnapshots, 047 true); 048 } 049 050 public static class InfoDataPointSnapshot extends DataPointSnapshot { 051 052 /** 053 * To create a new {@link InfoDataPointSnapshot}, you can either call the constructor directly 054 * or use the Builder with {@link InfoDataPointSnapshot#builder()}. 055 * 056 * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. 057 */ 058 public InfoDataPointSnapshot(Labels labels) { 059 this(labels, 0L); 060 } 061 062 /** 063 * Constructor with an additional scrape timestamp. This is only useful in rare cases as the 064 * scrape timestamp is usually set by the Prometheus server during scraping. Exceptions include 065 * mirroring metrics with given timestamps from other metric sources. 066 */ 067 public InfoDataPointSnapshot(Labels labels, long scrapeTimestampMillis) { 068 this(labels, scrapeTimestampMillis, false); 069 } 070 071 private InfoDataPointSnapshot(Labels labels, long scrapeTimestampMillis, boolean internal) { 072 super(labels, 0L, scrapeTimestampMillis, internal); 073 } 074 075 public static Builder builder() { 076 return new Builder(); 077 } 078 079 @Override 080 DataPointSnapshot escape(EscapingScheme escapingScheme) { 081 return new InfoSnapshot.InfoDataPointSnapshot( 082 SnapshotEscaper.escapeLabels(getLabels(), escapingScheme), 083 getScrapeTimestampMillis(), 084 true); 085 } 086 087 public static class Builder extends DataPointSnapshot.Builder<Builder> { 088 089 private Builder() {} 090 091 public InfoDataPointSnapshot build() { 092 return new InfoDataPointSnapshot(labels, scrapeTimestampMillis, true); 093 } 094 095 @Override 096 protected Builder self() { 097 return this; 098 } 099 } 100 } 101 102 public static Builder builder() { 103 return new Builder(); 104 } 105 106 public static class Builder extends MetricSnapshot.Builder<Builder> { 107 108 private final List<InfoDataPointSnapshot> dataPoints = new ArrayList<>(); 109 110 private Builder() {} 111 112 /** Add a data point. Call multiple times for adding multiple data points. */ 113 public Builder dataPoint(InfoDataPointSnapshot dataPoint) { 114 dataPoints.add(dataPoint); 115 return this; 116 } 117 118 @Override 119 public Builder unit(@Nullable Unit unit) { 120 throw new IllegalArgumentException("Info metric cannot have a unit."); 121 } 122 123 @Override 124 protected MetricMetadata buildMetadata() { 125 if (name == null) { 126 throw new IllegalArgumentException("Missing required field: name is null"); 127 } 128 return MetricMetadataSupport.infoMetadata(name, help); 129 } 130 131 @Override 132 public InfoSnapshot build() { 133 return new InfoSnapshot(buildMetadata(), dataPoints); 134 } 135 136 @Override 137 protected Builder self() { 138 return this; 139 } 140 } 141}