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

Commit 365c32f

Browse files
author
Bogdan Drutu
authored
Add a simple traceconfigz page. (#590)
* Add a simple traceconfigz page. * Apply google formatter. * Fix warning VA_FORMAT_STRING_USES_NEWLINE. * Add getDescription and polish the HTML. * Update based on comments.
1 parent 1f25cb4 commit 365c32f

File tree

9 files changed

+247
-7
lines changed

9 files changed

+247
-7
lines changed

api/src/main/java/io/opencensus/trace/Sampler.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public abstract class Sampler {
3030
* is a root span.
3131
* @param traceId the {@link TraceId} for the new {@code Span}. This will be identical to that in
3232
* the parentContext, unless this is a root span.
33-
* @param spanId the span ID for the new {@code Span}.
33+
* @param spanId the {@link SpanId} for the new {@code Span}.
3434
* @param name the name of the new {@code Span}.
3535
* @param parentLinks the parentLinks associated with the new {@code Span}.
3636
* @return {@code true} if the {@code Span} is sampled.
@@ -42,4 +42,14 @@ public abstract boolean shouldSample(
4242
SpanId spanId,
4343
String name,
4444
List<Span> parentLinks);
45+
46+
/**
47+
* Returns the description of this {@code Sampler}. This may be displayed on debug pages or in
48+
* the logs.
49+
*
50+
* <p>Example: "ProbabilitySampler{0.000100}"
51+
*
52+
* @return the description of this {@code Sampler}.
53+
*/
54+
public abstract String getDescription();
4555
}

api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public boolean shouldSample(
4343
return true;
4444
}
4545

46+
@Override
47+
public String getDescription() {
48+
return toString();
49+
}
50+
4651
@Override
4752
public String toString() {
4853
return "AlwaysSampleSampler";

api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public boolean shouldSample(
4343
return false;
4444
}
4545

46+
@Override
47+
public String getDescription() {
48+
return toString();
49+
}
50+
4651
@Override
4752
public String toString() {
4853
return "NeverSampleSampler";

api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,9 @@ public final boolean shouldSample(
9292
// code is executed in-line for every Span creation).
9393
return Math.abs(traceId.getLowerLong()) < getIdUpperBound();
9494
}
95+
96+
@Override
97+
public final String getDescription() {
98+
return String.format("ProbabilitySampler{%.6f}", getProbability());
99+
}
95100
}

contrib/zpages/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ apply plugin: 'java'
88
}
99

1010
dependencies {
11-
compile project(':opencensus-api')
11+
compile project(':opencensus-api'),
12+
libraries.guava
1213

1314
signature "org.codehaus.mojo.signature:java18:+@signature"
1415
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* Copyright 2017, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opencensus.contrib.zpages;
18+
19+
import static com.google.common.base.Strings.isNullOrEmpty;
20+
21+
import com.google.common.base.Charsets;
22+
import io.opencensus.trace.config.TraceConfig;
23+
import io.opencensus.trace.config.TraceParams;
24+
import io.opencensus.trace.samplers.Samplers;
25+
import java.io.BufferedWriter;
26+
import java.io.OutputStream;
27+
import java.io.OutputStreamWriter;
28+
import java.io.PrintWriter;
29+
import java.util.Map;
30+
31+
// TODO(bdrutu): Add tests.
32+
/**
33+
* HTML page formatter for tracing config. The page displays information about the current active
34+
* tracing configuration and allows users to change it.
35+
*/
36+
final class TraceConfigzZPageHandler extends ZPageHandler {
37+
private static final String TRACE_CONFIGZ_URL = "/traceconfigz";
38+
private final TraceConfig traceConfig;
39+
40+
private static final String CHANGE = "change";
41+
private static final String PERMANENT_CHANGE = "permanently";
42+
private static final String RESTORE_DEFAULT_CHANGE = "restore_default";
43+
private static final String QUERY_COMPONENT_SAMPLING_PROBABILITY = "samplingprobability";
44+
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_ATTRIBUTES = "maxnumberofattributes";
45+
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_ANNOTATIONS = "maxnumberofannotations";
46+
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_NETWORK_EVENTS =
47+
"maxnumberofnetworkevents";
48+
private static final String QUERY_COMPONENT_MAX_NUMBER_OF_LINKS = "maxnumberoflinks";
49+
50+
// TODO(bdrutu): Use post.
51+
// TODO(bdrutu): Refactor this to not use a big "printf".
52+
private static final String TRACECONFIGZ_FORM_BODY =
53+
"<form action=/traceconfigz method=get>%n"
54+
// Permanently changes table.
55+
+ "<table>%n"
56+
+ "<td colspan=\"3\"><b>Permanently change</b> "
57+
+ "<input type=\"hidden\" name=\"%s\" value=\"%s\"></td>%n"
58+
+ "<tr><td>SamplingProbability to</td> "
59+
+ "<td><input type=text size=10 name=%s value=\"\"></td> <td>(%s)</td>%n"
60+
+ "<tr><td>MaxNumberOfAttributes to</td> "
61+
+ "<td><input type=text size=10 name=%s value=\"\"></td> <td>(%d)</td>%n"
62+
+ "<tr><td>MaxNumberOfAnnotations to</td>"
63+
+ "<td><input type=text size=10 name=%s value=\"\"></td> <td>(%d)</td>%n"
64+
+ "<tr><td>MaxNumberOfNetworkEvents to</td> "
65+
+ "<td><input type=text size=10 name=%s value=\"\"></td> <td>(%d)</td>%n"
66+
+ "<tr><td>MaxNumberOfLinks to</td>"
67+
+ "<td><input type=text size=10 name=%s value=\"\"></td> <td>(%d)</td>%n"
68+
+ "</table>%n"
69+
// Submit button.
70+
+ "<input type=submit value=Submit>%n"
71+
+ "</form>";
72+
73+
private static final String RESTORE_DEFAULT_FORM_BODY =
74+
"<form action=/traceconfigz method=get>%n"
75+
// Restore to default.
76+
+ "<b>Restore default</b> %n"
77+
+ "<input type=\"hidden\" name=\"%s\" value=\"%s\"></td>%n"
78+
+ "</br>%n"
79+
// Reset button.
80+
+ "<input type=submit value=Reset>%n"
81+
+ "</form>";
82+
83+
static TraceConfigzZPageHandler create(TraceConfig traceConfig) {
84+
return new TraceConfigzZPageHandler(traceConfig);
85+
}
86+
87+
@Override
88+
public String getUrlPath() {
89+
return TRACE_CONFIGZ_URL;
90+
}
91+
92+
@Override
93+
public void emitHtml(Map<String, String> queryMap, OutputStream outputStream) {
94+
PrintWriter out =
95+
new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, Charsets.UTF_8)));
96+
out.write("<!DOCTYPE html>\n");
97+
out.write("<html lang=\"en\"><head>\n");
98+
out.write("<meta charset=\"utf-8\">\n");
99+
out.write("<title>TraceConfigZ</title>\n");
100+
out.write("<link rel=\"shortcut icon\" href=\"//www.opencensus.io/favicon.ico\"/>\n");
101+
out.write("</head>\n");
102+
out.write("<body>\n");
103+
try {
104+
// Work that can throw exceptions.
105+
maybeApplyChanges(queryMap);
106+
} finally {
107+
// TODO(bdrutu): Maybe display to the page if an exception happened.
108+
// Display the page in any case.
109+
out.printf(
110+
TRACECONFIGZ_FORM_BODY,
111+
CHANGE,
112+
PERMANENT_CHANGE,
113+
QUERY_COMPONENT_SAMPLING_PROBABILITY,
114+
"0.0001", // TODO(bdrutu): Get this from the default sampler (if possible).
115+
QUERY_COMPONENT_MAX_NUMBER_OF_ATTRIBUTES,
116+
TraceParams.DEFAULT.getMaxNumberOfAttributes(),
117+
QUERY_COMPONENT_MAX_NUMBER_OF_ANNOTATIONS,
118+
TraceParams.DEFAULT.getMaxNumberOfAnnotations(),
119+
QUERY_COMPONENT_MAX_NUMBER_OF_NETWORK_EVENTS,
120+
TraceParams.DEFAULT.getMaxNumberOfNetworkEvents(),
121+
QUERY_COMPONENT_MAX_NUMBER_OF_LINKS,
122+
TraceParams.DEFAULT.getMaxNumberOfLinks());
123+
out.write("<br>\n");
124+
out.printf(RESTORE_DEFAULT_FORM_BODY, CHANGE, RESTORE_DEFAULT_CHANGE);
125+
out.write("<br>\n");
126+
emitTraceParamsTable(traceConfig.getActiveTraceParams(), out);
127+
out.write("</body>\n");
128+
out.write("</html>\n");
129+
out.close();
130+
}
131+
}
132+
133+
// If this is a supported change (currently only permanent changes are supported) apply it.
134+
private void maybeApplyChanges(Map<String, String> queryMap) {
135+
String changeStr = queryMap.get(CHANGE);
136+
if (PERMANENT_CHANGE.equals(changeStr)) {
137+
TraceParams.Builder traceParamsBuilder = traceConfig.getActiveTraceParams().toBuilder();
138+
String samplingProbabilityStr = queryMap.get(QUERY_COMPONENT_SAMPLING_PROBABILITY);
139+
if (!isNullOrEmpty(samplingProbabilityStr)) {
140+
double samplingProbability = Double.parseDouble(samplingProbabilityStr);
141+
traceParamsBuilder.setSampler(Samplers.probabilitySampler(samplingProbability));
142+
}
143+
String maxNumberOfAttributesStr = queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_ATTRIBUTES);
144+
if (!isNullOrEmpty(maxNumberOfAttributesStr)) {
145+
int maxNumberOfAttributes = Integer.parseInt(maxNumberOfAttributesStr);
146+
traceParamsBuilder.setMaxNumberOfAttributes(maxNumberOfAttributes);
147+
}
148+
String maxNumberOfAnnotationsStr = queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_ANNOTATIONS);
149+
if (!isNullOrEmpty(maxNumberOfAnnotationsStr)) {
150+
int maxNumberOfAnnotations = Integer.parseInt(maxNumberOfAnnotationsStr);
151+
traceParamsBuilder.setMaxNumberOfAnnotations(maxNumberOfAnnotations);
152+
}
153+
String maxNumberOfNetworkEventsStr =
154+
queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_NETWORK_EVENTS);
155+
if (!isNullOrEmpty(maxNumberOfNetworkEventsStr)) {
156+
int maxNumberOfNetworkEvents = Integer.parseInt(maxNumberOfNetworkEventsStr);
157+
traceParamsBuilder.setMaxNumberOfNetworkEvents(maxNumberOfNetworkEvents);
158+
}
159+
String maxNumverOfLinksStr = queryMap.get(QUERY_COMPONENT_MAX_NUMBER_OF_LINKS);
160+
if (!isNullOrEmpty(maxNumverOfLinksStr)) {
161+
int maxNumberOfLinks = Integer.parseInt(maxNumverOfLinksStr);
162+
traceParamsBuilder.setMaxNumberOfLinks(maxNumberOfLinks);
163+
}
164+
traceConfig.updateActiveTraceParams(traceParamsBuilder.build());
165+
} else if (RESTORE_DEFAULT_CHANGE.equals(changeStr)) {
166+
traceConfig.updateActiveTraceParams(TraceParams.DEFAULT);
167+
}
168+
}
169+
170+
// Prints a table to a PrintWriter that shows existing trace parameters.
171+
private static void emitTraceParamsTable(TraceParams params, PrintWriter out) {
172+
out.write(
173+
"<b>Active tracing parameters:</b><br>\n"
174+
+ "<table rules=\"all\" frame=\"border\">\n"
175+
+ " <tr style=\"background: #eee\">\n"
176+
+ " <td><b>Name</b></td>\n"
177+
+ " <td><b>Value</b></td>\n"
178+
+ " </tr>\n");
179+
out.printf(
180+
" <tr>%n <td>Sampler</td>%n <td>%s</td>%n </tr>%n",
181+
params.getSampler().getDescription());
182+
out.printf(
183+
" <tr>%n <td>MaxNumberOfAttributes</td>%n <td>%d</td>%n </tr>%n",
184+
params.getMaxNumberOfAttributes());
185+
out.printf(
186+
" <tr>%n <td>MaxNumberOfAnnotations</td>%n <td>%d</td>%n </tr>%n",
187+
params.getMaxNumberOfAnnotations());
188+
out.printf(
189+
" <tr>%n <td>MaxNumberOfNetworkEvents</td>%n <td>%d</td>%n </tr>%n",
190+
params.getMaxNumberOfNetworkEvents());
191+
out.printf(
192+
" <tr>%n <td>MaxNumberOfLinks</td>%n <td>%d</td>%n </tr>%n",
193+
params.getMaxNumberOfLinks());
194+
195+
out.write("</table>\n");
196+
}
197+
198+
private TraceConfigzZPageHandler(TraceConfig traceConfig) {
199+
this.traceConfig = traceConfig;
200+
}
201+
}

