Skip to content
Permalink
Browse files
fix duplicate typeline for prometheus type (#3137)
  • Loading branch information
Shoothzj committed Mar 29, 2022
1 parent e931dbd commit 38dc3281f5f175a7d194d4c0d4b255472886187b
Showing 4 changed files with 71 additions and 17 deletions.
@@ -172,12 +172,13 @@ public StatsLogger getStatsLogger(String scope) {

@Override
public void writeAllMetrics(Writer writer) throws IOException {
PrometheusTextFormatUtil.writeMetricsCollectedByPrometheusClient(writer, registry);
PrometheusTextFormat prometheusTextFormat = new PrometheusTextFormat();
PrometheusTextFormat.writeMetricsCollectedByPrometheusClient(writer, registry);

gauges.forEach((sc, gauge) -> PrometheusTextFormatUtil.writeGauge(writer, sc.getScope(), gauge));
counters.forEach((sc, counter) -> PrometheusTextFormatUtil.writeCounter(writer, sc.getScope(), counter));
gauges.forEach((sc, gauge) -> prometheusTextFormat.writeGauge(writer, sc.getScope(), gauge));
counters.forEach((sc, counter) -> prometheusTextFormat.writeCounter(writer, sc.getScope(), counter));
opStats.forEach((sc, opStatLogger) ->
PrometheusTextFormatUtil.writeOpStat(writer, sc.getScope(), opStatLogger));
prometheusTextFormat.writeOpStat(writer, sc.getScope(), opStatLogger));
}

@Override
@@ -24,18 +24,23 @@
import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* Logic to write metrics in Prometheus text format.
*/
public class PrometheusTextFormatUtil {
static void writeGauge(Writer w, String name, SimpleGauge<? extends Number> gauge) {
public class PrometheusTextFormat {

Set<String> metricNameSet = new HashSet<>();

void writeGauge(Writer w, String name, SimpleGauge<? extends Number> gauge) {
// Example:
// # TYPE bookie_storage_entries_count gauge
// bookie_storage_entries_count 519
try {
w.append("# TYPE ").append(name).append(" gauge\n");
writeType(w, name, "gauge");
w.append(name);
writeLabels(w, gauge.getLabels());
w.append(' ').append(gauge.getSample().toString()).append('\n');
@@ -44,12 +49,12 @@ static void writeGauge(Writer w, String name, SimpleGauge<? extends Number> gaug
}
}

static void writeCounter(Writer w, String name, LongAdderCounter counter) {
void writeCounter(Writer w, String name, LongAdderCounter counter) {
// Example:
// # TYPE jvm_threads_started_total counter
// jvm_threads_started_total 59
try {
w.append("# TYPE ").append(name).append(" counter\n");
writeType(w, name, "counter");
w.append(name);
writeLabels(w, counter.getLabels());
w.append(' ').append(counter.get().toString()).append('\n');
@@ -58,7 +63,7 @@ static void writeCounter(Writer w, String name, LongAdderCounter counter) {
}
}

static void writeOpStat(Writer w, String name, DataSketchesOpStatsLogger opStat) {
void writeOpStat(Writer w, String name, DataSketchesOpStatsLogger opStat) {
// Example:
// # TYPE bookie_journal_JOURNAL_ADD_ENTRY summary
// bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.5",} NaN
@@ -80,7 +85,7 @@ static void writeOpStat(Writer w, String name, DataSketchesOpStatsLogger opStat)
// bookie_journal_JOURNAL_ADD_ENTRY_count{success="true",} 658.0
// bookie_journal_JOURNAL_ADD_ENTRY_sum{success="true",} 1265.0800000000002
try {
w.append("# TYPE ").append(name).append(" summary\n");
writeType(w, name, "summary");
writeQuantile(w, opStat, name, false, 0.5);
writeQuantile(w, opStat, name, false, 0.75);
writeQuantile(w, opStat, name, false, 0.95);
@@ -106,7 +111,7 @@ static void writeOpStat(Writer w, String name, DataSketchesOpStatsLogger opStat)
}
}

private static void writeLabels(Writer w, Map<String, String> labels) throws IOException {
private void writeLabels(Writer w, Map<String, String> labels) throws IOException {
if (labels.isEmpty()) {
return;
}
@@ -116,7 +121,7 @@ private static void writeLabels(Writer w, Map<String, String> labels) throws IOE
w.append('}');
}

private static void writeLabelsNoBraces(Writer w, Map<String, String> labels) throws IOException {
private void writeLabelsNoBraces(Writer w, Map<String, String> labels) throws IOException {
if (labels.isEmpty()) {
return;
}
@@ -134,7 +139,7 @@ private static void writeLabelsNoBraces(Writer w, Map<String, String> labels) th
}
}

private static void writeQuantile(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success,
private void writeQuantile(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success,
double quantile) throws IOException {
w.append(name)
.append("{success=\"").append(success.toString())
@@ -148,7 +153,7 @@ private static void writeQuantile(Writer w, DataSketchesOpStatsLogger opStat, St
.append(Double.toString(opStat.getQuantileValue(success, quantile))).append('\n');
}

private static void writeCount(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success)
private void writeCount(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success)
throws IOException {
w.append(name).append("_count{success=\"").append(success.toString()).append("\"");
if (!opStat.getLabels().isEmpty()) {
@@ -159,7 +164,7 @@ private static void writeCount(Writer w, DataSketchesOpStatsLogger opStat, Strin
.append(Long.toString(opStat.getCount(success))).append('\n');
}

private static void writeSum(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success)
private void writeSum(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success)
throws IOException {
w.append(name).append("_sum{success=\"").append(success.toString()).append("\"");
if (!opStat.getLabels().isEmpty()) {
@@ -195,4 +200,13 @@ static void writeMetricsCollectedByPrometheusClient(Writer w, CollectorRegistry
}
}
}

void writeType(Writer w, String name, String type) throws IOException {
if (metricNameSet.contains(name)) {
return;
}
metricNameSet.add(name);
w.append("# TYPE ").append(name).append(" ").append(type).append("\n");
}

}
@@ -0,0 +1,39 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.bookkeeper.stats.prometheus;

import java.io.IOException;
import java.io.StringWriter;
import org.junit.Assert;
import org.junit.Test;

/**
* Test for {@link PrometheusTextFormat}.
*/
public class PrometheusTextFormatTest {

@Test
public void testPrometheusTypeDuplicate() throws IOException {
PrometheusTextFormat prometheusTextFormat = new PrometheusTextFormat();
StringWriter writer = new StringWriter();
prometheusTextFormat.writeType(writer, "counter", "gauge");
prometheusTextFormat.writeType(writer, "counter", "gauge");
String string = writer.toString();
Assert.assertEquals("# TYPE counter gauge\n", string);
}

}
@@ -26,7 +26,7 @@
*/
public interface StatsProvider {
/**
* Intialize the stats provider by loading the given configuration <i>conf</i>.
* Initialize the stats provider by loading the given configuration <i>conf</i>.
*
* @param conf
* Configuration to configure the stats provider.

0 comments on commit 38dc328

Please sign in to comment.