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

Wrote benchmark tests for the zPages module #1504

Merged
merged 30 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ec31e3e
Removed URLEncoder
williamhu99 Jul 17, 2020
e0fe0ed
Fixed typo
williamhu99 Jul 18, 2020
cf7f5c8
Added URLDecoding
williamhu99 Jul 20, 2020
9db8e7e
Included comment for string replacement
williamhu99 Jul 20, 2020
4127978
Added unit tests for special characters in span names
williamhu99 Jul 20, 2020
e17c337
Resolved URL decoding issues
williamhu99 Jul 21, 2020
bb58b26
Moved url decoding to parseQueryMap and updated the corresponding uni…
williamhu99 Jul 21, 2020
80a5ccf
Added a README file for zPage quickstart
williamhu99 Jul 22, 2020
dcbd9aa
Add images for README
williamhu99 Jul 22, 2020
24ffce2
Updated README
williamhu99 Jul 22, 2020
5047849
Add frontend images
williamhu99 Jul 22, 2020
85a539e
Add backend images
williamhu99 Jul 22, 2020
4156123
Added our design doc
williamhu99 Jul 22, 2020
265cf27
Added details on package
wty27 Jul 23, 2020
c102e45
Reworded a few lines
williamhu99 Jul 23, 2020
e977dcf
Merge branch 'master' of https://github.com/open-telemetry/openteleme…
williamhu99 Jul 23, 2020
ed8ef33
Moved DESIGN.md to a docs folder and changed gradle config to impleme…
williamhu99 Jul 24, 2020
f595909
Changed wording regarding HttpServer requirement
wty27 Jul 27, 2020
806b632
Added zpages folder under docs, resolved broken image links
wty27 Jul 27, 2020
9e4dde8
Resolved comments for the design md file
williamhu99 Jul 27, 2020
86c2a51
Made a few wording changes
williamhu99 Jul 27, 2020
a3c9a5a
Wrote a benchmark test for TracezSpanBuckets (#23)
williamhu99 Jul 29, 2020
07b2fcf
Updated README file (#25)
wty27 Aug 4, 2020
542f756
Wrote benchmark tests for TracezDataAggregator (#24)
williamhu99 Aug 4, 2020
fe056e3
Merged with original repo
williamhu99 Aug 4, 2020
f714b43
Added Javadocs to the TracezDataAggregator benchmark tests
williamhu99 Aug 5, 2020
922e950
Removed benchmark results from README and added a param to the Tracez…
williamhu99 Aug 5, 2020
13d82c4
Update sdk_extensions/zpages/src/jmh/java/io/opentelemetry/sdk/extens…
williamhu99 Aug 6, 2020
5ab6f6a
Added multiple param values for TracezDataAggregatorBenchmark
williamhu99 Aug 6, 2020
18a4141
Merge branch 'master' of github.com:williamhu99/opentelemetry-java in…
williamhu99 Aug 6, 2020
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
17 changes: 14 additions & 3 deletions sdk_extensions/zpages/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# OpenTelemetry SDK Contrib - zPages
# OpenTelemetry SDK Extension zPages

[![Javadocs][javadoc-image]][javadoc-url]

This module contains code for OpenTelemetry's Java zPages, which are a collection of dynamic HTML
This module contains code for the OpenTelemetry Java zPages, which are a collection of dynamic HTML
web pages that display stats and trace data.

* Java 7 compatible.
Expand Down Expand Up @@ -98,4 +98,15 @@ details. For example, here are the details of the `ChildSpan` latency sample (ro
The /traceconfigz zPage displays information about the currently active tracing configuration and
provides an interface for users to modify relevant parameters. Here is what the web page looks like:

![traceconfigz](img/traceconfigz.png)
![traceconfigz](img/traceconfigz.png)

## Benchmark Testing

This module contains two sets of benchmark tests: one for adding spans to an instance of
TracezSpanBuckets and another for retrieving counts and spans with TracezDataAggregator. You can run
the tests yourself with the following commands:

```
./gradlew -PjmhIncludeSingleClass=TracezSpanBucketsBenchmark clean :opentelemetry-sdk-extension-zpages:jmh
./gradlew -PjmhIncludeSingleClass=TracezDataAggregatorBenchmark clean :opentelemetry-sdk-extension-zpages:jmh
```
8 changes: 8 additions & 0 deletions sdk_extensions/zpages/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id "java"
id "maven-publish"

id "me.champeau.gradle.jmh"
id "ru.vyarus.animalsniffer"
}

Expand All @@ -22,3 +23,10 @@ dependencies {

signature "org.codehaus.mojo.signature:java17:1.0@signature"
}

animalsniffer {
// Don't check sourceSets.jmh and sourceSets.test
sourceSets = [
sourceSets.main
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* 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.OpenTelemetrySdk;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Status;
import io.opentelemetry.trace.Tracer;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

/** Benchmark class for {@link TracezDataAggregator}. */
@State(Scope.Benchmark)
public class TracezDataAggregatorBenchmark {

private static final String runningSpan = "RUNNING_SPAN";
private static final String latencySpan = "LATENCY_SPAN";
private static final String errorSpan = "ERROR_SPAN";
private final Tracer tracer =
OpenTelemetrySdk.getTracerProvider().get("TracezDataAggregatorBenchmark");
private final TracezSpanProcessor spanProcessor = TracezSpanProcessor.newBuilder().build();
private final TracezDataAggregator dataAggregator = new TracezDataAggregator(spanProcessor);

@Param({"1000000"})
williamhu99 marked this conversation as resolved.
Show resolved Hide resolved
private int numberOfSpans;

@Setup(Level.Trial)
public final void setup() {
// Generate 1 million running spans, span latencies, and error spans
williamhu99 marked this conversation as resolved.
Show resolved Hide resolved
for (int i = 0; i < numberOfSpans; i++) {
tracer.spanBuilder(runningSpan).startSpan();
tracer.spanBuilder(latencySpan).startSpan().end();
Span error = tracer.spanBuilder(errorSpan).startSpan();
error.setStatus(Status.UNKNOWN);
error.end();
}
}

/** Get span counts with 1 thread. */
@Benchmark
@Threads(value = 1)
williamhu99 marked this conversation as resolved.
Show resolved Hide resolved
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getCounts_01Thread(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpanCounts());
blackhole.consume(dataAggregator.getSpanLatencyCounts());
blackhole.consume(dataAggregator.getErrorSpanCounts());
}

/** Get span counts with 5 threads. */
@Benchmark
@Threads(value = 5)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getCounts_05Threads(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpanCounts());
blackhole.consume(dataAggregator.getSpanLatencyCounts());
blackhole.consume(dataAggregator.getErrorSpanCounts());
}

/** Get span counts with 10 threads. */
@Benchmark
@Threads(value = 10)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getCounts_10Threads(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpanCounts());
blackhole.consume(dataAggregator.getSpanLatencyCounts());
blackhole.consume(dataAggregator.getErrorSpanCounts());
}

/** Get span counts with 20 threads. */
@Benchmark
@Threads(value = 20)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getCounts_20Threads(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpanCounts());
blackhole.consume(dataAggregator.getSpanLatencyCounts());
blackhole.consume(dataAggregator.getErrorSpanCounts());
}

/** Get spans with 1 thread. */
@Benchmark
@Threads(value = 1)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getSpans_01Thread(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpans(runningSpan));
blackhole.consume(dataAggregator.getOkSpans(latencySpan, 0, Long.MAX_VALUE));
blackhole.consume(dataAggregator.getErrorSpans(errorSpan));
}

/** Get spans with 5 threads. */
@Benchmark
@Threads(value = 5)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getSpans_05Threads(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpans(runningSpan));
blackhole.consume(dataAggregator.getOkSpans(latencySpan, 0, Long.MAX_VALUE));
blackhole.consume(dataAggregator.getErrorSpans(errorSpan));
}

