-
Notifications
You must be signed in to change notification settings - Fork 714
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Adrian Cole
committed
Mar 16, 2020
1 parent
e55da25
commit c45f5f3
Showing
17 changed files
with
1,462 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...rumentation/benchmarks/src/main/java/brave/propagation/B3SinglePropagationBenchmarks.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
...ion/benchmarks/src/main/java/brave/propagation/w3c/TraceContextPropagationBenchmarks.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright 2013-2020 The OpenZipkin 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 brave.propagation.w3c; | ||
|
||
import brave.internal.HexCodec; | ||
import brave.propagation.Propagation; | ||
import brave.propagation.TraceContext; | ||
import brave.propagation.TraceContext.Extractor; | ||
import brave.propagation.TraceContext.Injector; | ||
import brave.propagation.TraceContextOrSamplingFlags; | ||
import java.util.Collections; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.TimeUnit; | ||
import org.openjdk.jmh.annotations.Benchmark; | ||
import org.openjdk.jmh.annotations.BenchmarkMode; | ||
import org.openjdk.jmh.annotations.Fork; | ||
import org.openjdk.jmh.annotations.Measurement; | ||
import org.openjdk.jmh.annotations.Mode; | ||
import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
import org.openjdk.jmh.annotations.Warmup; | ||
import org.openjdk.jmh.runner.Runner; | ||
import org.openjdk.jmh.runner.RunnerException; | ||
import org.openjdk.jmh.runner.options.Options; | ||
import org.openjdk.jmh.runner.options.OptionsBuilder; | ||
|
||
@Measurement(iterations = 5, time = 1) | ||
@Warmup(iterations = 10, time = 1) | ||
@Fork(3) | ||
@BenchmarkMode(Mode.SampleTime) | ||
@OutputTimeUnit(TimeUnit.MICROSECONDS) | ||
public class TraceContextPropagationBenchmarks { | ||
static final Propagation<String> tc = | ||
TraceContextPropagation.FACTORY.create(Propagation.KeyFactory.STRING); | ||
static final Injector<Map<String, String>> tcInjector = tc.injector(Map::put); | ||
static final Extractor<Map<String, String>> tcExtractor = tc.extractor(Map::get); | ||
|
||
static final TraceContext context = TraceContext.newBuilder() | ||
.traceIdHigh(HexCodec.lowerHexToUnsignedLong("67891233abcdef01")) | ||
.traceId(HexCodec.lowerHexToUnsignedLong("2345678912345678")) | ||
.spanId(HexCodec.lowerHexToUnsignedLong("463ac35c9f6413ad")) | ||
.sampled(true) | ||
.build(); | ||
|
||
// TODO: add tracestate examples which prefer the b3 entry | ||
static final Map<String, String> incoming128 = new LinkedHashMap<String, String>() { | ||
{ | ||
put("traceparent", TraceparentFormat.writeTraceparentFormat(context)); | ||
} | ||
}; | ||
|
||
static final Map<String, String> incomingPadded = new LinkedHashMap<String, String>() { | ||
{ | ||
put("traceparent", | ||
TraceparentFormat.writeTraceparentFormat(context.toBuilder().traceIdHigh(0).build())); | ||
} | ||
}; | ||
|
||
static final Map<String, String> incomingMalformed = new LinkedHashMap<String, String>() { | ||
{ | ||
put("traceparent", "b970dafd-0d95-40aa-95d8-1d8725aebe40"); // not ok | ||
} | ||
}; | ||
|
||
static final Map<String, String> nothingIncoming = Collections.emptyMap(); | ||
|
||
@Benchmark public void inject() { | ||
Map<String, String> carrier = new LinkedHashMap<>(); | ||
tcInjector.inject(context, carrier); | ||
} | ||
|
||
@Benchmark public TraceContextOrSamplingFlags extract_128() { | ||
return tcExtractor.extract(incoming128); | ||
} | ||
|
||
@Benchmark public TraceContextOrSamplingFlags extract_padded() { | ||
return tcExtractor.extract(incomingPadded); | ||
} | ||
|
||
@Benchmark public TraceContextOrSamplingFlags extract_nothing() { | ||
return tcExtractor.extract(nothingIncoming); | ||
} | ||
|
||
@Benchmark public TraceContextOrSamplingFlags extract_malformed() { | ||
return tcExtractor.extract(incomingMalformed); | ||
} | ||
|
||
// Convenience main entry-point | ||
public static void main(String[] args) throws RunnerException { | ||
Options opt = new OptionsBuilder() | ||
.addProfiler("gc") | ||
.include(".*" + TraceContextPropagationBenchmarks.class.getSimpleName()) | ||
.build(); | ||
|
||
new Runner(opt).run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
Copyright 2013-2020 The OpenZipkin 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. | ||
--> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>io.zipkin.brave</groupId> | ||
<artifactId>brave-parent</artifactId> | ||
<version>5.10.2-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>brave-propagation-parent</artifactId> | ||
<name>Brave: Trace Propagation Formats</name> | ||
<packaging>pom</packaging> | ||
|
||
<properties> | ||
<main.basedir>${project.basedir}/..</main.basedir> | ||
</properties> | ||
|
||
<modules> | ||
<module>w3c</module> | ||
</modules> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>brave</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>brave-tests</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# brave-propagation-w3c rationale | ||
|
||
## Trace Context Specification | ||
|
||
### Why do we write a tracestate entry? | ||
We write both "traceparent" and a "tracestate" entry for two reasons. The first is due to | ||
incompatibility between the "traceparent" format and our trace context. This is described in another | ||
section. | ||
|
||
The other reason is durability across hops. When your direct upstream is not the same tracing | ||
system, its span ID (which they call parentId in section 3.2.2.4) will not be valid: using it will | ||
break the trace. Instead, we look at our "tracestate" entry, which represents the last known place | ||
in the same system. | ||
|
||
### What is supported by Brave, but not by traceparent format? | ||
|
||
#### `SamplingFlags` can precede a trace | ||
B3 has always had the ability to influence the start of a trace with a sampling decision. For | ||
example, you can propagate `b3=0` to force the next hop to not trace the request. This is used for | ||
things like not sampling health checks. Conversely, you can force sampling by propagating `b3=d` | ||
(the debug flag). `traceparent` requires a trace ID and a span ID, so cannot propagate this. | ||
|
||
#### `TraceIdContext` (trace ID only) | ||
Amazon trace format can propagate a trace ID prior to starting a trace, for correlation purposes. | ||
`traceparent` requires a trace ID and a span ID, so cannot a trace ID standalone. | ||
|
||
#### Not yet sampled/ deferred decision | ||
B3 and Amazon formats support assigning a span ID prior to a sampling decision. `traceparent` has no | ||
way to tell the difference between an explicit no and lack of a decision, as it only has one bit | ||
flag. | ||
|
||
#### Debug flag | ||
B3 has always had a debug flag, which is a way to force a trace even if normal sampling says no. | ||
`traceparent` cannot distinguish between this and a normal decision, as it only has one bit flag. | ||
|
||
#### Trace-scoped sampling decision | ||
`traceparent` does not distinguish between a hop-level or a trace scoped decision in the format. | ||
This means that traces can be broken as it is valid to change the decision at every step (which | ||
breaks the hierarchy). This is the main reason why we need a separate `tracestate` entry. | ||
|
||
### Why serialize the trace context in two formats? | ||
|
||
The "traceparent" header is only portable to get the `TraceContext.traceId()` and | ||
`TraceContext.spanId()`. Section 3.2.2.5.1, the sampled flag, is incompatible with B3 sampling. The | ||
format also lacks fields for `TraceContext.parentId()` and `TraceContext.debug()`. This requires us | ||
to re-serialize the same context in two formats: one for compliance ("traceparent") and one that | ||
actually stores the context (B3 single format). | ||
|
||
The impact on users will be higher overhead and confusion when comparing the sampled value of | ||
"traceparent" which may be different than "b3". | ||
|
||
### Why is traceparent incompatible with B3? | ||
|
||
It may seem like incompatibility between "traceparent" and B3 were accidental, but that was not the | ||
case. The Zipkin community held the first meetings leading to this specification, and were directly | ||
involved in the initial design. Use cases of B3 were well known by working group members. Choices to | ||
become incompatible with B3 (and Amazon X-Ray format) sampling were conscious, as were decisions to | ||
omit other fields we use. These decisions were made in spite of protest from Zipkin community | ||
members and others. There is a rationale document for the specification, but the working group has | ||
so far not explained these decisions, or even mention B3 at all. | ||
|
||
https://github.com/w3c/trace-context/blob/d2ed8084780efcedab7e60c48b06ca3c00bea55c/http_header_format_rationale.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# brave-propagation-w3c | ||
|
||
This project includes propagation handlers for W3C defined headers. | ||
|
||
## Trace Context | ||
The [Trace Context][https://w3c.github.io/trace-context/] specification defines two headers: | ||
|
||
* `traceparent` - almost the same as our [B3-single format](https://github.com/openzipkin/b3-propagation#single-header) | ||
* `tracestate` - vendor-specific (or format-specific): may impact how to interpret `traceparent` | ||
|
||
This implementation can survive mixed systems who follow the specification and forward the | ||
`tracestate` header. When writing the `traceparent` header, this also overwrites the `tracestate` | ||
entry named 'b3' (in B3 single format). When reading headers, this entry is favored over the | ||
`traceparent`, allowing the the next span to re-attach to the last known 'b3' header. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
Copyright 2013-2020 The OpenZipkin 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. | ||
--> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<groupId>io.zipkin.brave</groupId> | ||
<artifactId>brave-propagation-parent</artifactId> | ||
<version>5.10.2-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>brave-propagation-w3c</artifactId> | ||
<name>Brave Propagation: W3C Tracing headers (traceparent, tracestate, etc.)</name> | ||
|
||
<properties> | ||
<main.basedir>${project.basedir}/../..</main.basedir> | ||
<main.java.version>1.6</main.java.version> | ||
<main.signature.artifact>java16</main.signature.artifact> | ||
</properties> | ||
|
||
<dependencies> | ||
<!-- to mock Platform calls --> | ||
<dependency> | ||
<groupId>org.powermock</groupId> | ||
<artifactId>powermock-module-junit4</artifactId> | ||
<version>${powermock.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.powermock</groupId> | ||
<artifactId>powermock-api-mockito2</artifactId> | ||
<version>${powermock.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-jar-plugin</artifactId> | ||
<configuration> | ||
<archive> | ||
<manifestEntries> | ||
<Automatic-Module-Name>brave.propagation.w3c</Automatic-Module-Name> | ||
</manifestEntries> | ||
</archive> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
Oops, something went wrong.