org.cloudfoundry.promregator.endpoint.SingleTargetMetricsEndpoint Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of promregator Show documentation
Show all versions of promregator Show documentation
Prometheus/CloudFoundry Metrics Aggregator
package org.cloudfoundry.promregator.endpoint;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.cloudfoundry.promregator.rewrite.AbstractMetricFamilySamplesEnricher;
import org.cloudfoundry.promregator.rewrite.CFAllLabelsMetricFamilySamplesEnricher;
import org.cloudfoundry.promregator.rewrite.NullMetricFamilySamplesEnricher;
import org.cloudfoundry.promregator.scanner.Instance;
import org.cloudfoundry.promregator.scanner.ResolvedTarget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Gauge;
import io.prometheus.client.exporter.common.TextFormat;
@RestController
@Scope(value=WebApplicationContext.SCOPE_REQUEST) // see also https://github.com/promregator/promregator/issues/51
@RequestMapping(EndpointConstants.ENDPOINT_PATH_SINGLE_TARGET_SCRAPING+"/{applicationId}/{instanceNumber}")
public class SingleTargetMetricsEndpoint extends AbstractMetricsEndpoint {
private static final Logger log = LoggerFactory.getLogger(SingleTargetMetricsEndpoint.class);
private Instance instance;
@GetMapping(produces=TextFormat.CONTENT_TYPE_004)
public ResponseEntity getMetrics(
@PathVariable String applicationId,
@PathVariable String instanceNumber
) {
if (this.isLoopbackRequest()) {
throw new LoopbackScrapingDetectedException("Erroneous Loopback Scraping request detected");
}
String instanceId = String.format("%s:%s", applicationId, instanceNumber);
String response = null;
try {
response = this.handleRequest( discoveredApplicationId -> applicationId.equals(discoveredApplicationId)
, requestInstance -> {
if (requestInstance.getInstanceId().equals(instanceId)) {
this.instance = requestInstance;
return true;
}
return false;
});
} catch (ScrapingException e) {
return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(response, HttpStatus.OK);
}
@Override
protected boolean isIncludeGlobalMetrics() {
// NB: This is done by PromregatorMetricsEndpoint in this scenario instead.
return false;
}
@Override
protected boolean isLabelEnrichmentSuppressable() {
/*
* we only have metrics of a single Cloud Foundry application instance in our
* response. Thus, it is permitted that label enrichment may be suppressed (hence answering "true" here).
*/
return true;
}
@Override
protected void handleScrapeDuration(CollectorRegistry requestRegistry, Duration duration) {
/*
* Note: The scrape_duration_seconds metric is being passed on to Prometheus with
* the normal scraping request.
* If the configuration option promregator.scraping.labelEnrichment is disabled, then
* the metric must also comply to this approach. Otherwise there might arise issues
* with rewriting in Prometheus.
*/
AbstractMetricFamilySamplesEnricher enricher = null;
String[] ownTelemetryLabels = null;
if (this.isLabelEnrichmentEnabled()) {
if (this.instance == null) {
log.warn("Internal inconsistency: Single Target Metrics Endpoint triggered, even though instance could not be detected; skipping scrape_duration");
return;
}
ResolvedTarget t = this.instance.getTarget();
ownTelemetryLabels = CFAllLabelsMetricFamilySamplesEnricher.getEnrichingLabelNames();
enricher = new CFAllLabelsMetricFamilySamplesEnricher(t.getOrgName(), t.getSpaceName(), t.getApplicationName(), this.instance.getInstanceId());
} else {
ownTelemetryLabels = NullMetricFamilySamplesEnricher.getEnrichingLabelNames();
enricher = new NullMetricFamilySamplesEnricher();
}
Gauge scrapeDuration = Gauge.build("promregator_scrape_duration_seconds", "Duration in seconds indicating how long scraping of all metrics took")
.labelNames(ownTelemetryLabels)
.register(requestRegistry);
List labelValues = enricher.getEnrichedLabelValues(new ArrayList<>(0));
scrapeDuration.labels(labelValues.toArray(new String[0])).set(duration.toMillis() / 1000.0);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy