diff --git a/Sources/Tracing/NoOpTracer.swift b/Sources/Tracing/NoOpTracer.swift index e270051..4b10829 100644 --- a/Sources/Tracing/NoOpTracer.swift +++ b/Sources/Tracing/NoOpTracer.swift @@ -139,6 +139,12 @@ public struct NoOpTracer: LegacyTracer { } } + /// Update the span attributes in a block instead of individually. + /// + /// The NoOpSpan implementation does not call the closure as setting attributes + /// on a NoOpSpan does nothing. + public func updateAttributes(_ update: (inout SpanAttributes) -> Void) {} + /// Finishes the span. /// - Parameter instant: the time instant the span completed. public func end(at instant: @autoclosure () -> Instant) { diff --git a/Sources/Tracing/SpanProtocol.swift b/Sources/Tracing/SpanProtocol.swift index a207618..21d548f 100644 --- a/Sources/Tracing/SpanProtocol.swift +++ b/Sources/Tracing/SpanProtocol.swift @@ -92,6 +92,17 @@ public protocol Span: Sendable { nonmutating set } + /// Update the span attributes in a block instead of individually. + /// + /// Updating a span attribute involves some type of thread synchronisation + /// primitive to avoid multiple threads updating the attributes at the same + /// time. If you update each attribute individually, this can cause slowdown. + /// This function updates the attributes in one call to avoid hitting the + /// thread synchronisation code multiple times. + /// + /// - Parameter update: closure used to update span attributes + func updateAttributes(_ update: (inout SpanAttributes) -> Void) + /// A Boolean value that indicates whether the span is recording information such as events, attributes, status, and so on. var isRecording: Bool { get }