An implementation of trace span sender based on Hercules client. Also provides mapping from Hercules events back to spans.
Here's how ISpan instances are mapped into Hercules events (according to schema):
-
TraceId
(mandatory) --->traceId
tag ofUUID
type. -
SpanId
(mandatory) --->spanId
tag ofUUID
type. -
ParentSpanId
(optional) --->parentSpanId
tag ofUUID
type. -
BeginTimestamp
(mandatory) corresponds to 2 tags:beginTimestampUtc
— along
tag that contains the UTC timestamp in 100-ns ticks from Unix epoch.beginTimestampUtcOffset
— along
tag with offset from UTC expressed in 100-ns ticks.
-
EndTimestamp
(optional) also corresponds to 2 tags, both of which can be absent for 'endless' spans:endTimestampUtc
— along
tag that contains the UTC timestamp in 100-ns ticks from Unix epoch.endTimestampUtcOffset
— along
tag with offset from UTC expressed in 100-ns ticks.
-
Annotations
dictionary corresponds to a container with nameannotations
. This container contains a tag for each pair. Keys are translated as-is, and the values are handled according to following conventions:- If the value is a primitive scalar or a vector of primitive scalars natively supported by Hercules (such as
int
,long
,guid
,string
, etc), it's mapped as-is. - Otherwise the value gets converted to
string
: either stringified directly (if it properly overridesToString()
) or serialized to JSON. No further container-like structure is allowed, all values end up being 'flat'.
- If the value is a primitive scalar or a vector of primitive scalars natively supported by Hercules (such as
Hercules event's built-in timestamp is chosen equal to EndTimestampUtc
or BeginTimestampUtc
if former is missing.
Unix epoch used as a reference point for timestamp is 1970-01-01 00:00:00.000Z
.