001package io.prometheus.client.exporter.common;
002
003import io.prometheus.client.Collector;
004
005import java.util.Collections;
006import java.util.Enumeration;
007import java.io.IOException;
008import java.io.Writer;
009
010public class TextFormat {
011  /**
012   * Write out the text version 0.0.4 of the given MetricFamilySamples.
013   */
014  public static void write004(Writer writer, Enumeration<Collector.MetricFamilySamples> mfs) throws IOException {
015    /* See http://prometheus.io/docs/instrumenting/exposition_formats/
016     * for the output format specification. */
017    for (Collector.MetricFamilySamples metricFamilySamples: Collections.list(mfs)) {
018      writer.write("# HELP " + metricFamilySamples.name + " " + escapeHelp(metricFamilySamples.help) + "\n");
019      writer.write("# TYPE " + metricFamilySamples.name + " " + typeString(metricFamilySamples.type) + "\n");
020      for (Collector.MetricFamilySamples.Sample sample: metricFamilySamples.samples) {
021        writer.write(sample.name);
022        if (sample.labelNames.size() > 0) {
023          writer.write("{");
024          for (int i = 0; i < sample.labelNames.size(); ++i) {
025            writer.write(String.format("%s=\"%s\",",
026                sample.labelNames.get(i),  escapeLabelValue(sample.labelValues.get(i))));
027          }
028          writer.write("}");
029        }
030        writer.write(" " + Collector.doubleToGoString(sample.value) + "\n");
031      }
032    }
033  }
034
035  /**
036   * Content-type for text verision 0.0.4.
037   */
038  public final static String CONTENT_TYPE_004 = "text/plain; version=0.0.4; charset=utf-8";
039
040  static String escapeHelp(String s) {
041    return s.replace("\\", "\\\\").replace("\n", "\\n");
042  }
043  static String escapeLabelValue(String s) {
044    return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n");
045  }
046
047  static String typeString(Collector.Type t) {
048    switch (t) {
049      case GAUGE:
050        return "gauge";
051      case COUNTER:
052        return "counter";
053      case SUMMARY:
054        return "summary";
055      case HISTOGRAM:
056        return "histogram";
057      default:
058        return "untyped";
059    }
060  }
061}