001package io.prometheus.metrics.model.snapshots; 002 003public abstract class DataPointSnapshot { 004 private final Labels labels; 005 private final long createdTimestampMillis; 006 private final long scrapeTimestampMillis; 007 008 protected DataPointSnapshot(Labels labels, long createdTimestampMillis, long scrapeTimestampMillis) { 009 this.labels = labels; 010 this.createdTimestampMillis = createdTimestampMillis; 011 this.scrapeTimestampMillis = scrapeTimestampMillis; 012 validate(); 013 } 014 015 private void validate() { 016 if (labels == null) { 017 throw new IllegalArgumentException("Labels cannot be null. Use Labels.EMPTY if there are no labels."); 018 } 019 if (createdTimestampMillis < 0) { 020 throw new IllegalArgumentException("Created timestamp cannot be negative. Use 0 if the metric doesn't have a created timestamp."); 021 } 022 if (scrapeTimestampMillis < 0) { 023 throw new IllegalArgumentException("Scrape timestamp cannot be negative. Use 0 to indicate that the Prometheus server should set the scrape timestamp."); 024 } 025 if (hasCreatedTimestamp() && hasScrapeTimestamp()) { 026 if (scrapeTimestampMillis < createdTimestampMillis) { 027 throw new IllegalArgumentException("The scrape timestamp cannot be before the created timestamp"); 028 } 029 } 030 } 031 032 public Labels getLabels() { 033 return labels; 034 } 035 036 public boolean hasScrapeTimestamp() { 037 return scrapeTimestampMillis != 0L; 038 } 039 040 /** 041 * This will only return a reasonable value if {@link #hasScrapeTimestamp()} is true. 042 */ 043 public long getScrapeTimestampMillis() { 044 return scrapeTimestampMillis; 045 } 046 047 public boolean hasCreatedTimestamp() { 048 return createdTimestampMillis != 0L; 049 } 050 051 /** 052 * This will only return a reasonable value if {@link #hasCreatedTimestamp()} is true. 053 * Some metrics like Gauge don't have created timestamps. For these metrics {@link #hasCreatedTimestamp()} 054 * is always false. 055 */ 056 public long getCreatedTimestampMillis() { 057 return createdTimestampMillis; 058 } 059 060 public static abstract class Builder<T extends Builder<T>> { 061 062 protected Labels labels = Labels.EMPTY; 063 protected long scrapeTimestampMillis = 0L; 064 065 public T labels(Labels labels) { 066 this.labels = labels; 067 return self(); 068 } 069 070 /** 071 * In most cases you should not set a scrape timestamp, 072 * because the scrape timestamp is set by the Prometheus server during scraping. 073 * Exceptions include mirroring metrics with given timestamps from other metric sources. 074 */ 075 public T scrapeTimestampMillis(long scrapeTimestampMillis) { 076 this.scrapeTimestampMillis = scrapeTimestampMillis; 077 return self(); 078 } 079 080 protected abstract T self(); 081 } 082}