001package io.prometheus.metrics.expositionformats; 002 003import io.prometheus.metrics.annotations.StableApi; 004import io.prometheus.metrics.config.EscapingScheme; 005import io.prometheus.metrics.model.snapshots.MetricSnapshots; 006import java.io.IOException; 007import java.io.OutputStream; 008import javax.annotation.Nullable; 009 010/** 011 * Write the Prometheus protobuf format as defined in <a 012 * href="https://github.com/prometheus/client_model/tree/master/io/prometheus/client">github.com/prometheus/client_model</a>. 013 * 014 * <p>As of today, this is the only exposition format that supports native histograms. 015 */ 016@StableApi 017public class PrometheusProtobufWriter implements ExpositionFormatWriter { 018 019 @Nullable private static final ExpositionFormatWriter DELEGATE = createProtobufWriter(); 020 021 public static final String CONTENT_TYPE = 022 "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; " 023 + "encoding=delimited"; 024 025 @Nullable 026 private static ExpositionFormatWriter createProtobufWriter() { 027 try { 028 return Class.forName( 029 "io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl") 030 .asSubclass(ExpositionFormatWriter.class) 031 .getDeclaredConstructor() 032 .newInstance(); 033 } catch (Exception e) { 034 // not in classpath 035 return null; 036 } 037 } 038 039 @Override 040 public boolean accepts(@Nullable String acceptHeader) { 041 if (acceptHeader == null) { 042 return false; 043 } else { 044 return acceptHeader.contains("application/vnd.google.protobuf") 045 && acceptHeader.contains("proto=io.prometheus.client.MetricFamily"); 046 } 047 } 048 049 @Override 050 public String getContentType() { 051 return CONTENT_TYPE; 052 } 053 054 @Override 055 public boolean isAvailable() { 056 return DELEGATE != null; 057 } 058 059 @Override 060 public String toDebugString(MetricSnapshots metricSnapshots, EscapingScheme escapingScheme) { 061 return getDelegate().toDebugString(metricSnapshots, escapingScheme); 062 } 063 064 @Override 065 public void write( 066 OutputStream out, MetricSnapshots metricSnapshots, EscapingScheme escapingScheme) 067 throws IOException { 068 getDelegate().write(out, metricSnapshots, escapingScheme); 069 } 070 071 private ExpositionFormatWriter getDelegate() { 072 if (DELEGATE == null) { 073 throw new UnsupportedOperationException("Prometheus protobuf writer not available"); 074 } 075 return DELEGATE; 076 } 077}