contrib/zpages/src/main/java/io/opencensus/contrib/zpages/TracezZPageHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ private TracezZPageHandler(
134134
* @param sampledSpanStore the instance of the {@code SampledSpanStore} to be used.
135135
* @return a new {@code TracezZPageHandler}.
136136
*/
137-
public static TracezZPageHandler create(
137+
static TracezZPageHandler create(
138138
@Nullable RunningSpanStore runningSpanStore, @Nullable SampledSpanStore sampledSpanStore) {
139139
return new TracezZPageHandler(runningSpanStore, sampledSpanStore);
140140
}

contrib/zpages/src/main/java/io/opencensus/contrib/zpages/ZPageHandler.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ public abstract class ZPageHandler {
4040
*/
4141
public abstract void emitHtml(Map<String, String> queryMap, OutputStream outputStream);
4242

43-
/**
44-
* Package protected constructor to disallow users to extend this class.
45-
*/
43+
/** Package protected constructor to disallow users to extend this class. */
4644
ZPageHandler() {}
4745
}

contrib/zpages/src/main/java/io/opencensus/contrib/zpages/ZPageHandlers.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,11 @@ public final class ZPageHandlers {
6565
TracezZPageHandler.create(
6666
Tracing.getExportComponent().getRunningSpanStore(),
6767
Tracing.getExportComponent().getSampledSpanStore());
68+
private static final ZPageHandler traceConfigzZPageHandler =
69+
TraceConfigzZPageHandler.create(Tracing.getTraceConfig());
6870

6971
private static final Object monitor = new Object();
72+
7073
@GuardedBy("monitor")
7174
private static HttpServer server;
7275

@@ -86,13 +89,25 @@ public static ZPageHandler getTracezZPageHandler() {
8689
return tracezZPageHandler;
8790
}
8891

92+
/**
93+
* Returns a {@code ZPageHandler} for tracing config. The page displays information about all
94+
* active configuration and allow changing the active configuration.
95+
*
96+
* @return a {@code ZPageHandler} for tracing config.
97+
*/
98+
public static ZPageHandler getTraceConfigzZPageHandler() {
99+
return traceConfigzZPageHandler;
100+
}
101+
89102
/**
90103
* Registers all pages to the given {@code HttpServer}.
91104
*
92105
* @param server the server that exports the tracez page.
93106
*/
94107
public static void registerAllToHttpServer(HttpServer server) {
95108
server.createContext(tracezZPageHandler.getUrlPath(), new ZPageHttpHandler(tracezZPageHandler));
109+
server.createContext(
110+
traceConfigzZPageHandler.getUrlPath(), new ZPageHttpHandler(traceConfigzZPageHandler));
96111
}
97112

98113
/**
@@ -124,7 +139,7 @@ public void run() {
124139
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
125140
logger.fine("*** Shutting down gRPC server (JVM shutting down)");
126141
ZPageHandlers.stop();
127-
logger.fine("*** server shut down");
142+
logger.fine("*** Server shut down");
128143
}
129144
});
130145
}

0 commit comments

Comments
 (0)