/** Get spans with 10 threads. */
@Benchmark
@Threads(value = 10)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getSpans_10Threads(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpans(runningSpan));
blackhole.consume(dataAggregator.getOkSpans(latencySpan, 0, Long.MAX_VALUE));
blackhole.consume(dataAggregator.getErrorSpans(errorSpan));
}

/** Get spans with 20 threads. */
@Benchmark
@Threads(value = 20)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void getSpans_20Threads(Blackhole blackhole) {
blackhole.consume(dataAggregator.getRunningSpans(runningSpan));
blackhole.consume(dataAggregator.getOkSpans(latencySpan, 0, Long.MAX_VALUE));
blackhole.consume(dataAggregator.getErrorSpans(errorSpan));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Tracer;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;

/** Benchmark class for {@link TracezSpanBuckets}. */
@State(Scope.Benchmark)
public class TracezSpanBucketsBenchmark {

private static final String spanName = "BENCHMARK_SPAN";
private static ReadableSpan readableSpan;
private TracezSpanBuckets bucket;

@Setup(Level.Trial)
public final void setup() {
bucket = new TracezSpanBuckets();
Tracer tracer = OpenTelemetrySdk.getTracerProvider().get("TracezZPageBenchmark");
Span span = tracer.spanBuilder(spanName).startSpan();
span.end();
readableSpan = (ReadableSpan) span;
}

@Benchmark
@Threads(value = 1)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void addToBucket_01Thread() {
williamhu99 marked this conversation as resolved.
Show resolved Hide resolved
bucket.addToBucket(readableSpan);
}

@Benchmark
@Threads(value = 5)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void addToBucket_05Threads() {
bucket.addToBucket(readableSpan);
}

@Benchmark
@Threads(value = 10)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void addToBucket_10Threads() {
bucket.addToBucket(readableSpan);
}

@Benchmark
@Threads(value = 20)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void addToBucket_20Threads() {
bucket.addToBucket(readableSpan);
}
}