001package io.prometheus.metrics.expositionformats; 002 003import io.prometheus.metrics.annotations.StableApi; 004import io.prometheus.metrics.config.ExporterProperties; 005import io.prometheus.metrics.config.OpenMetrics2Properties; 006import io.prometheus.metrics.config.PrometheusProperties; 007import javax.annotation.Nullable; 008 009@StableApi 010public class ExpositionFormats { 011 012 private final PrometheusProtobufWriter prometheusProtobufWriter; 013 private final PrometheusTextFormatWriter prometheusTextFormatWriter; 014 private final OpenMetricsTextFormatWriter openMetricsTextFormatWriter; 015 private final OpenMetrics2TextFormatWriter openMetrics2TextFormatWriter; 016 017 private ExpositionFormats( 018 PrometheusProtobufWriter prometheusProtobufWriter, 019 PrometheusTextFormatWriter prometheusTextFormatWriter, 020 OpenMetricsTextFormatWriter openMetricsTextFormatWriter, 021 OpenMetrics2TextFormatWriter openMetrics2TextFormatWriter) { 022 this.prometheusProtobufWriter = prometheusProtobufWriter; 023 this.prometheusTextFormatWriter = prometheusTextFormatWriter; 024 this.openMetricsTextFormatWriter = openMetricsTextFormatWriter; 025 this.openMetrics2TextFormatWriter = openMetrics2TextFormatWriter; 026 } 027 028 public static ExpositionFormats init() { 029 return init(PrometheusProperties.get()); 030 } 031 032 @SuppressWarnings("deprecation") 033 public static ExpositionFormats init(PrometheusProperties properties) { 034 ExporterProperties exporterProps = properties.getExporterProperties(); 035 OpenMetrics2Properties om2Props = properties.getOpenMetrics2Properties(); 036 037 return new ExpositionFormats( 038 new PrometheusProtobufWriter(), 039 PrometheusTextFormatWriter.builder() 040 .setIncludeCreatedTimestamps(exporterProps.getIncludeCreatedTimestamps()) 041 .setTimestampsInMs(exporterProps.getPrometheusTimestampsInMs()) 042 .build(), 043 OpenMetricsTextFormatWriter.builder() 044 .setCreatedTimestampsEnabled(exporterProps.getIncludeCreatedTimestamps()) 045 .setExemplarsOnAllMetricTypesEnabled(exporterProps.getExemplarsOnAllMetricTypes()) 046 .build(), 047 OpenMetrics2TextFormatWriter.builder() 048 .setOpenMetrics2Properties(om2Props) 049 .setCreatedTimestampsEnabled(exporterProps.getIncludeCreatedTimestamps()) 050 .setExemplarsOnAllMetricTypesEnabled(exporterProps.getExemplarsOnAllMetricTypes()) 051 .build()); 052 } 053 054 /** 055 * @deprecated Use {@link #init(PrometheusProperties)} instead. 056 */ 057 @Deprecated 058 @SuppressWarnings({"InlineMeSuggester"}) 059 public static ExpositionFormats init(ExporterProperties properties) { 060 return init(PrometheusProperties.builder().exporterProperties(properties).build()); 061 } 062 063 public ExpositionFormatWriter findWriter(@Nullable String acceptHeader) { 064 if (prometheusProtobufWriter.accepts(acceptHeader)) { 065 return prometheusProtobufWriter; 066 } 067 068 if (isOpenMetrics2Enabled() && openMetrics2TextFormatWriter.accepts(acceptHeader)) { 069 if (openMetrics2TextFormatWriter.getOpenMetrics2Properties().getContentNegotiation()) { 070 String version = parseOpenMetricsVersion(acceptHeader); 071 if ("2.0.0".equals(version)) { 072 return openMetrics2TextFormatWriter; 073 } 074 // version=1.0.0 or no version: fall through to OM1. 075 } else { 076 // contentNegotiation=false: OM2 handles all OpenMetrics requests. 077 return openMetrics2TextFormatWriter; 078 } 079 } 080 081 if (openMetricsTextFormatWriter.accepts(acceptHeader)) { 082 return openMetricsTextFormatWriter; 083 } 084 085 return prometheusTextFormatWriter; 086 } 087 088 private boolean isOpenMetrics2Enabled() { 089 return openMetrics2TextFormatWriter.getOpenMetrics2Properties().getEnabled(); 090 } 091 092 public PrometheusProtobufWriter getPrometheusProtobufWriter() { 093 return prometheusProtobufWriter; 094 } 095 096 public PrometheusTextFormatWriter getPrometheusTextFormatWriter() { 097 return prometheusTextFormatWriter; 098 } 099 100 public OpenMetricsTextFormatWriter getOpenMetricsTextFormatWriter() { 101 return openMetricsTextFormatWriter; 102 } 103 104 public OpenMetrics2TextFormatWriter getOpenMetrics2TextFormatWriter() { 105 return openMetrics2TextFormatWriter; 106 } 107 108 @Nullable 109 private static String parseOpenMetricsVersion(@Nullable String acceptHeader) { 110 if (acceptHeader == null) { 111 return null; 112 } 113 for (String mediaType : acceptHeader.split(",")) { 114 if (mediaType.contains("application/openmetrics-text")) { 115 for (String param : mediaType.split(";")) { 116 String[] tokens = param.split("="); 117 if (tokens.length == 2) { 118 String key = tokens[0].trim(); 119 String value = tokens[1].trim(); 120 if (key.equals("version")) { 121 return value; 122 } 123 } 124 } 125 return null; 126 } 127 } 128 return null; 129 } 130}