TracingInstrument
extends Instrument
with startSpan
method:
/// An `Instrument` with added functionality for distributed tracing. Is uses the span-based tracing model and is
/// based on the OpenTracing/OpenTelemetry spec.
public protocol TracingInstrument: Instrument {
/// Start a new `Span` within the given `BaggageContext` at a given timestamp.
/// - Parameters:
/// - operationName: The name of the operation being traced. This may be a handler function, database call, ...
/// - context: The `BaggageContext` within to start the new `Span`.
/// - kind: The `SpanKind` of the new `Span`.
/// - timestamp: The `DispatchTime` at which to start the new `Span`.
func startSpan(
named operationName: String,
context: BaggageContext,
ofKind kind: SpanKind,
at timestamp: DispatchTime?
) -> Span
}
However, at the same time it provides its default implementation with exactly the same signature.
It is possible to create new type of a TracingInstrument
which does not override the default implementation, example:
extension XRayRecorder: TracingInstrument {
public func extract<Carrier, Extractor>(_ carrier: Carrier, into baggage: inout BaggageContext, using extractor: Extractor) where Carrier == Extractor.Carrier, Extractor : ExtractorProtocol {
// TODO: impl
}
public func inject<Carrier, Injector>(_ baggage: BaggageContext, into carrier: inout Carrier, using injector: Injector) where Carrier == Injector.Carrier, Injector : InjectorProtocol {
// TODO: impl
}
}
in which case:
let instrument: TracingInstrument = XRayRecorder(emitter: emitter)
instrument.startSpan(/ .../)
will be recursively calling itself
I understand the motivation to provide a default implementation was to provide default value for SpanKind
.
Perhaps it would be safer if it was optional from the very beginning:
func startSpan(
named operationName: String,
context: BaggageContext,
ofKind kind: SpanKind?,
at timestamp: DispatchTime?
) -> Span
or not included in the arguments in the extension (in fact the value of kind
is not used at all even if different than default value):
public func startSpan(
named operationName: String,
context: BaggageContext,
at timestamp: DispatchTime? = nil
) -> Span {
self.startSpan(named: operationName, context: context, ofKind: .internal, at: nil)
}