- Changed Random instantiation to a shared Random
- Changed the name of the converter
- Changed generator into random
- Span id is now non-nullable.
- it gets generated in the http filter if it's not there
- it's generated in the spring-integration channels if it wasn't set
Brave's span collector, which turned out to not be a great tool for
direct use. Brave internally creates spans before sending to its
collector, so validation is implicit. The flip side of this is using the
collector directly does not validate spans. This means it is easy to
send invalid ones, for example missing span names. The problem is more
difficult as the data is in binary (thrift).
This introduces HttpZipkinSpanReporter, which validates via zipkin-java
classes before sending on the wire. Moreover, this sends in json to make
debugging problems easier.
This does not fully remove the Brave dependency, as further work is
needed. Particularly, Brave is indirectly referenced in other code.
See https://github.com/openzipkin/zipkin-java/issues/68
See #98 (Reporter is an OpenTracing term)
Zipkin 0.4.1 obviates some duplication of configuration. It is also the
first version that's published as a docker image.
By switching to the published image of zipkin-java, we can be more
consistent, as `spring-cloud-sleuth-zipkin-stream` is derived from that,
not the scala query service.
Recent versions of zipkin and brave operate with http instead of scribe.
This changes the implementation accordingly, as well adds a sampler to
the POST endpoint.
A notable impact is that we no longer require a collector process, as
the zipkin server's POST endpoint is a collector.
Missing service name:
Zipkin service names were logged as null, which is invalid and led to
them showing up as "unknown" in the zipkin ui. This was due to a wiring
bug, and a special-case, which this change fixes.
The special-case was when a sleuth span had no annotations. Since zipkin
service names are attached to annotations, they are only queryable when
annotations exist. When there are no annotations, we add the "lc"
binary annotation, which makes that span attached to the correct service
in zipkin.
Polishing:
Zipkin timestamps were not always set as microseconds. This fixes that.
The de-facto label in zipkin for unknown service is "unknown". This
fixes the code, which formerly fell back to "application".
This also removes complexity in assigning timestamp and duration as we
no longer need to make pseudo-annotations "acquire" and "release".
Finally, this adds tests about above consistently to both scs-zipkin and
scs-zipkin-stream.
If the flag is set then annotations are collected and the data are exported
in zipkin or stream. If not you still get the correlation ids, so a purely
log-oriented solution will always have useful data on all requests.
Instrumentation should be able to get by with only 2
interfaces: TraceManager and TraceAccessor (the former is
not needed if you aren't starting a new Span). No explicit
access to thread locals or manipulation of thread context
is required (except locally where necessary).
A Span is enclosed by a Trace (actually a view of the complete
Trace that would be constructed remotely).
Zipkin now has Span.timestamp/duration, so no more need for
"aquire/release".
This also corrects the host/endpoint logged for timeline annotations, as
it should always be the local process.
KV annotations are just "annotations", and the "start" and "stop"
annotations in zipkin are "acquire" and "release" (since, in
particular the latter can in principle happen more than once
and not necessarily the last thing that happens to a span).
TODO: decide if TraceContextHolder is really holding a Span
or a TraceContext (or TraceScope). Maybe think of a better
name for TraceScope.
There was an ordering error in the conditions as well, causing the
wrong async customizers to be registered. Another issue was the
servlet async processing (request atribute not cached in all branches)
resulting in multiple spans per request.
An @Async method should start a new trace. Still not finished that bit
because if the user also customizes the async post processor there will
be a clash.
Biggest change here is better support for async web requests.
Each async request goes through the TraceFilter multiple times so you
have to re-attach to the span in the request if there is one.
Directly using the collector gives us more control of the annotations.
The main improvement/change here is that we need to send the span
name and parent details downstream as well as the span id. It's not
logically required by the trace model, but zipkin needs it, so it
can set annotations on the parent span (server recv/send).