Skip to content

Instantly share code, notes, and snippets.

HttpServletRequest httpRequest = (HttpServletRequest) request;
TraceContextOrSamplingFlags contextOrFlags = contextExtractor.extract(httpRequest);
Span span = contextOrFlags.context() != null
? tracer.joinSpan(contextOrFlags.context())
: tracer.newTrace(contextOrFlags.samplingFlags());
@codefromthecrypt
codefromthecrypt / normal-instrumentation.txt
Last active January 11, 2017 05:02
Normal case of Zipkin instrumentation
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ Tracer: Web │ │ Tracer: App │
│ │ │ │
└──────────────────────────────┘ │ └──────────────────────────────┘
────────────────────────────────────┴───────────────────────────────────
┌ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌─────────────────────────────┐
(1) │(1) Web tracer starts a trace│
│ sr │ │ since no headers exist │
─────────▶ └─────────────────────────────┘
@codefromthecrypt
codefromthecrypt / kakfa-oneway.java
Last active July 12, 2018 19:56
Kafka one-way with Brave
/**
* This is an example of a one-way or "messaging span", which is possible by use of the {@link
* Span#flush()} operator.
*
* <p>Note that this uses a span as a kafka key, not because it is recommended, rather as it is
* convenient for demonstration, since kafka doesn't have message properties.
*
* <p>See https://github.com/openzipkin/zipkin/issues/1243
*/
public class KafkaExampleIT {
@codefromthecrypt
codefromthecrypt / textikflow.txt
Created January 2, 2017 07:39
example tracing flow made with textik
I made this with https://textik.com in attempts to explain how service naming work. Since english is
second language for many coders, diagrams help. In this case, achieved understanding in <20 minutes!
The tracer on Server A starts a trace since is doesn't read
headers or anything from the browser's request. In zipkin
this has annotation "sr" with the serviceName "loginService"
-\
-\ Server A has role loginService, so its tracer is named that.
Browser -\+--------------+
@codefromthecrypt
codefromthecrypt / opentracing-zipkin.md
Last active October 27, 2021 01:44
My ramble on OpenTracing (with a side of Zipkin)

I've had many people ask me questions about OpenTracing, often in relation to OpenZipkin. I've seen assertions about how it is vendor neutral and is the lock-in cure. This post is not a sanctioned, polished or otherwise muted view, rather what I personally think about what it is and is not, and what it helps and does not help with. Scroll to the very end if this is too long. Feel free to add a comment if I made any factual mistakes or you just want to add a comment.

So, what is OpenTracing?

OpenTracing is documentation and library interfaces for distributed tracing instrumentation. To be "OpenTracing" requires bundling its interfaces in your work, so that others can use it to time distributed operations with the same library.

So, who is it for?

OpenTracing interfaces are targeted to authors of instrumentation libraries, and those who want to collaborate with traces created by them. Ex something started a trace somewhere and I add a notable event to that trace. Structure logging was recently added to O

public final class HttpClient4Instrumentation {
public static class Config extends ClientHandler.Config<HttpRequest, HttpResponse> {
@Override protected Parser<HttpRequest, String> spanNameParser() {
return r -> r.getRequestLine().getMethod();
}
@Override protected TagsParser<HttpRequest> requestTagsParser() {
return TagsParser.builder(HttpRequest.class)
.addParser(TraceKeys.HTTP_URL, input -> input.getRequestLine().getUri())
[[{"traceId":"ffdc9bb9a6453df3","id":"ffdc9bb9a6453df3","name":"http:/","timestamp":1478624611519000,"duration":11940,"annotations":[{"timestamp":1478624611519000,"value":"sr","endpoint":{"serviceName":"frontend","ipv4":"127.0.0.1","port":8081}},{"timestamp":1478624611530000,"value":"ss","endpoint":{"serviceName":"frontend","ipv4":"127.0.0.1","port":8081}}]},{"traceId":"ffdc9bb9a6453df3","id":"b89b8dfb23214f08","name":"call-backend","parentId":"ffdc9bb9a6453df3","timestamp":1478624611521000,"duration":9012,"binaryAnnotations":[{"key":"lc","value":"unknown","endpoint":{"serviceName":"frontend","ipv4":"127.0.0.1","port":8081}},{"key":"mvc.controller.class","value":"Frontend","endpoint":{"serviceName":"frontend","ipv4":"127.0.0.1","port":8081}},{"key":"mvc.controller.method","value":"callBackend","endpoint":{"serviceName":"frontend","ipv4":"127.0.0.1","port":8081}}]},{"traceId":"ffdc9bb9a6453df3","id":"a50cd5a4f50046de","name":"http:/api","parentId":"b89b8dfb23214f08","timestamp":1478624611521000,"duration":6516
[
{
"traceId": "4e441824ec2b6a44",
"id": "4e441824ec2b6a44",
"name": "get",
"timestamp": 1477975620117000,
"duration": 500209,
"annotations": [
{
"timestamp": 1477975620117000,
/**
* Instrumentation should set {@link Span#timestamp} when recording a span so that guess-work
* isn't needed. Since a lot of instrumentation don't, we have to make some guesses.
*
* <pre><ul>
* <li>If there is a {@link Constants#CLIENT_SEND}, use that</li>
* <li>Fall back to {@link Constants#SERVER_RECV}, if a root span</li>
* <li>Otherwise, return null</li>
* </ul></pre>
*/
@codefromthecrypt
codefromthecrypt / gist:8b73f488bfeb1d8dc86a8a2b5ee5c4ad
Created August 30, 2016 17:29
Finally got zipkin span encoding into the single-digit microsecond range
CodecBenchmarks.writeClientSpan_json_zipkin avgt 15 1.445 ± 0.036 us/op
CodecBenchmarks.writeClientSpan_thrift_libthrift avgt 15 1.951 ± 0.014 us/op
CodecBenchmarks.writeClientSpan_thrift_zipkin avgt 15 0.433 ± 0.011 us/op
CodecBenchmarks.writeLocalSpan_json_zipkin avgt 15 0.813 ± 0.010 us/op
CodecBenchmarks.writeLocalSpan_thrift_libthrift avgt 15 1.191 ± 0.016 us/op
CodecBenchmarks.writeLocalSpan_thrift_zipkin avgt 15 0.268 ± 0.004 us/op
CodecBenchmarks.writeRpcSpan_json_zipkin avgt 15 3.606 ± 0.068 us/op
CodecBenchmarks.writeRpcSpan_thrift_libthrift avgt 15 5.134 ± 0.081 us/op
CodecBenchmarks.writeRpcSpan_thrift_zipkin avgt 15 1.384 ± 0.078 us/op
CodecBenchmarks.writeRpcV6Span_json_zipkin avgt 15 3.912 ± 0.115 us/op