Skip to content
This repository has been archived by the owner on Dec 23, 2023. It is now read-only.

Commit

Permalink
Exporter/Prometheus: Allow to set custom namespace. (#1850)
Browse files Browse the repository at this point in the history
* Exporter/Prometheus: Allow to set custom namespace.

* Fix wording.
  • Loading branch information
songy23 authored Apr 19, 2019
1 parent 1a08c36 commit d62a2e7
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- Add HTTP text format serializer to Tag propagation component.
- Support constant labels in Gauge APIs.
- Add an option to allow users to override the default "opencensus_task" metric label in Stackdriver Stats Exporter.
- Allow setting custom namespace in Prometheus exporter.

## 0.20.0 - 2019-03-28
- Add OpenCensus Java OC-Agent Trace Exporter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@
* <p>Each OpenCensus {@link Metric} will be converted to a Prometheus {@link MetricFamilySamples},
* and each {@code Point} of the {@link Metric} will be converted to Prometheus {@link Sample}s.
*
* <p>{@link io.opencensus.metrics.export.Value.ValueDouble}, {@link
* <p>{@code io.opencensus.metrics.export.Value.ValueDouble}, {@code
* io.opencensus.metrics.export.Value.ValueLong} will be converted to a single {@link Sample}.
* {@link io.opencensus.metrics.export.Value.ValueSummary} will be converted to two {@link Sample}s
* sum and count. {@link io.opencensus.metrics.export.Value.ValueDistribution} will be converted to
* {@code io.opencensus.metrics.export.Value.ValueSummary} will be converted to two {@code Sample}s
* sum and count. {@code io.opencensus.metrics.export.Value.ValueDistribution} will be converted to
* a list of {@link Sample}s that have the sum, count and histogram buckets.
*
* <p>{@link LabelKey} and {@link LabelValue} will be converted to Prometheus {@code LabelName} and
Expand All @@ -76,9 +76,9 @@ final class PrometheusExportUtils {
@VisibleForTesting static final String LABEL_NAME_QUANTILE = "quantile";

// Converts a Metric to a Prometheus MetricFamilySamples.
static MetricFamilySamples createMetricFamilySamples(Metric metric) {
static MetricFamilySamples createMetricFamilySamples(Metric metric, String namespace) {
MetricDescriptor metricDescriptor = metric.getMetricDescriptor();
String name = Collector.sanitizeMetricName(metricDescriptor.getName());
String name = getNamespacedName(metricDescriptor.getName(), namespace);
Type type = getType(metricDescriptor.getType());
List<String> labelNames = convertToLabelNames(metricDescriptor.getLabelKeys());
List<Sample> samples = Lists.newArrayList();
Expand All @@ -94,8 +94,8 @@ static MetricFamilySamples createMetricFamilySamples(Metric metric) {
// Converts a MetricDescriptor to a Prometheus MetricFamilySamples.
// Used only for Prometheus metric registry, should not contain any actual samples.
static MetricFamilySamples createDescribableMetricFamilySamples(
MetricDescriptor metricDescriptor) {
String name = Collector.sanitizeMetricName(metricDescriptor.getName());
MetricDescriptor metricDescriptor, String namespace) {
String name = getNamespacedName(metricDescriptor.getName(), namespace);
Type type = getType(metricDescriptor.getType());
List<String> labelNames = convertToLabelNames(metricDescriptor.getLabelKeys());

Expand All @@ -116,6 +116,16 @@ static MetricFamilySamples createDescribableMetricFamilySamples(
name, type, metricDescriptor.getDescription(), Collections.<Sample>emptyList());
}

private static String getNamespacedName(String metricName, String namespace) {
if (!namespace.isEmpty()) {
if (!namespace.endsWith("/") && !namespace.endsWith("_")) {
namespace += '_';
}
metricName = namespace + metricName;
}
return Collector.sanitizeMetricName(metricName);
}

@VisibleForTesting
static Type getType(MetricDescriptor.Type type) {
if (type == MetricDescriptor.Type.CUMULATIVE_INT64
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public final class PrometheusStatsCollector extends Collector implements Collect
private static final String EXPORT_METRICS_TO_PROMETHEUS = "ExportMetricsToPrometheus";
private final MetricReader collectMetricReader;
private final MetricReader describeMetricReader;
private final String namespace;

/**
* Creates a {@link PrometheusStatsCollector} and registers it to Prometheus {@link
Expand All @@ -68,7 +69,7 @@ public final class PrometheusStatsCollector extends Collector implements Collect
* @since 0.12
*/
public static void createAndRegister() {
new PrometheusStatsCollector(Metrics.getExportComponent().getMetricProducerManager())
new PrometheusStatsCollector(Metrics.getExportComponent().getMetricProducerManager(), "")
.register();
}

Expand All @@ -88,12 +89,18 @@ public static void createAndRegister(PrometheusStatsConfiguration configuration)
if (registry == null) {
registry = CollectorRegistry.defaultRegistry;
}
new PrometheusStatsCollector(Metrics.getExportComponent().getMetricProducerManager())
new PrometheusStatsCollector(
Metrics.getExportComponent().getMetricProducerManager(), configuration.getNamespace())
.register(registry);
}

private static final class ExportMetricExporter extends MetricExporter {
private final ArrayList<MetricFamilySamples> samples = new ArrayList<>();
private final String namespace;

private ExportMetricExporter(String namespace) {
this.namespace = namespace;
}

@Override
public void export(Collection<Metric> metrics) {
Expand All @@ -111,7 +118,7 @@ public void export(Collection<Metric> metrics) {
continue;
}
try {
samples.add(PrometheusExportUtils.createMetricFamilySamples(metric));
samples.add(PrometheusExportUtils.createMetricFamilySamples(metric, namespace));
} catch (Throwable e) {
logger.log(Level.WARNING, "Exception thrown when collecting metric samples.", e);
tracer
Expand All @@ -127,13 +134,18 @@ public void export(Collection<Metric> metrics) {

@Override
public List<MetricFamilySamples> collect() {
ExportMetricExporter exportMetricExporter = new ExportMetricExporter();
ExportMetricExporter exportMetricExporter = new ExportMetricExporter(namespace);
collectMetricReader.readAndExport(exportMetricExporter);
return exportMetricExporter.samples;
}

private static final class DescribeMetricExporter extends MetricExporter {
private final ArrayList<MetricFamilySamples> samples = new ArrayList<>();
private final String namespace;

private DescribeMetricExporter(String namespace) {
this.namespace = namespace;
}

@Override
public void export(Collection<Metric> metrics) {
Expand All @@ -142,7 +154,7 @@ public void export(Collection<Metric> metrics) {
try {
samples.add(
PrometheusExportUtils.createDescribableMetricFamilySamples(
metric.getMetricDescriptor()));
metric.getMetricDescriptor(), namespace));
} catch (Throwable e) {
logger.log(Level.WARNING, "Exception thrown when describing metrics.", e);
tracer
Expand All @@ -158,13 +170,13 @@ public void export(Collection<Metric> metrics) {

@Override
public List<MetricFamilySamples> describe() {
DescribeMetricExporter describeMetricExporter = new DescribeMetricExporter();
DescribeMetricExporter describeMetricExporter = new DescribeMetricExporter(namespace);
describeMetricReader.readAndExport(describeMetricExporter);
return describeMetricExporter.samples;
}

@VisibleForTesting
PrometheusStatsCollector(MetricProducerManager metricProducerManager) {
PrometheusStatsCollector(MetricProducerManager metricProducerManager, String namespace) {
this.collectMetricReader =
MetricReader.create(
MetricReader.Options.builder()
Expand All @@ -177,6 +189,7 @@ public List<MetricFamilySamples> describe() {
.setMetricProducerManager(metricProducerManager)
.setSpanName(DESCRIBE_METRICS_FOR_PROMETHEUS)
.build());
this.namespace = namespace;
}

private static String exceptionMessage(Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.google.auto.value.AutoValue;
import io.prometheus.client.CollectorRegistry;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

/**
Expand All @@ -38,17 +37,26 @@ public abstract class PrometheusStatsConfiguration {
* @return the Prometheus {@code CollectorRegistry}.
* @since 0.13
*/
@Nullable
public abstract CollectorRegistry getRegistry();

/**
* Returns the namespace used for Prometheus metrics.
*
* @return the namespace.
* @since 0.21
*/
public abstract String getNamespace();

/**
* Returns a new {@link Builder}.
*
* @return a {@code Builder}.
* @since 0.13
*/
public static Builder builder() {
return new AutoValue_PrometheusStatsConfiguration.Builder();
return new AutoValue_PrometheusStatsConfiguration.Builder()
.setRegistry(CollectorRegistry.defaultRegistry)
.setNamespace("");
}

/**
Expand All @@ -70,6 +78,15 @@ public abstract static class Builder {
*/
public abstract Builder setRegistry(CollectorRegistry registry);

/**
* Sets the namespace used for Prometheus metrics.
*
* @param namespace the namespace.
* @return this.
* @since 0.21
*/
public abstract Builder setNamespace(String namespace);

/**
* Builds a new {@link PrometheusStatsConfiguration} with current settings.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,49 @@ public void getType() {
public void createDescribableMetricFamilySamples() {
assertThat(
PrometheusExportUtils.createDescribableMetricFamilySamples(
CUMULATIVE_METRIC_DESCRIPTOR))
CUMULATIVE_METRIC_DESCRIPTOR, ""))
.isEqualTo(
new MetricFamilySamples(
METRIC_NAME, Type.COUNTER, METRIC_DESCRIPTION, Collections.<Sample>emptyList()));
assertThat(
PrometheusExportUtils.createDescribableMetricFamilySamples(SUMMARY_METRIC_DESCRIPTOR))
PrometheusExportUtils.createDescribableMetricFamilySamples(
SUMMARY_METRIC_DESCRIPTOR, ""))
.isEqualTo(
new MetricFamilySamples(
METRIC_NAME2, Type.SUMMARY, METRIC_DESCRIPTION, Collections.<Sample>emptyList()));
assertThat(
PrometheusExportUtils.createDescribableMetricFamilySamples(HISTOGRAM_METRIC_DESCRIPTOR))
PrometheusExportUtils.createDescribableMetricFamilySamples(
HISTOGRAM_METRIC_DESCRIPTOR, ""))
.isEqualTo(
new MetricFamilySamples(
METRIC_NAME3, Type.HISTOGRAM, METRIC_DESCRIPTION, Collections.<Sample>emptyList()));
}

@Test
public void createDescribableMetricFamilySamples_WithNamespace() {
String namespace1 = "myorg";
assertThat(
PrometheusExportUtils.createDescribableMetricFamilySamples(
CUMULATIVE_METRIC_DESCRIPTOR, namespace1))
.isEqualTo(
new MetricFamilySamples(
namespace1 + '_' + METRIC_NAME,
Type.COUNTER,
METRIC_DESCRIPTION,
Collections.<Sample>emptyList()));

String namespace2 = "opencensus/";
assertThat(
PrometheusExportUtils.createDescribableMetricFamilySamples(
CUMULATIVE_METRIC_DESCRIPTOR, namespace2))
.isEqualTo(
new MetricFamilySamples(
"opencensus_" + METRIC_NAME,
Type.COUNTER,
METRIC_DESCRIPTION,
Collections.<Sample>emptyList()));
}

@Test
public void getSamples() {
assertThat(
Expand Down Expand Up @@ -306,7 +333,7 @@ public void createDescribableMetricFamilySamples_Histogram_DisallowLeLabelName()
"Prometheus Histogram cannot have a label named 'le', "
+ "because it is a reserved label for bucket boundaries. "
+ "Please remove this key from your view.");
PrometheusExportUtils.createDescribableMetricFamilySamples(LE_LABEL_METRIC_DESCRIPTOR);
PrometheusExportUtils.createDescribableMetricFamilySamples(LE_LABEL_METRIC_DESCRIPTOR, "");
}

@Test
Expand All @@ -315,12 +342,13 @@ public void createDescribableMetricFamilySamples_Summary_DisallowQuantileLabelNa
thrown.expectMessage(
"Prometheus Summary cannot have a label named 'quantile', "
+ "because it is a reserved label. Please remove this key from your view.");
PrometheusExportUtils.createDescribableMetricFamilySamples(QUANTILE_LABEL_METRIC_DESCRIPTOR);
PrometheusExportUtils.createDescribableMetricFamilySamples(
QUANTILE_LABEL_METRIC_DESCRIPTOR, "");
}

@Test
public void createMetricFamilySamples() {
assertThat(PrometheusExportUtils.createMetricFamilySamples(LONG_METRIC))
assertThat(PrometheusExportUtils.createMetricFamilySamples(LONG_METRIC, ""))
.isEqualTo(
new MetricFamilySamples(
METRIC_NAME,
Expand All @@ -332,7 +360,7 @@ public void createMetricFamilySamples() {
Arrays.asList("k1", "k2"),
Arrays.asList("v1", "v2"),
123456789))));
assertThat(PrometheusExportUtils.createMetricFamilySamples(SUMMARY_METRIC))
assertThat(PrometheusExportUtils.createMetricFamilySamples(SUMMARY_METRIC, ""))
.isEqualTo(
new MetricFamilySamples(
METRIC_NAME2,
Expand All @@ -354,7 +382,7 @@ public void createMetricFamilySamples() {
Arrays.asList("k_3", LABEL_NAME_QUANTILE),
Arrays.asList("v1", "0.99"),
10.2))));
assertThat(PrometheusExportUtils.createMetricFamilySamples(DISTRIBUTION_METRIC))
assertThat(PrometheusExportUtils.createMetricFamilySamples(DISTRIBUTION_METRIC, ""))
.isEqualTo(
new MetricFamilySamples(
METRIC_NAME3,
Expand Down Expand Up @@ -392,4 +420,21 @@ public void createMetricFamilySamples() {
Collections.singletonList("v-3"),
22.0))));
}

@Test
public void createMetricFamilySamples_WithNamespace() {
String namespace = "opencensus_";
assertThat(PrometheusExportUtils.createMetricFamilySamples(LONG_METRIC, namespace))
.isEqualTo(
new MetricFamilySamples(
namespace + METRIC_NAME,
Type.COUNTER,
METRIC_DESCRIPTION,
Collections.singletonList(
new Sample(
namespace + METRIC_NAME,
Arrays.asList("k1", "k2"),
Arrays.asList("v1", "v2"),
123456789))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ public void setUp() {

@Test
public void testCollect() {
PrometheusStatsCollector collector = new PrometheusStatsCollector(mockMetricProducerManager);
PrometheusStatsCollector collector =
new PrometheusStatsCollector(mockMetricProducerManager, "");
assertThat(collector.collect())
.containsExactly(
new MetricFamilySamples(
Expand Down Expand Up @@ -151,32 +152,48 @@ public void testCollect() {
@Test
public void testCollect_SkipDistributionMetricWithLeLabelKey() {
doReturn(Collections.singletonList(LE_LABEL_METRIC)).when(mockMetricProducer).getMetrics();
PrometheusStatsCollector collector = new PrometheusStatsCollector(mockMetricProducerManager);
PrometheusStatsCollector collector =
new PrometheusStatsCollector(mockMetricProducerManager, "");
assertThat(collector.collect()).isEmpty();
}

@Test
public void testDescribe() {
PrometheusStatsCollector collector = new PrometheusStatsCollector(mockMetricProducerManager);
PrometheusStatsCollector collector =
new PrometheusStatsCollector(mockMetricProducerManager, "");
assertThat(collector.describe())
.containsExactly(
new MetricFamilySamples(
METRIC_NAME, Type.HISTOGRAM, METRIC_DESCRIPTION, Collections.<Sample>emptyList()));
}

@Test
public void testDescribe_WithNamespace() {
String namespace = "myorg";
PrometheusStatsCollector collector =
new PrometheusStatsCollector(mockMetricProducerManager, namespace);
assertThat(collector.describe())
.containsExactly(
new MetricFamilySamples(
namespace + '_' + METRIC_NAME,
Type.HISTOGRAM,
METRIC_DESCRIPTION,
Collections.<Sample>emptyList()));
}

@Test
public void testCollect_WithNoopViewManager() {
PrometheusStatsCollector collector =
new PrometheusStatsCollector(
ExportComponent.newNoopExportComponent().getMetricProducerManager());
ExportComponent.newNoopExportComponent().getMetricProducerManager(), "");
assertThat(collector.collect()).isEmpty();
}

@Test
public void testDescribe_WithNoopViewManager() {
PrometheusStatsCollector collector =
new PrometheusStatsCollector(
ExportComponent.newNoopExportComponent().getMetricProducerManager());
ExportComponent.newNoopExportComponent().getMetricProducerManager(), "");
assertThat(collector.describe()).isEmpty();
}
}

0 comments on commit d62a2e7

Please sign in to comment.