Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New metric "exporter_version" reports the version of the exporter #214

Merged
merged 1 commit into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,23 @@

package com.oracle.wls.exporter;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.oracle.wls.exporter.domain.MBeanSelector;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.oracle.wls.exporter.domain.MBeanSelector;

import static com.oracle.wls.exporter.domain.MapUtils.isNullOrEmptyString;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;

public class ExporterCall extends AuthenticatedCall {

public ExporterCall(WebClientFactory webClientFactory, InvocationContext context) {
super(webClientFactory, context);
Locale.setDefault(Locale.US);
}

@Override
Expand All @@ -41,7 +39,7 @@ private void displayMetrics(WebClient webClient, MetricsStream metricsStream) th
try {
for (MBeanSelector selector : LiveConfiguration.getQueries())
displayMetrics(webClient, metricsStream, selector);
metricsStream.printPerformanceMetrics();
metricsStream.printPlatformMetrics();
} catch (RestPortConnectionException e) {
reportFailure(e);
webClient.setRetryNeeded();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Copyright (c) 2017, 2021, Oracle and/or its affiliates.
// Copyright (c) 2017, 2022, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.

package com.oracle.wls.exporter;

import javax.management.MBeanServerConnection;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.util.Locale;
import javax.management.MBeanServerConnection;

import com.sun.management.OperatingSystemMXBean;

Expand All @@ -35,7 +35,7 @@ class MetricsStream extends PrintStream {
* @throws IOException if some error occurs while creating the performance probe
*/
MetricsStream(String instance, OutputStream outputStream) throws IOException {
this(instance, outputStream, new PlatformPeformanceProbe());
this(instance, outputStream, new PlatformPerformanceProbe());
}

/**
Expand All @@ -58,37 +58,49 @@ class MetricsStream extends PrintStream {
* @param value the metric value
*/
void printMetric(String name, Object value) {
print(name + " " + value + '\n');
print(name + " " + value + System.lineSeparator());
scrapeCount++;
}

/**
* Prints the summary performance metrics
*/
void printPerformanceMetrics() {
printf( "%s %d\n", getCountName(), scrapeCount);
printf(Locale.US, "%s %.2f\n", getDurationName(), toSeconds(getElapsedTime()));
printf(Locale.US, "%s %.2f\n", getCpuUsageName(), toSeconds(getCpuUsed()));
void printPlatformMetrics() {
printf( "%s %d%n", getCountName(), scrapeCount);
printf(Locale.US, "%s %.2f%n", getDurationName(), toSeconds(getElapsedTime()));
printf(Locale.US, "%s %.2f%n", getCpuUsageName(), toSeconds(getCpuUsed()));
printf("%s %d%n", getExporterVersionName(), 1);
}

private String getDurationName() {
return "wls_scrape_duration_seconds" + getPerformanceQualifier();
return "wls_scrape_duration_seconds" + getPlatformQualifier();
}

/**
* Returns the qualifiers to add to the performance metrics, specifying the configured server
* Returns the qualifiers to add to the platform metrics, specifying the configured server
* @return a metrics qualifier string
*/
private String getPerformanceQualifier() {
private String getPlatformQualifier() {
return String.format("{instance=\"%s\"}", instance);
}

private String getCpuUsageName() {
return "wls_scrape_cpu_seconds" + getPerformanceQualifier();
return "wls_scrape_cpu_seconds" + getPlatformQualifier();
}

private String getCountName() {
return "wls_scrape_mbeans_count_total" + getPerformanceQualifier();
return "wls_scrape_mbeans_count_total" + getPlatformQualifier();
}

private String getExporterVersionName() {
return "exporter_version" + getExporterVersionQualifier();
}

/**
* Returns the qualifiers to add to the version metric.
*/
private String getExporterVersionQualifier() {
return String.format("{instance=\"%s\",version=\"%s\"}", instance, LiveConfiguration.getVersionString());
}

private long getElapsedTime() {
Expand All @@ -108,10 +120,10 @@ interface PerformanceProbe {
long getCurrentCpu();
}

private static class PlatformPeformanceProbe implements PerformanceProbe {
private static class PlatformPerformanceProbe implements PerformanceProbe {
private final OperatingSystemMXBean osMBean;

PlatformPeformanceProbe() throws IOException {
PlatformPerformanceProbe() throws IOException {
MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();
osMBean = ManagementFactory.newPlatformMXBeanProxy(mbsc,
ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@

package com.oracle.wls.exporter;

import java.io.BufferedReader;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

import com.google.common.collect.ImmutableMap;
import com.oracle.wls.exporter.webapp.ExporterServlet;
Expand Down Expand Up @@ -324,29 +322,7 @@ void onGet_producePerformanceMetrics() throws Exception {

servlet.doGet(request, response);

assertThat(toHtml(response), containsString("wls_scrape_mbeans_count_total{instance=\"myhost:7654\"} 6"));
}

@Test
void onGetInForeignLocale_performanceMetricsUsePeriodForFloatingPoint() throws Exception {
factory.addJsonResponse(getGroupResponseMap());
initServlet(CONFIG_WITH_CATEGORY_VALUE);

Locale.setDefault(Locale.FRANCE);
servlet.doGet(request, response);

assertThat(getMetricValue("wls_scrape_duration_seconds"), containsString("."));
}

@SuppressWarnings("SameParameterValue")
private String getMetricValue(String metricsName) throws IOException {
String line;
BufferedReader reader = new BufferedReader(new StringReader(toHtml(response)));
do {
line = reader.readLine();
} while (line != null && !line.contains(metricsName));

return (line == null) ? "" : line.split(" ")[1];
assertThat(toHtml(response), containsString("wls_scrape_mbeans_count_total"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;

import com.google.common.collect.ImmutableMap;
import com.meterware.simplestub.Memento;
import com.meterware.simplestub.StaticStubSupport;
import com.meterware.simplestub.SystemPropertySupport;
import com.oracle.wls.exporter.matchers.PrometheusMetricsMatcher;
import com.oracle.wls.exporter.webapp.HttpServletRequestStub;
import com.oracle.wls.exporter.webapp.ServletUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static com.oracle.wls.exporter.MetricsStreamTest.LocaleSupport.setFrenchLocale;
import static com.oracle.wls.exporter.matchers.PrometheusMetricsMatcher.followsPrometheusRules;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
Expand All @@ -31,8 +38,13 @@ class MetricsStreamTest {
private static final long NANOSEC_PER_SECONDS = 1000000000;
private static final String LINE_SEPARATOR = "line.separator";
private static final String WINDOWS_LINE_SEPARATOR = "\r\n";
private static final String HOST_NAME = "wlshost";
private static final int HOST_PORT = 7201;
private static final String INSTANCE = HOST_NAME + ':' + HOST_PORT;
private static final SortedMap<String,String> QUALIFICATIONS
= new TreeMap<>(ImmutableMap.of("instance", INSTANCE));
private final PerformanceProbeStub performanceProbe = new PerformanceProbeStub();
private final HttpServletRequestStub postRequest = HttpServletRequestStub.createPostRequest().withHostName("wlshost").withPort(7201);
private final HttpServletRequestStub postRequest = HttpServletRequestStub.createPostRequest().withHostName(HOST_NAME).withPort(HOST_PORT);
private ByteArrayOutputStream baos;
private MetricsStream metrics;
private final List<Memento> mementos = new ArrayList<>();
Expand All @@ -47,7 +59,7 @@ public void setUp() throws NoSuchFieldException {

private void initMetricsStream() {
baos = new ByteArrayOutputStream();
metrics = new MetricsStream("wlshost:7201", new PrintStream(baos), performanceProbe);
metrics = new MetricsStream(INSTANCE, new PrintStream(baos), performanceProbe);
}

@AfterEach
Expand All @@ -58,11 +70,11 @@ public void tearDown() {
@Test
void whenNoMetricsScraped_reportNoneScraped() {
assertThat(getPrintedMetrics(),
containsString("wls_scrape_mbeans_count_total{instance=\"wlshost:7201\"} 0"));
containsString(getQualifiedPlatformMetricName("wls_scrape_mbeans_count_total") + " 0"));
}

private String getPrintedMetrics() {
metrics.printPerformanceMetrics();
metrics.printPlatformMetrics();
return baos.toString();
}

Expand Down Expand Up @@ -93,7 +105,10 @@ private void simulateWindows() throws NoSuchFieldException {
}

private List<String> getPrintedMetricValues() {
return Arrays.stream(getPrintedMetrics().split("\n")).map(l -> l.split(" ")[1]).collect(Collectors.toList());
return Arrays.stream(getPrintedMetrics()
.split(System.lineSeparator()))
.map(PrometheusMetricsMatcher::getMetricValue)
.collect(Collectors.toList());
}

@Test
Expand All @@ -103,25 +118,41 @@ void afterMetricsScraped_reportScrapedCount() {
metrics.printMetric("c", 0);

assertThat(getPrintedMetrics(),
containsString("wls_scrape_mbeans_count_total{instance=\"wlshost:7201\"} 3"));
containsString(getQualifiedPlatformMetricName("wls_scrape_mbeans_count_total") + " 3"));
}


private String getQualifiedPlatformMetricName(String metricName) {
return metricName + '{' + QUALIFICATIONS.entrySet().stream().map(this::toQualification).collect(Collectors.joining(",")) + '}';
}

private String toQualification(Map.Entry<String,String> entry) {
return String.format("%s=\"%s\"", entry.getKey(), entry.getValue());
}

@Test
void afterTimePasses_reportScrapeDuration() {
performanceProbe.incrementElapsedTime(12.4);

assertThat(getPrintedMetrics(),
containsString("wls_scrape_duration_seconds{instance=\"wlshost:7201\"} 12.40"));
containsString(getQualifiedPlatformMetricName("wls_scrape_duration_seconds") + " 12.40"));
}

@Test
void afterProcessing_reportCpuPercent() {
performanceProbe.incrementCpuTime(3.2);

assertThat(getPrintedMetrics(),
containsString("wls_scrape_cpu_seconds{instance=\"wlshost:7201\"} 3.20"));
containsString(getQualifiedPlatformMetricName("wls_scrape_cpu_seconds") + " 3.20"));
}

@Test
void includeVersionStringInMetrics() {
metrics.printPlatformMetrics();

assertThat(baos.toString(), containsString(LiveConfiguration.getVersionString()));
}

@Test
void producedMetricsAreCompliant() {
performanceProbe.incrementElapsedTime(20);
Expand All @@ -130,6 +161,24 @@ void producedMetricsAreCompliant() {
assertThat(getPrintedMetrics(), followsPrometheusRules());
}

@Test
void alwaysUseUSEncodingForMetrics() {
mementos.add(setFrenchLocale());

metrics.printMetric("scraped value", 3.14);

assertThat(baos.toString(), containsString("."));
}

@Test
void alwaysUseUSEncodingForPlatformMetrics() {
mementos.add(setFrenchLocale());

metrics.printPlatformMetrics();

assertThat(baos.toString(), containsString("."));
}

@SuppressWarnings("SameParameterValue")
static class PerformanceProbeStub implements MetricsStream.PerformanceProbe {
private long currentTime = getRandom();
Expand All @@ -156,4 +205,27 @@ public long getCurrentCpu() {
return currentCpu;
}
}

static class LocaleSupport implements Memento {
private final Locale savedLocale = Locale.getDefault();

private LocaleSupport(Locale locale) {
Locale.setDefault(locale);
}

static Memento setFrenchLocale() {
return new LocaleSupport(new Locale.Builder().setLanguage("fr").setRegion("FR").build());
}

@Override
public void revert() {
Locale.setDefault(savedLocale);
}

@SuppressWarnings("unchecked")
@Override
public Locale getOriginalValue() {
return savedLocale;
}
}
}
Loading