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