blob: 2a02cca6fe4304e45ece2e8eeeb4547251a4c064 [file] [log] [blame]
/*
* Copyright 2017, OpenCensus 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.opencensus.contrib.zpages;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.google.common.base.Charsets;
import io.opencensus.trace.config.TraceConfig;
import io.opencensus.trace.config.TraceParams;
import io.opencensus.trace.samplers.Samplers;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Map;
// TODO(bdrutu): Add tests.
// TODO(hailongwen): Remove the usage of `NetworkEvent` in the future.
/**
* HTML page formatter for tracing config. The page displays information about the current active
* tracing configuration and allows users to change it.
*/
final class TraceConfigzZPageHandler extends ZPageHandler {
private static final String TRACE_CONFIGZ_URL = "/traceconfigz";
private final TraceConfig traceConfig;
private static final String CHANGE = "change";
private static final String PERMANENT_CHANGE = "permanently";
private static final String RESTORE_DEFAULT_CHANGE = "restore_default";
private static final String QUERY_COMPONENT_SAMPLING_PROBABILITY = "samplingprobability";
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_ATTRIBUTES = "maxnumberofattributes";
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_ANNOTATIONS = "maxnumberofannotations";
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_NETWORK_EVENTS =
"maxnumberofnetworkevents";
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_LINKS = "maxnumberoflinks";
// TODO(bdrutu): Use post.
// TODO(bdrutu): Refactor this to not use a big "printf".
private static final String TRACECONFIGZ_FORM_BODY =
"<form action=/traceconfigz method=get>%n"
// Permanently changes table.
+ "<table class=\"small\" rules=\"all\">%n"
+ "<td colspan=\"3\" class=\"col_head\">Permanently change "
+ "<input type=\"hidden\" name=\"%s\" value=\"%s\"></td>%n"
+ "<tr><td>SamplingProbability to</td> "
+ "<td><input type=text size=15 name=%s value=\"\"></td> <td>(%s)</td>%n"
+ "<tr><td>MaxNumberOfAttributes to</td> "
+ "<td><input type=text size=15 name=%s value=\"\"></td> <td>(%d)</td>%n"
+ "<tr><td>MaxNumberOfAnnotations to</td>"
+ "<td><input type=text size=15 name=%s value=\"\"></td> <td>(%d)</td>%n"
+ "<tr><td>MaxNumberOfNetworkEvents to</td> "
+ "<td><input type=text size=15 name=%s value=\"\"></td> <td>(%d)</td>%n"
+ "<tr><td>MaxNumberOfLinks to</td>"
+ "<td><input type=text size=15 name=%s value=\"\"></td> <td>(%d)</td>%n"
+ "</table>%n"
// Submit button.
+ "<input class=\"button\" type=submit value=Submit>%n"
+ "</form>";
private static final String RESTORE_DEFAULT_FORM_BODY =
"<form action=/traceconfigz method=get>%n"
// Restore to default.
+ "<b class=\"title\">Restore default</b> %n"
+ "<input type=\"hidden\" name=\"%s\" value=\"%s\"></td>%n"
+ "</br>%n"
// Reset button.
+ "<input class=\"button\" type=submit value=Reset>%n"
+ "</form>";
static TraceConfigzZPageHandler create(TraceConfig traceConfig) {
return new TraceConfigzZPageHandler(traceConfig);
}
@Override
public String getUrlPath() {
return TRACE_CONFIGZ_URL;
}
private static void emitStyle(PrintWriter out) {
out.write("<style>\n");
out.write(Style.style);
out.write("</style>\n");
}
@Override
@SuppressWarnings("deprecation")
public void emitHtml(Map<String, String> queryMap, OutputStream outputStream) {
PrintWriter out =
new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, Charsets.UTF_8)));
out.write("<!DOCTYPE html>\n");
out.write("<html lang=\"en\"><head>\n");
out.write("<meta charset=\"utf-8\">\n");
out.write("<title>TraceConfigZ</title>\n");
out.write("<link rel=\"shortcut icon\" href=\"https://opencensus.io/images/favicon.ico\"/>\n");
out.write(
"<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300\""
+ "rel=\"stylesheet\">\n");
out.write(
"<link href=\"https://fonts.googleapis.com/css?family=Roboto\"" + "rel=\"stylesheet\">\n");
emitStyle(out);
out.write("</head>\n");
out.write("<body>\n");
out.write(
"<p class=\"header\">"
+ "<img class=\"oc\" src=\"https://opencensus.io/img/logo-sm.svg\" />"
+ "Open<span>Census</span></p>");
out.write("<h1 class=\"left\">Trace Configuration</h1>");
out.write("<p></p>");
try {
// Work that can throw exceptions.
maybeApplyChanges(queryMap);
} finally {
// TODO(bdrutu): Maybe display to the page if an exception happened.
// Display the page in any case.
out.printf(
TRACECONFIGZ_FORM_BODY,
CHANGE,
PERMANENT_CHANGE,
QUERY_COMPONENT_SAMPLING_PROBABILITY,
"0.0001", // TODO(bdrutu): Get this from the default sampler (if possible).
QUERY_COMPONENT_MAX_NUMBER_OF_ATTRIBUTES,
TraceParams.DEFAULT.getMaxNumberOfAttributes(),
QUERY_COMPONENT_MAX_NUMBER_OF_ANNOTATIONS,
TraceParams.DEFAULT.getMaxNumberOfAnnotations(),
QUERY_COMPONENT_MAX_NUMBER_OF_NETWORK_EVENTS,
TraceParams.DEFAULT.getMaxNumberOfNetworkEvents(),
QUERY_COMPONENT_MAX_NUMBER_OF_LINKS,
TraceParams.DEFAULT.getMaxNumberOfLinks());
out.write("<br>\n");
out.printf(RESTORE_DEFAULT_FORM_BODY, CHANGE, RESTORE_DEFAULT_CHANGE);
out.write("<br>\n");
emitTraceParamsTable(traceConfig.getActiveTraceParams(), out);
out.write("</body>\n");
out.write("</html>\n");
out.close();
}
}
// If this is a supported change (currently only permanent changes are supported) apply it.
@SuppressWarnings("deprecation")
private void maybeApplyChanges(Map<String, String> queryMap) {
String changeStr = queryMap.get(CHANGE);
if (PERMANENT_CHANGE.equals(changeStr)) {
TraceParams.Builder traceParamsBuilder = traceConfig.getActiveTraceParams().toBuilder();
String samplingProbabilityStr = queryMap.get(QUERY_COMPONENT_SAMPLING_PROBABILITY);
if (!isNullOrEmpty(samplingProbabilityStr)) {
double samplingProbability = Double.parseDouble(samplingProbabilityStr);
traceParamsBuilder.setSampler(Samplers.probabilitySampler(samplingProbability));
}
String maxNumberOfAttributesStr = queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_ATTRIBUTES);
if (!isNullOrEmpty(maxNumberOfAttributesStr)) {
int maxNumberOfAttributes = Integer.parseInt(maxNumberOfAttributesStr);
traceParamsBuilder.setMaxNumberOfAttributes(maxNumberOfAttributes);
}
String maxNumberOfAnnotationsStr = queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_ANNOTATIONS);
if (!isNullOrEmpty(maxNumberOfAnnotationsStr)) {
int maxNumberOfAnnotations = Integer.parseInt(maxNumberOfAnnotationsStr);
traceParamsBuilder.setMaxNumberOfAnnotations(maxNumberOfAnnotations);
}
String maxNumberOfNetworkEventsStr =
queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_NETWORK_EVENTS);
if (!isNullOrEmpty(maxNumberOfNetworkEventsStr)) {
int maxNumberOfNetworkEvents = Integer.parseInt(maxNumberOfNetworkEventsStr);
traceParamsBuilder.setMaxNumberOfNetworkEvents(maxNumberOfNetworkEvents);
}
String maxNumverOfLinksStr = queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_LINKS);
if (!isNullOrEmpty(maxNumverOfLinksStr)) {
int maxNumberOfLinks = Integer.parseInt(maxNumverOfLinksStr);
traceParamsBuilder.setMaxNumberOfLinks(maxNumberOfLinks);
}
traceConfig.updateActiveTraceParams(traceParamsBuilder.build());
} else if (RESTORE_DEFAULT_CHANGE.equals(changeStr)) {
traceConfig.updateActiveTraceParams(TraceParams.DEFAULT);
}
}
// Prints a table to a PrintWriter that shows existing trace parameters.
@SuppressWarnings("deprecation")
private static void emitTraceParamsTable(TraceParams params, PrintWriter out) {
out.write(
"<b class=\"title\">Active tracing parameters:</b><br>\n"
+ "<table class=\"small\" rules=\"all\">\n"
+ " <tr>\n"
+ " <td class=\"col_headR\">Name</td>\n"
+ " <td class=\"col_head\">Value</td>\n"
+ " </tr>\n");
out.printf(
" <tr>%n <td>Sampler</td>%n <td>%s</td>%n </tr>%n",
params.getSampler().getDescription());
out.printf(
" <tr>%n <td>MaxNumberOfAttributes</td>%n <td>%d</td>%n </tr>%n",
params.getMaxNumberOfAttributes());
out.printf(
" <tr>%n <td>MaxNumberOfAnnotations</td>%n <td>%d</td>%n </tr>%n",
params.getMaxNumberOfAnnotations());
out.printf(
" <tr>%n <td>MaxNumberOfNetworkEvents</td>%n <td>%d</td>%n </tr>%n",
params.getMaxNumberOfNetworkEvents());
out.printf(
" <tr>%n <td>MaxNumberOfLinks</td>%n <td>%d</td>%n </tr>%n",
params.getMaxNumberOfLinks());
out.write("</table>\n");
}
private TraceConfigzZPageHandler(TraceConfig traceConfig) {
this.traceConfig = traceConfig;
}
}