Skip to content

Commit ede4ce3

Browse files
committed
!time define Timestamp backed by DispatchWallTime
1 parent d9bdcc8 commit ede4ce3

File tree

10 files changed

+128
-42
lines changed

10 files changed

+128
-42
lines changed

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let package = Package(
1111
dependencies: [
1212
.package(
1313
name: "swift-baggage-context",
14-
url: "https://github.com/slashmo/gsoc-swift-baggage-context.git",
14+
url: "https://github.com/slashmo/gsoc-swift-baggage-context",
1515
from: "0.1.0"
1616
),
1717
.package(url: "https://github.com/apple/swift-nio.git", from: "2.17.0"),

Sources/Instrumentation/Tracing/NoOpTracing.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
import Baggage
15-
import Dispatch
1615

1716
/// No operation TracingInstrument, used when no tracing is required.
1817
public struct NoOpTracingInstrument: TracingInstrument {
1918
public func startSpan(
2019
named operationName: String,
2120
context: BaggageContext,
2221
ofKind kind: SpanKind,
23-
at timestamp: DispatchTime?
22+
at timestamp: Timestamp?
2423
) -> Span {
2524
NoOpSpan()
2625
}
@@ -40,11 +39,11 @@ public struct NoOpTracingInstrument: TracingInstrument {
4039
public var status: SpanStatus?
4140
public let kind: SpanKind = .internal
4241

43-
public var startTimestamp: DispatchTime {
42+
public var startTimestamp: Timestamp {
4443
.now()
4544
}
4645

47-
public var endTimestamp: DispatchTime? = nil
46+
public var endTimestamp: Timestamp?
4847

4948
public var baggage: BaggageContext {
5049
.init()
@@ -65,7 +64,7 @@ public struct NoOpTracingInstrument: TracingInstrument {
6564

6665
public let isRecording = false
6766

68-
public mutating func end(at timestamp: DispatchTime) {
67+
public mutating func end(at timestamp: Timestamp) {
6968
// ignore
7069
}
7170
}

Sources/Instrumentation/Tracing/Span.swift

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
import Baggage
15-
import Dispatch
1615

1716
/// A `Span` type that follows the OpenTracing/OpenTelemetry spec. The span itself should not be
1817
/// initializable via its public interface. `Span` creation should instead go through `tracer.startSpan`
@@ -30,11 +29,11 @@ public protocol Span {
3029
/// The status of this span.
3130
var status: SpanStatus? { get set }
3231

33-
/// The precise `DispatchTime` of when the `Span` was started.
34-
var startTimestamp: DispatchTime { get }
32+
/// The `Timestamp` of when the `Span` was started.
33+
var startTimestamp: Timestamp { get }
3534

36-
/// The precise `DispatchTime` of when the `Span` has ended.
37-
var endTimestamp: DispatchTime? { get }
35+
/// The `Timestamp` of when the `Span` has ended.
36+
var endTimestamp: Timestamp? { get }
3837

3938
/// The read-only `BaggageContext` of this `Span`, set when starting this `Span`.
4039
var baggage: BaggageContext { get }
@@ -54,8 +53,8 @@ public protocol Span {
5453
mutating func addLink(_ link: SpanLink)
5554

5655
/// End this `Span` at the given timestamp.
57-
/// - Parameter timestamp: The `DispatchTime` at which the span ended.
58-
mutating func end(at timestamp: DispatchTime)
56+
/// - Parameter timestamp: The `Timestamp` at which the span ended.
57+
mutating func end(at timestamp: Timestamp)
5958
}
6059

6160
extension Span {
@@ -77,23 +76,23 @@ extension Span {
7776
// ==== ----------------------------------------------------------------------------------------------------------------
7877
// MARK: Span Event
7978

80-
/// An event that occured during a `Span`.
79+
/// An event that occurred during a `Span`.
8180
public struct SpanEvent {
8281
/// The human-readable name of this `SpanEvent`.
8382
public let name: String
8483

8584
/// One or more `SpanAttribute`s with the same restrictions as defined for `Span` attributes.
8685
public var attributes: SpanAttributes
8786

88-
/// The `DispatchTime` at which this event occured.
89-
public let timestamp: DispatchTime
87+
/// The `Timestamp` at which this event occurred.
88+
public let timestamp: Timestamp
9089

9190
/// Create a new `SpanEvent`.
9291
/// - Parameters:
9392
/// - name: The human-readable name of this event.
94-
/// - attributes: The `SpanAttributes` describing this event. Defaults to no attributes.
95-
/// - timestamp: The `DispatchTime` at which this event occured. Defaults to `.now()`.
96-
public init(name: String, attributes: SpanAttributes = [:], at timestamp: DispatchTime = .now()) {
93+
/// - attributes: attributes describing this event. Defaults to no attributes.
94+
/// - timestamp: The `Timestamp` at which this event occurred. Defaults to `.now()`.
95+
public init(name: String, attributes: SpanAttributes = [:], at timestamp: Timestamp = .now()) {
9796
self.name = name
9897
self.attributes = attributes
9998
self.timestamp = timestamp
@@ -116,7 +115,7 @@ public enum SpanAttribute {
116115
case double(Double)
117116
case bool(Bool)
118117

119-
// TODO: This could be misused to create a heterogenuous array of attributes, which is not allowed in OT:
118+
// TODO: This could be misused to create a heterogeneous array of attributes, which is not allowed in OT:
120119
// https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#set-attributes
121120

122121
case array([SpanAttribute])
@@ -203,15 +202,15 @@ extension SpanAttributes: ExpressibleByDictionaryLiteral {
203202

204203
/// Represents the status of a finished Span. It's composed of a canonical code in conjunction with an optional descriptive message.
205204
public struct SpanStatus {
206-
public let cannonicalCode: CannonicalCode
205+
public let canonicalCode: CannonicalCode
207206
public let message: String?
208207

209208
/// Create a new `SpanStatus`.
210209
/// - Parameters:
211-
/// - cannonicalCode: The cannonical code of this `SpanStatus`.
210+
/// - canonicalCode: The canonical code of this `SpanStatus`.
212211
/// - message: The optional descriptive message of this `SpanStatus`. Defaults to nil.
213-
public init(cannonicalCode: CannonicalCode, message: String? = nil) {
214-
self.cannonicalCode = cannonicalCode
212+
public init(canonicalCode: CannonicalCode, message: String? = nil) {
213+
self.canonicalCode = canonicalCode
215214
self.message = message
216215
}
217216

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import Dispatch
15+
16+
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
17+
import Darwin
18+
#else
19+
import Glibc
20+
#endif
21+
22+
/// Represents a wall-clock time with microsecond precision.
23+
public struct Timestamp: Comparable, CustomStringConvertible {
24+
private let time: DispatchWallTime
25+
26+
/// Microseconds since Epoch
27+
public var microsSinceEpoch: Int64 {
28+
Int64(bitPattern: self.time.rawValue) / -1000
29+
}
30+
31+
/// Milliseconds since Epoch
32+
public var millisSinceEpoch: Int64 {
33+
Int64(bitPattern: self.time.rawValue) / -1_000_000
34+
}
35+
36+
/// Returns the current time.
37+
public static func now() -> Timestamp {
38+
self.init(time: .now())
39+
}
40+
41+
/// A time in the distant future.
42+
public static let distantFuture: Timestamp = .init(time: .distantFuture)
43+
44+
public init(millisSinceEpoch: Int64) {
45+
let nanoSinceEpoch = UInt64(millisSinceEpoch) * 1_000_000
46+
let seconds = UInt64(nanoSinceEpoch / 1_000_000_000)
47+
let nanoseconds = nanoSinceEpoch - (seconds * 1_000_000_000)
48+
self.init(time: DispatchWallTime(timespec: timespec(tv_sec: Int(seconds), tv_nsec: Int(nanoseconds))))
49+
}
50+
51+
public init(time: DispatchWallTime) {
52+
self.time = time
53+
}
54+
55+
public var description: String {
56+
"Timestamp(\(self.time.rawValue))"
57+
}
58+
59+
public static func < (lhs: Timestamp, rhs: Timestamp) -> Bool {
60+
lhs.time < rhs.time
61+
}
62+
63+
public static func == (lhs: Timestamp, rhs: Timestamp) -> Bool {
64+
lhs.time == rhs.time
65+
}
66+
}

Sources/Instrumentation/Tracing/TracingInstrument.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
import Baggage
15-
import Dispatch
1615

1716
/// An `Instrument` with added functionality for distributed tracing. Is uses the span-based tracing model and is
1817
/// based on the OpenTracing/OpenTelemetry spec.
@@ -27,7 +26,7 @@ public protocol TracingInstrument: Instrument {
2726
named operationName: String,
2827
context: BaggageContext,
2928
ofKind kind: SpanKind,
30-
at timestamp: DispatchTime?
29+
at timestamp: Timestamp?
3130
) -> Span
3231
}
3332

@@ -42,7 +41,7 @@ extension TracingInstrument {
4241
public func startSpan(
4342
named operationName: String,
4443
context: BaggageContext,
45-
at timestamp: DispatchTime? = nil
44+
at timestamp: Timestamp? = nil
4645
) -> Span {
4746
self.startSpan(named: operationName, context: context, ofKind: .internal, at: nil)
4847
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import Instrumentation
15+
import XCTest
16+
17+
final class TimestampTests: XCTestCase {
18+
func test_timestamp_now() {
19+
let timestamp = Timestamp.now()
20+
XCTAssertGreaterThan(timestamp.microsSinceEpoch, 1_595_592_205_693_986)
21+
XCTAssertGreaterThan(timestamp.millisSinceEpoch, 1_595_592_205_693)
22+
}
23+
}

Tests/InstrumentationTests/Tracing/TracedLockTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private final class TracedLockPrintlnTracer: TracingInstrument {
5757
named operationName: String,
5858
context: BaggageContext,
5959
ofKind kind: SpanKind,
60-
at timestamp: DispatchTime?
60+
at timestamp: Timestamp?
6161
) -> Span {
6262
TracedLockPrintlnSpan(
6363
operationName: operationName,
@@ -87,8 +87,8 @@ private final class TracedLockPrintlnTracer: TracingInstrument {
8787
}
8888
}
8989

90-
let startTimestamp: DispatchTime
91-
private(set) var endTimestamp: DispatchTime?
90+
let startTimestamp: Timestamp
91+
private(set) var endTimestamp: Timestamp?
9292

9393
let baggage: BaggageContext
9494

@@ -110,7 +110,7 @@ private final class TracedLockPrintlnTracer: TracingInstrument {
110110

111111
init(
112112
operationName: String,
113-
startTimestamp: DispatchTime,
113+
startTimestamp: Timestamp,
114114
kind: SpanKind,
115115
context baggage: BaggageContext
116116
) {
@@ -130,9 +130,9 @@ private final class TracedLockPrintlnTracer: TracingInstrument {
130130
self.events.append(event)
131131
}
132132

133-
mutating func end(at timestamp: DispatchTime) {
133+
mutating func end(at timestamp: Timestamp) {
134134
self.endTimestamp = timestamp
135-
print(" span [\(self.operationName): \(self.baggage[TaskIDKey.self] ?? "no-name")] @ \(timestamp): end (took \(timestamp.uptimeNanoseconds - self.startTimestamp.uptimeNanoseconds) nanos)")
135+
print(" span [\(self.operationName): \(self.baggage[TaskIDKey.self] ?? "no-name")] @ \(timestamp): end")
136136
}
137137
}
138138
}

Tests/InstrumentationTests/TracingInstrumentTests.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
import Baggage
1515
import BaggageLogging
16-
import Dispatch
1716
import Instrumentation
1817
import XCTest
1918

@@ -36,7 +35,7 @@ final class JaegerTracer: TracingInstrument {
3635
named operationName: String,
3736
context: BaggageContext,
3837
ofKind kind: SpanKind,
39-
at timestamp: DispatchTime?
38+
at timestamp: Timestamp?
4039
) -> Span {
4140
let span = OTSpan(
4241
operationName: operationName,
@@ -101,8 +100,8 @@ struct OTSpan: Span {
101100
}
102101
}
103102

104-
let startTimestamp: DispatchTime
105-
private(set) var endTimestamp: DispatchTime?
103+
let startTimestamp: Timestamp
104+
private(set) var endTimestamp: Timestamp?
106105

107106
let baggage: BaggageContext
108107

@@ -126,7 +125,7 @@ struct OTSpan: Span {
126125

127126
init(
128127
operationName: String,
129-
startTimestamp: DispatchTime,
128+
startTimestamp: Timestamp,
130129
context baggage: BaggageContext,
131130
kind: SpanKind,
132131
onEnd: @escaping (Span) -> Void
@@ -146,7 +145,7 @@ struct OTSpan: Span {
146145
self.events.append(event)
147146
}
148147

149-
mutating func end(at timestamp: DispatchTime) {
148+
mutating func end(at timestamp: Timestamp) {
150149
self.endTimestamp = timestamp
151150
self.onEnd(self)
152151
}

scripts/validate_license_headers.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ EOF
109109
(
110110
cd "$here/.."
111111
find . \
112-
\( \! -path './.build/*' -a \
112+
\( \! -path './UseCases/.build/*' -a \
113+
\( \! -path './.build/*' \) -a \
113114
\( "${matching_files[@]}" \) -a \
114115
\( \! \( "${exceptions[@]}" \) \) \) | while read line; do
115116
if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then

0 commit comments

Comments
 (0)