Implemented TraceConfigZ zPage (#1441)
* Implemented TraceConfigZ zPage (#22) * Added link to index zpage * Used AutoValue for TableRow classes * Changed wording of HTML content * Changed Builder to interface, fixed build issues * Removed tableRow classes, added omitEmpty in parseQueryMap * Added test for invalid inputs * Changed to use illegalArgumentException
This commit is contained in:
parent
78ed6490ba
commit
ad6f9e364c
|
|
@ -13,7 +13,12 @@ dependencies {
|
|||
project(':opentelemetry-sdk')
|
||||
|
||||
implementation libraries.guava
|
||||
|
||||
compileOnly 'com.sun.net.httpserver:http:20070405'
|
||||
|
||||
annotationProcessor libraries.auto_value
|
||||
|
||||
testAnnotationProcessor libraries.auto_value
|
||||
|
||||
signature "org.codehaus.mojo.signature:java17:1.0@signature"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
* Copyright 2020, OpenTelemetry Authors
|
||||
*
|
||||
* Licensed 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 io.opentelemetry.sdk.extensions.zpages;
|
||||
|
||||
import io.opentelemetry.sdk.trace.Samplers;
|
||||
import io.opentelemetry.sdk.trace.TracerSdkProvider;
|
||||
import io.opentelemetry.sdk.trace.config.TraceConfig;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
final class TraceConfigzZPageHandler extends ZPageHandler {
|
||||
private static final String TRACE_CONFIGZ_URL = "/traceconfigz";
|
||||
private static final String TRACE_CONFIGZ_NAME = "TraceConfigZ";
|
||||
private static final String TRACE_CONFIGZ_DESCRIPTION =
|
||||
"TraceConfigZ displays information about the current active tracing configuration"
|
||||
+ " and allows users to change it";
|
||||
private static final String QUERY_STRING_ACTION = "action";
|
||||
private static final String QUERY_STRING_ACTION_CHANGE = "change";
|
||||
private static final String QUERY_STRING_ACTION_DEFAULT = "default";
|
||||
private static final String QUERY_STRING_SAMPLING_PROBABILITY = "samplingprobability";
|
||||
private static final String QUERY_STRING_MAX_NUM_OF_ATTRIBUTES = "maxnumofattributes";
|
||||
private static final String QUERY_STRING_MAX_NUM_OF_EVENTS = "maxnumofevents";
|
||||
private static final String QUERY_STRING_MAX_NUM_OF_LINKS = "maxnumoflinks";
|
||||
private static final String QUERY_STRING_MAX_NUM_OF_ATTRIBUTES_PER_EVENT =
|
||||
"maxnumofattributesperevent";
|
||||
private static final String QUERY_STRING_MAX_NUM_OF_ATTRIBUTES_PER_LINK =
|
||||
"maxnumofattributesperlink";
|
||||
// Background color used for zebra striping rows in table
|
||||
private static final String ZEBRA_STRIPE_COLOR = "#e6e6e6";
|
||||
private static final Logger logger = Logger.getLogger(TraceConfigzZPageHandler.class.getName());
|
||||
private final TracerSdkProvider tracerProvider;
|
||||
|
||||
TraceConfigzZPageHandler(TracerSdkProvider tracerProvider) {
|
||||
this.tracerProvider = tracerProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrlPath() {
|
||||
return TRACE_CONFIGZ_URL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPageName() {
|
||||
return TRACE_CONFIGZ_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPageDescription() {
|
||||
return TRACE_CONFIGZ_DESCRIPTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits CSS styles to the {@link PrintStream} {@code out}. Content emited by this function should
|
||||
* be enclosed by <head></head> tag.
|
||||
*
|
||||
* @param out the {@link PrintStream} {@code out}.
|
||||
*/
|
||||
private static void emitHtmlStyle(PrintStream out) {
|
||||
out.print("<style>");
|
||||
out.print(ZPageStyle.style);
|
||||
out.print("</style>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a row of the change tracing parameter table to the {@link PrintStream} {@code out}. Each
|
||||
* row corresponds to one tracing parameter.
|
||||
*
|
||||
* @param out the {@link PrintStream} {@code out}.
|
||||
* @param rowName the display name of the corresponding tracing parameter.
|
||||
* @param paramName the name of the corresponding tracing parameter (this will be used to
|
||||
* construct the query parameter in URL).
|
||||
* @param inputPlaceHolder placeholder for the <input> HTML element.
|
||||
* @param paramDefaultValue the default value of the corresponding tracing parameter.
|
||||
* @param zebraStripeColor hex code of the color used for zebra striping rows.
|
||||
* @param zebraStripe boolean indicating if the row is zebra striped.
|
||||
*/
|
||||
private static void emitChangeTableRow(
|
||||
PrintStream out,
|
||||
String rowName,
|
||||
String paramName,
|
||||
String inputPlaceHolder,
|
||||
String paramDefaultValue,
|
||||
String zebraStripeColor,
|
||||
boolean zebraStripe) {
|
||||
if (zebraStripe) {
|
||||
out.print("<tr style=\"background-color: " + zebraStripeColor + ";\">");
|
||||
} else {
|
||||
out.print("<tr>");
|
||||
}
|
||||
out.print("<td>Update " + rowName + "</td>");
|
||||
out.print(
|
||||
"<td class=\"border-left-dark\"><input type=text size=15 name="
|
||||
+ paramName
|
||||
+ " value=\"\" placeholder=\""
|
||||
+ inputPlaceHolder
|
||||
+ "\" /></td>");
|
||||
out.print("<td class=\"border-left-dark\">(" + paramDefaultValue + ")</td>");
|
||||
out.print("</tr>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the change tracing parameter table to the {@link PrintStream} {@code out}.
|
||||
*
|
||||
* @param out the {@link PrintStream} {@code out}.
|
||||
*/
|
||||
private static void emitChangeTable(PrintStream out) {
|
||||
out.print("<table style=\"border-spacing: 0; border: 1px solid #363636;\">");
|
||||
out.print("<tr class=\"bg-color\">");
|
||||
out.print(
|
||||
"<th colspan=2 style=\"text-align: left;\" class=\"header-text\">"
|
||||
+ "<b>Update active TraceConfig</b></th>");
|
||||
out.print("<th colspan=1 class=\"header-text border-left-white\"><b>Default</b></th>");
|
||||
emitChangeTableRow(
|
||||
/* out= */ out,
|
||||
/* rowName= */ "SamplingProbability to",
|
||||
/* paramName= */ QUERY_STRING_SAMPLING_PROBABILITY,
|
||||
/* inputPlaceHolder= */ "[0.0, 1.0]",
|
||||
/* paramDefaultValue= */ TraceConfig.getDefault().getSampler().getDescription(),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ false);
|
||||
emitChangeTableRow(
|
||||
/* out= */ out,
|
||||
/* rowName= */ "MaxNumberOfAttributes to",
|
||||
/* paramName= */ QUERY_STRING_MAX_NUM_OF_ATTRIBUTES,
|
||||
/* inputPlaceHolder= */ "",
|
||||
/* paramDefaultValue= */ Integer.toString(
|
||||
TraceConfig.getDefault().getMaxNumberOfAttributes()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ true);
|
||||
emitChangeTableRow(
|
||||
/* out= */ out,
|
||||
/* rowName= */ "MaxNumberOfEvents to",
|
||||
/* paramName= */ QUERY_STRING_MAX_NUM_OF_EVENTS,
|
||||
/* inputPlaceHolder= */ "",
|
||||
/* paramDefaultValue= */ Integer.toString(TraceConfig.getDefault().getMaxNumberOfEvents()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ false);
|
||||
emitChangeTableRow(
|
||||
/* out= */ out,
|
||||
/* rowName= */ "MaxNumberOfLinks to",
|
||||
/* paramName= */ QUERY_STRING_MAX_NUM_OF_LINKS,
|
||||
/* inputPlaceHolder= */ "",
|
||||
/* paramDefaultValue= */ Integer.toString(TraceConfig.getDefault().getMaxNumberOfLinks()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ true);
|
||||
emitChangeTableRow(
|
||||
/* out= */ out,
|
||||
/* rowName= */ "MaxNumberOfAttributesPerEvent to",
|
||||
/* paramName= */ QUERY_STRING_MAX_NUM_OF_ATTRIBUTES_PER_EVENT,
|
||||
/* inputPlaceHolder= */ "",
|
||||
/* paramDefaultValue= */ Integer.toString(
|
||||
TraceConfig.getDefault().getMaxNumberOfAttributesPerEvent()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ false);
|
||||
emitChangeTableRow(
|
||||
/* out= */ out,
|
||||
/* rowName= */ "MaxNumberOfAttributesPerLink to",
|
||||
/* paramName= */ QUERY_STRING_MAX_NUM_OF_ATTRIBUTES_PER_LINK,
|
||||
/* inputPlaceHolder= */ "",
|
||||
/* paramDefaultValue= */ Integer.toString(
|
||||
TraceConfig.getDefault().getMaxNumberOfAttributesPerLink()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ true);
|
||||
out.print("</table>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a row of the active tracing parameter table to the {@link PrintStream} {@code out}. Each
|
||||
* row corresponds to one tracing parameter.
|
||||
*
|
||||
* @param out the {@link PrintStream} {@code out}.
|
||||
* @param paramName the name of the corresponding tracing parameter.
|
||||
* @param paramValue the value of the corresponding tracing parameter.
|
||||
* @param zebraStripeColor hex code of the color used for zebra striping rows.
|
||||
* @param zebraStripe boolean indicating if the row is zebra striped.
|
||||
*/
|
||||
private static void emitActiveTableRow(
|
||||
PrintStream out,
|
||||
String paramName,
|
||||
String paramValue,
|
||||
String zebraStripeColor,
|
||||
boolean zebraStripe) {
|
||||
if (zebraStripe) {
|
||||
out.print("<tr style=\"background-color: " + zebraStripeColor + ";\">");
|
||||
} else {
|
||||
out.print("<tr>");
|
||||
}
|
||||
out.print("<td>" + paramName + "</td>");
|
||||
out.print("<td class=\"border-left-dark\">" + paramValue + "</td>");
|
||||
out.print("</tr>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the active tracing parameters table to the {@link PrintStream} {@code out}.
|
||||
*
|
||||
* @param out the {@link PrintStream} {@code out}.
|
||||
*/
|
||||
private void emitActiveTable(PrintStream out) {
|
||||
out.print("<table style=\"border-spacing: 0; border: 1px solid #363636;\">");
|
||||
out.print("<tr class=\"bg-color\">");
|
||||
out.print("<th class=\"header-text\"><b>Name</b></th>");
|
||||
out.print("<th class=\"header-text border-left-white\"><b>Value</b></th>");
|
||||
out.print("</tr>");
|
||||
emitActiveTableRow(
|
||||
/* out= */ out,
|
||||
/* paramName= */ "Sampler",
|
||||
/* paramValue=*/ this.tracerProvider.getActiveTraceConfig().getSampler().getDescription(),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ false);
|
||||
emitActiveTableRow(
|
||||
/* out= */ out,
|
||||
/* paramName= */ "MaxNumOfAttributes",
|
||||
/* paramValue=*/ Integer.toString(
|
||||
this.tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributes()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ true);
|
||||
emitActiveTableRow(
|
||||
/* out= */ out,
|
||||
/* paramName= */ "MaxNumOfEvents",
|
||||
/* paramValue=*/ Integer.toString(
|
||||
this.tracerProvider.getActiveTraceConfig().getMaxNumberOfEvents()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ false);
|
||||
emitActiveTableRow(
|
||||
/* out= */ out,
|
||||
/* paramName= */ "MaxNumOfLinks",
|
||||
/* paramValue=*/ Integer.toString(
|
||||
this.tracerProvider.getActiveTraceConfig().getMaxNumberOfLinks()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ true);
|
||||
emitActiveTableRow(
|
||||
/* out= */ out,
|
||||
/* paramName= */ "MaxNumOfAttributesPerEvent",
|
||||
/* paramValue=*/ Integer.toString(
|
||||
this.tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerEvent()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe= */ false);
|
||||
emitActiveTableRow(
|
||||
/* out= */ out,
|
||||
/* paramName= */ "MaxNumOfAttributesPerLink",
|
||||
/* paramValue=*/ Integer.toString(
|
||||
this.tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerLink()),
|
||||
/* zebraStripeColor= */ ZEBRA_STRIPE_COLOR,
|
||||
/* zebraStripe=*/ true);
|
||||
out.print("</table>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits HTML body content to the {@link PrintStream} {@code out}. Content emitted by this
|
||||
* function should be enclosed by <body></body> tag.
|
||||
*
|
||||
* @param out the {@link PrintStream} {@code out}.
|
||||
*/
|
||||
private void emitHtmlBody(PrintStream out) {
|
||||
out.print(
|
||||
"<a href=\"/\"><img style=\"height: 90px;\" src=\"data:image/png;base64,"
|
||||
+ ZPageLogo.getLogoBase64()
|
||||
+ "\" /></a>");
|
||||
out.print("<h1>Trace Configuration</h1>");
|
||||
out.print("<form class=\"form-flex\" action=\"" + TRACE_CONFIGZ_URL + "\" method=\"get\">");
|
||||
out.print(
|
||||
"<input type=\"hidden\" name=\"action\" value=\"" + QUERY_STRING_ACTION_CHANGE + "\" />");
|
||||
emitChangeTable(out);
|
||||
// Button for submit
|
||||
out.print("<button class=\"button\" type=\"submit\" value=\"Submit\">Submit</button>");
|
||||
out.print("</form>");
|
||||
// Button for restore default
|
||||
out.print("<form class=\"form-flex\" action=\"" + TRACE_CONFIGZ_URL + "\" method=\"get\">");
|
||||
out.print(
|
||||
"<input type=\"hidden\" name=\"action\" value=\"" + QUERY_STRING_ACTION_DEFAULT + "\" />");
|
||||
out.print("<button class=\"button\" type=\"submit\" value=\"Submit\">Restore Default</button>");
|
||||
out.print("</form>");
|
||||
out.print("<h2>Active Tracing Parameters</h2>");
|
||||
emitActiveTable(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitHtml(Map<String, String> queryMap, OutputStream outputStream) {
|
||||
// PrintStream for emiting HTML contents
|
||||
try (PrintStream out = new PrintStream(outputStream, /* autoFlush= */ false, "UTF-8")) {
|
||||
out.print("<!DOCTYPE html>");
|
||||
out.print("<html lang=\"en\">");
|
||||
out.print("<head>");
|
||||
out.print("<meta charset=\"UTF-8\">");
|
||||
out.print(
|
||||
"<link rel=\"shortcut icon\" href=\"data:image/png;base64,"
|
||||
+ ZPageLogo.getFaviconBase64()
|
||||
+ "\" type=\"image/png\">");
|
||||
out.print(
|
||||
"<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300\""
|
||||
+ "rel=\"stylesheet\">");
|
||||
out.print(
|
||||
"<link href=\"https://fonts.googleapis.com/css?family=Roboto\" rel=\"stylesheet\">");
|
||||
out.print("<title>" + TRACE_CONFIGZ_NAME + "</title>");
|
||||
emitHtmlStyle(out);
|
||||
out.print("</head>");
|
||||
out.print("<body>");
|
||||
try {
|
||||
// Apply updated trace configuration based on query parameters
|
||||
applyTraceConfig(queryMap);
|
||||
emitHtmlBody(out);
|
||||
} catch (Throwable t) {
|
||||
out.print("Error while generating HTML: " + t.toString());
|
||||
logger.log(Level.WARNING, "error while generating HTML", t);
|
||||
}
|
||||
out.print("</body>");
|
||||
out.print("</html>");
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.WARNING, "error while generating HTML", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply updated trace configuration through the tracerProvider based on query parameters.
|
||||
*
|
||||
* @param queryMap the map containing URL query parameters.
|
||||
* @throws NumberFormatException if one of the {@code double}/{@code integer} valued query string
|
||||
* does not contain a parsable {@code double}/{@code integer}.
|
||||
*/
|
||||
private void applyTraceConfig(Map<String, String> queryMap) {
|
||||
String action = queryMap.get(QUERY_STRING_ACTION);
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
if (action.equals(QUERY_STRING_ACTION_CHANGE)) {
|
||||
TraceConfig.Builder newConfigBuilder = this.tracerProvider.getActiveTraceConfig().toBuilder();
|
||||
String samplingProbabilityStr = queryMap.get(QUERY_STRING_SAMPLING_PROBABILITY);
|
||||
if (samplingProbabilityStr != null) {
|
||||
try {
|
||||
double samplingProbability = Double.parseDouble(samplingProbabilityStr);
|
||||
if (samplingProbability == 0) {
|
||||
newConfigBuilder.setSampler(Samplers.alwaysOff());
|
||||
} else if (samplingProbability == 1) {
|
||||
newConfigBuilder.setSampler(Samplers.alwaysOn());
|
||||
} else {
|
||||
newConfigBuilder.setSampler(Samplers.probability(samplingProbability));
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("SamplingProbability must be of the type double", e);
|
||||
}
|
||||
}
|
||||
String maxNumOfAttributesStr = queryMap.get(QUERY_STRING_MAX_NUM_OF_ATTRIBUTES);
|
||||
if (maxNumOfAttributesStr != null) {
|
||||
try {
|
||||
int maxNumOfAttributes = Integer.parseInt(maxNumOfAttributesStr);
|
||||
newConfigBuilder.setMaxNumberOfAttributes(maxNumOfAttributes);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("MaxNumOfAttributes must be of the type integer", e);
|
||||
}
|
||||
}
|
||||
String maxNumOfEventsStr = queryMap.get(QUERY_STRING_MAX_NUM_OF_EVENTS);
|
||||
if (maxNumOfEventsStr != null) {
|
||||
try {
|
||||
int maxNumOfEvents = Integer.parseInt(maxNumOfEventsStr);
|
||||
newConfigBuilder.setMaxNumberOfEvents(maxNumOfEvents);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("MaxNumOfEvents must be of the type integer", e);
|
||||
}
|
||||
}
|
||||
String maxNumOfLinksStr = queryMap.get(QUERY_STRING_MAX_NUM_OF_LINKS);
|
||||
if (maxNumOfLinksStr != null) {
|
||||
try {
|
||||
int maxNumOfLinks = Integer.parseInt(maxNumOfLinksStr);
|
||||
newConfigBuilder.setMaxNumberOfLinks(maxNumOfLinks);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("MaxNumOfLinks must be of the type integer", e);
|
||||
}
|
||||
}
|
||||
String maxNumOfAttributesPerEventStr =
|
||||
queryMap.get(QUERY_STRING_MAX_NUM_OF_ATTRIBUTES_PER_EVENT);
|
||||
if (maxNumOfAttributesPerEventStr != null) {
|
||||
try {
|
||||
int maxNumOfAttributesPerEvent = Integer.parseInt(maxNumOfAttributesPerEventStr);
|
||||
newConfigBuilder.setMaxNumberOfAttributesPerEvent(maxNumOfAttributesPerEvent);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"MaxNumOfAttributesPerEvent must be of the type integer", e);
|
||||
}
|
||||
}
|
||||
String maxNumOfAttributesPerLinkStr =
|
||||
queryMap.get(QUERY_STRING_MAX_NUM_OF_ATTRIBUTES_PER_LINK);
|
||||
if (maxNumOfAttributesPerLinkStr != null) {
|
||||
try {
|
||||
int maxNumOfAttributesPerLink = Integer.parseInt(maxNumOfAttributesPerLinkStr);
|
||||
newConfigBuilder.setMaxNumberOfAttributesPerLink(maxNumOfAttributesPerLink);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"MaxNumOfAttributesPerLink must be of the type integer", e);
|
||||
}
|
||||
}
|
||||
this.tracerProvider.updateActiveTraceConfig(newConfigBuilder.build());
|
||||
} else if (action.equals(QUERY_STRING_ACTION_DEFAULT)) {
|
||||
TraceConfig defaultConfig = TraceConfig.getDefault().toBuilder().build();
|
||||
this.tracerProvider.updateActiveTraceConfig(defaultConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -538,7 +538,7 @@ final class TracezZPageHandler extends ZPageHandler {
|
|||
+ "rel=\"stylesheet\">");
|
||||
out.print(
|
||||
"<link href=\"https://fonts.googleapis.com/css?family=Roboto\" rel=\"stylesheet\">");
|
||||
out.print("<title>TraceZ</title>");
|
||||
out.print("<title>" + TRACEZ_NAME + "</title>");
|
||||
emitHtmlStyle(out);
|
||||
out.print("</head>");
|
||||
out.print("<body>");
|
||||
|
|
|
|||
|
|
@ -32,9 +32,10 @@ import java.util.Map;
|
|||
/** An {@link HttpHandler} that will be used to render HTML pages using any {@code ZPageHandler}. */
|
||||
final class ZPageHttpHandler implements HttpHandler {
|
||||
// Splitter for splitting URL query parameters
|
||||
private static final Splitter QUERY_SPLITTER = Splitter.on("&").trimResults();
|
||||
private static final Splitter QUERY_SPLITTER = Splitter.on("&").trimResults().omitEmptyStrings();
|
||||
// Splitter for splitting URL query parameters' key value
|
||||
private static final Splitter QUERY_KEYVAL_SPLITTER = Splitter.on("=").trimResults();
|
||||
private static final Splitter QUERY_KEYVAL_SPLITTER =
|
||||
Splitter.on("=").trimResults().omitEmptyStrings();
|
||||
// Query string parameter name for span name
|
||||
private static final String PARAM_SPAN_NAME = "zspanname";
|
||||
// The corresponding ZPageHandler for the zPage (e.g. TracezZPageHandler)
|
||||
|
|
@ -66,8 +67,6 @@ final class ZPageHttpHandler implements HttpHandler {
|
|||
} else {
|
||||
queryMap.put(keyValuePair.get(0), keyValuePair.get(1));
|
||||
}
|
||||
} else {
|
||||
queryMap.put(keyValuePair.get(0), "");
|
||||
}
|
||||
}
|
||||
return ImmutableMap.copyOf(queryMap);
|
||||
|
|
|
|||
|
|
@ -69,12 +69,16 @@ public final class ZPageServer {
|
|||
TracezSpanProcessor.newBuilder().build();
|
||||
private static final TracezDataAggregator tracezDataAggregator =
|
||||
new TracezDataAggregator(tracezSpanProcessor);
|
||||
private static final TracerSdkProvider tracerProvider = OpenTelemetrySdk.getTracerProvider();
|
||||
// Handler for /tracez page
|
||||
private static final ZPageHandler tracezZPageHandler =
|
||||
new TracezZPageHandler(tracezDataAggregator);
|
||||
// Handler for index page, **please include all available zPages in the constructor**
|
||||
// Handler for /traceconfigz page
|
||||
private static final ZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
// Handler for index page, **please include all available ZPageHandlers in the constructor**
|
||||
private static final ZPageHandler indexZPageHandler =
|
||||
new IndexZPageHandler(ImmutableList.of(tracezZPageHandler));
|
||||
new IndexZPageHandler(ImmutableList.of(tracezZPageHandler, traceConfigzZPageHandler));
|
||||
|
||||
private static final Object mutex = new Object();
|
||||
private static final AtomicBoolean isTracezSpanProcesserAdded = new AtomicBoolean(false);
|
||||
|
|
@ -86,7 +90,6 @@ public final class ZPageServer {
|
|||
/** Function that adds the {@link TracezSpanProcessor} to the {@link TracerSdkProvider}. */
|
||||
private static void addTracezSpanProcessor() {
|
||||
if (isTracezSpanProcesserAdded.compareAndSet(false, true)) {
|
||||
TracerSdkProvider tracerProvider = OpenTelemetrySdk.getTracerProvider();
|
||||
tracerProvider.addSpanProcessor(tracezSpanProcessor);
|
||||
}
|
||||
}
|
||||
|
|
@ -121,6 +124,23 @@ public final class ZPageServer {
|
|||
server.createContext(tracezZPageHandler.getUrlPath(), new ZPageHttpHandler(tracezZPageHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@code ZPageHandler} for tracing config. The page displays information about all
|
||||
* active configuration and allow changing the active configuration.
|
||||
*
|
||||
* <p>It displays a change table which allows users to change active configuration.
|
||||
*
|
||||
* <p>It displays an active value table which displays current active configuration.
|
||||
*
|
||||
* <p>Refreshing the page will show the updated active configuration.
|
||||
*
|
||||
* @param server the {@link HttpServer} for the page to register to.
|
||||
*/
|
||||
static void registerTraceConfigzZPageHandler(HttpServer server) {
|
||||
server.createContext(
|
||||
traceConfigzZPageHandler.getUrlPath(), new ZPageHttpHandler(traceConfigzZPageHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all zPages to the given {@link HttpServer} {@code server}.
|
||||
*
|
||||
|
|
@ -130,6 +150,7 @@ public final class ZPageServer {
|
|||
// For future zPages, register them to the server in here
|
||||
registerIndexZPageHandler(server);
|
||||
registerTracezZPageHandler(server);
|
||||
registerTraceConfigzZPageHandler(server);
|
||||
}
|
||||
|
||||
/** Method for stopping the {@link HttpServer} {@code server}. */
|
||||
|
|
|
|||
|
|
@ -39,5 +39,7 @@ final class ZPageStyle {
|
|||
+ ".align-right{text-align: right;}"
|
||||
+ "pre.no-margin{margin: 0;}"
|
||||
+ "pre.wrap-text{white-space:pre-wrap;}"
|
||||
+ "td.bg-white{background-color: #fff;}";
|
||||
+ "td.bg-white{background-color: #fff;}"
|
||||
+ "button.button{background-color: #fff; margin-top: 15px;}"
|
||||
+ "form.form-flex{display: flex; flex-direction: column; align-items: center;}";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public final class SpanBucketTest {
|
|||
|
||||
@Test
|
||||
public void verifyLatencyBucketSizeLimit() {
|
||||
SpanBucket latencyBucket = new SpanBucket(true);
|
||||
SpanBucket latencyBucket = new SpanBucket(/* isLatencyBucket= */ true);
|
||||
Span[] spans = new Span[LATENCY_BUCKET_SIZE + 1];
|
||||
for (int i = 0; i < LATENCY_BUCKET_SIZE + 1; i++) {
|
||||
spans[i] = tracer.spanBuilder(SPAN_NAME).startSpan();
|
||||
|
|
@ -60,7 +60,7 @@ public final class SpanBucketTest {
|
|||
|
||||
@Test
|
||||
public void verifyErrorBucketSizeLimit() {
|
||||
SpanBucket errorBucket = new SpanBucket(false);
|
||||
SpanBucket errorBucket = new SpanBucket(/* isLatencyBucket= */ false);
|
||||
Span[] spans = new Span[ERROR_BUCKET_SIZE + 1];
|
||||
for (int i = 0; i < ERROR_BUCKET_SIZE + 1; i++) {
|
||||
spans[i] = tracer.spanBuilder(SPAN_NAME).startSpan();
|
||||
|
|
@ -82,7 +82,7 @@ public final class SpanBucketTest {
|
|||
public void verifyThreadSafety() throws InterruptedException {
|
||||
int numberOfThreads = 4;
|
||||
int numberOfSpans = 4;
|
||||
SpanBucket spanBucket = new SpanBucket(true);
|
||||
SpanBucket spanBucket = new SpanBucket(/* isLatencyBucket= */ true);
|
||||
final CountDownLatch startSignal = new CountDownLatch(1);
|
||||
final CountDownLatch endSignal = new CountDownLatch(numberOfThreads);
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* Copyright 2020, OpenTelemetry Authors
|
||||
*
|
||||
* Licensed 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 io.opentelemetry.sdk.extensions.zpages;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.trace.Samplers;
|
||||
import io.opentelemetry.sdk.trace.TracerSdkProvider;
|
||||
import io.opentelemetry.sdk.trace.config.TraceConfig;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link TraceConfigzZPageHandler}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public final class TraceConfigzZPageHandlerTest {
|
||||
private static final TracerSdkProvider tracerProvider = OpenTelemetrySdk.getTracerProvider();
|
||||
private static final Map<String, String> emptyQueryMap = ImmutableMap.of();
|
||||
|
||||
@Test
|
||||
public void changeTable_emitRowsCorrectly() {
|
||||
OutputStream output = new ByteArrayOutputStream();
|
||||
String querySamplingProbability = "samplingprobability";
|
||||
String queryMaxNumOfAttributes = "maxnumofattributes";
|
||||
String queryMaxNumOfEvents = "maxnumofevents";
|
||||
String queryMaxNumOfLinks = "maxnumoflinks";
|
||||
String queryMaxNumOfAttributesPerEvent = "maxnumofattributesperevent";
|
||||
String queryMaxNumOfAttributesPerLink = "maxnumofattributesperlink";
|
||||
|
||||
TraceConfigzZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
traceConfigzZPageHandler.emitHtml(emptyQueryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("SamplingProbability to");
|
||||
assertThat(output.toString()).contains("name=" + querySamplingProbability);
|
||||
assertThat(output.toString())
|
||||
.contains("(" + TraceConfig.getDefault().getSampler().getDescription() + ")");
|
||||
assertThat(output.toString()).contains("MaxNumberOfAttributes to");
|
||||
assertThat(output.toString()).contains("name=" + queryMaxNumOfAttributes);
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
"(" + Integer.toString(TraceConfig.getDefault().getMaxNumberOfAttributes()) + ")");
|
||||
assertThat(output.toString()).contains("MaxNumberOfEvents to");
|
||||
assertThat(output.toString()).contains("name=" + queryMaxNumOfEvents);
|
||||
assertThat(output.toString())
|
||||
.contains("(" + Integer.toString(TraceConfig.getDefault().getMaxNumberOfEvents()) + ")");
|
||||
assertThat(output.toString()).contains("MaxNumberOfLinks to");
|
||||
assertThat(output.toString()).contains("name=" + queryMaxNumOfLinks);
|
||||
assertThat(output.toString())
|
||||
.contains("(" + Integer.toString(TraceConfig.getDefault().getMaxNumberOfLinks()) + ")");
|
||||
assertThat(output.toString()).contains("MaxNumberOfAttributesPerEvent to");
|
||||
assertThat(output.toString()).contains("name=" + queryMaxNumOfAttributesPerEvent);
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
"("
|
||||
+ Integer.toString(TraceConfig.getDefault().getMaxNumberOfAttributesPerEvent())
|
||||
+ ")");
|
||||
assertThat(output.toString()).contains("MaxNumberOfAttributesPerLink to");
|
||||
assertThat(output.toString()).contains("name=" + queryMaxNumOfAttributesPerLink);
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
"("
|
||||
+ Integer.toString(TraceConfig.getDefault().getMaxNumberOfAttributesPerLink())
|
||||
+ ")");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeTable_emitRowsCorrectly() {
|
||||
OutputStream output = new ByteArrayOutputStream();
|
||||
|
||||
TraceConfigzZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
traceConfigzZPageHandler.emitHtml(emptyQueryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Sampler");
|
||||
assertThat(output.toString())
|
||||
.contains(">" + tracerProvider.getActiveTraceConfig().getSampler().getDescription() + "<");
|
||||
assertThat(output.toString()).contains("MaxNumberOfAttributes");
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
">"
|
||||
+ Integer.toString(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributes())
|
||||
+ "<");
|
||||
assertThat(output.toString()).contains("MaxNumberOfEvents");
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
">"
|
||||
+ Integer.toString(tracerProvider.getActiveTraceConfig().getMaxNumberOfEvents())
|
||||
+ "<");
|
||||
assertThat(output.toString()).contains("MaxNumberOfLinks");
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
">"
|
||||
+ Integer.toString(tracerProvider.getActiveTraceConfig().getMaxNumberOfLinks())
|
||||
+ "<");
|
||||
assertThat(output.toString()).contains("MaxNumberOfAttributesPerEvent");
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
">"
|
||||
+ Integer.toString(
|
||||
tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerEvent())
|
||||
+ "<");
|
||||
assertThat(output.toString()).contains("MaxNumberOfAttributesPerLink");
|
||||
assertThat(output.toString())
|
||||
.contains(
|
||||
">"
|
||||
+ Integer.toString(
|
||||
tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerLink())
|
||||
+ "<");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appliesChangesCorrectly_formSubmit() {
|
||||
OutputStream output = new ByteArrayOutputStream();
|
||||
String querySamplingProbability = "samplingprobability";
|
||||
String queryMaxNumOfAttributes = "maxnumofattributes";
|
||||
String queryMaxNumOfEvents = "maxnumofevents";
|
||||
String queryMaxNumOfLinks = "maxnumoflinks";
|
||||
String queryMaxNumOfAttributesPerEvent = "maxnumofattributesperevent";
|
||||
String queryMaxNumOfAttributesPerLink = "maxnumofattributesperlink";
|
||||
String newSamplingProbability = "0.001";
|
||||
String newMaxNumOfAttributes = "16";
|
||||
String newMaxNumOfEvents = "16";
|
||||
String newMaxNumOfLinks = "16";
|
||||
String newMaxNumOfAttributesPerEvent = "16";
|
||||
String newMaxNumOfAttributesPerLink = "16";
|
||||
|
||||
Map<String, String> queryMap =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.put("action", "change")
|
||||
.put(querySamplingProbability, newSamplingProbability)
|
||||
.put(queryMaxNumOfAttributes, newMaxNumOfAttributes)
|
||||
.put(queryMaxNumOfEvents, newMaxNumOfEvents)
|
||||
.put(queryMaxNumOfLinks, newMaxNumOfLinks)
|
||||
.put(queryMaxNumOfAttributesPerEvent, newMaxNumOfAttributesPerEvent)
|
||||
.put(queryMaxNumOfAttributesPerLink, newMaxNumOfAttributesPerLink)
|
||||
.build();
|
||||
|
||||
TraceConfigzZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getSampler().getDescription())
|
||||
.isEqualTo(
|
||||
Samplers.probability(Double.parseDouble(newSamplingProbability)).getDescription());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributes())
|
||||
.isEqualTo(Integer.parseInt(newMaxNumOfAttributes));
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfEvents())
|
||||
.isEqualTo(Integer.parseInt(newMaxNumOfEvents));
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfLinks())
|
||||
.isEqualTo(Integer.parseInt(newMaxNumOfLinks));
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerEvent())
|
||||
.isEqualTo(Integer.parseInt(newMaxNumOfAttributesPerEvent));
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerLink())
|
||||
.isEqualTo(Integer.parseInt(newMaxNumOfAttributesPerLink));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appliesChangesCorrectly_restoreDefault() {
|
||||
OutputStream output = new ByteArrayOutputStream();
|
||||
|
||||
Map<String, String> queryMap = ImmutableMap.of("action", "default");
|
||||
|
||||
TraceConfigzZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getSampler().getDescription())
|
||||
.isEqualTo(TraceConfig.getDefault().getSampler().getDescription());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributes())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfAttributes());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfEvents())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfEvents());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfLinks())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfLinks());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerEvent())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfAttributesPerEvent());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerLink())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfAttributesPerLink());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appliesChangesCorrectly_doNotCrashOnNullParameters() {
|
||||
OutputStream output = new ByteArrayOutputStream();
|
||||
|
||||
Map<String, String> queryMap = ImmutableMap.of("action", "change");
|
||||
|
||||
TraceConfigzZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getSampler().getDescription())
|
||||
.isEqualTo(TraceConfig.getDefault().getSampler().getDescription());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributes())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfAttributes());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfEvents())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfEvents());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfLinks())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfLinks());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerEvent())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfAttributesPerEvent());
|
||||
assertThat(tracerProvider.getActiveTraceConfig().getMaxNumberOfAttributesPerLink())
|
||||
.isEqualTo(TraceConfig.getDefault().getMaxNumberOfAttributesPerLink());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyChanges_emitErrorOnInvalidInput() {
|
||||
// Invalid samplingProbability (not type of double)
|
||||
OutputStream output = new ByteArrayOutputStream();
|
||||
TraceConfigzZPageHandler traceConfigzZPageHandler =
|
||||
new TraceConfigzZPageHandler(tracerProvider);
|
||||
Map<String, String> queryMap =
|
||||
ImmutableMap.of("action", "change", "samplingprobability", "invalid");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("SamplingProbability must be of the type double");
|
||||
|
||||
// Invalid samplingProbability (< 0)
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "samplingprobability", "-1");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("probability must be in range [0.0, 1.0]");
|
||||
|
||||
// Invalid samplingProbability (> 1)
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "samplingprobability", "1.1");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("probability must be in range [0.0, 1.0]");
|
||||
|
||||
// Invalid maxNumOfAttributes
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "maxnumofattributes", "invalid");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("MaxNumOfAttributes must be of the type integer");
|
||||
|
||||
// Invalid maxNumOfEvents
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "maxnumofevents", "invalid");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("MaxNumOfEvents must be of the type integer");
|
||||
|
||||
// Invalid maxNumLinks
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "maxnumoflinks", "invalid");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("MaxNumOfLinks must be of the type integer");
|
||||
|
||||
// Invalid maxNumOfAttributesPerEvent
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "maxnumofattributesperevent", "invalid");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString())
|
||||
.contains("MaxNumOfAttributesPerEvent must be of the type integer");
|
||||
|
||||
// Invalid maxNumOfAttributesPerLink
|
||||
output = new ByteArrayOutputStream();
|
||||
traceConfigzZPageHandler = new TraceConfigzZPageHandler(tracerProvider);
|
||||
queryMap = ImmutableMap.of("action", "change", "maxnumofattributesperlink", "invalid");
|
||||
|
||||
traceConfigzZPageHandler.emitHtml(queryMap, output);
|
||||
|
||||
assertThat(output.toString()).contains("Error while generating HTML: ");
|
||||
assertThat(output.toString()).contains("MaxNumOfAttributesPerLink must be of the type integer");
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,6 @@ public final class ZPageHttpHandlerTest {
|
|||
URI uri =
|
||||
new URI("http://localhost:8000/tracez/tracez?zspanname=Test&ztype=1&zsubtype=5&noval");
|
||||
assertThat(ZPageHttpHandler.parseQueryMap(uri))
|
||||
.containsExactly("zspanname", "Test", "ztype", "1", "zsubtype", "5", "noval", "");
|
||||
.containsExactly("zspanname", "Test", "ztype", "1", "zsubtype", "5");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue