diff --git a/Package.resolved b/Package.resolved index d9283e1c..61e3c84d 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/grpc/grpc-swift.git", "state": { "branch": null, - "revision": "b83ee1ee2caa0660eb02444977b9b6e353c2adbf", - "version": "1.0.0-alpha.12" + "revision": "9e464a75079928366aa7041769a271fac89271bf", + "version": "1.0.0" } }, { @@ -33,8 +33,8 @@ "repositoryURL": "https://github.com/apple/swift-log.git", "state": { "branch": null, - "revision": "74d7b91ceebc85daf387ebb206003f78813f71aa", - "version": "1.2.0" + "revision": "12d3a8651d32295794a850307f77407f95b8c881", + "version": "1.4.1" } }, { @@ -42,8 +42,17 @@ "repositoryURL": "https://github.com/apple/swift-nio.git", "state": { "branch": null, - "revision": "120acb15c39aa3217e9888e515de160378fbcc1e", - "version": "2.18.0" + "revision": "6d3ca7e54e06a69d0f2612c2ce8bb8b7319085a4", + "version": "2.26.0" + } + }, + { + "package": "swift-nio-extras", + "repositoryURL": "https://github.com/apple/swift-nio-extras.git", + "state": { + "branch": null, + "revision": "de1c80ad1fdff1ba772bcef6b392c3ef735f39a6", + "version": "1.8.0" } }, { @@ -51,8 +60,8 @@ "repositoryURL": "https://github.com/apple/swift-nio-http2.git", "state": { "branch": null, - "revision": "c5d10f4165128c3d0cc0e3c0f0a8ef55947a73a6", - "version": "1.12.2" + "revision": "f4736a3b78a2bbe3feb7fc0f33f6683a8c27974c", + "version": "1.16.3" } }, { @@ -60,8 +69,8 @@ "repositoryURL": "https://github.com/apple/swift-nio-ssl.git", "state": { "branch": null, - "revision": "f0b118d9af6c4e78bc4f3f4fbb464020172b0bf4", - "version": "2.7.5" + "revision": "bbb38fbcbbe9dc4665b2c638dfa5681b01079bfb", + "version": "2.10.4" } }, { @@ -69,8 +78,8 @@ "repositoryURL": "https://github.com/apple/swift-nio-transport-services.git", "state": { "branch": null, - "revision": "2ac8fde712c1b1a147ecb7065824a40d2c09d0cb", - "version": "1.6.0" + "revision": "1d28d48e071727f4558a8a4bb1894472abc47a58", + "version": "1.9.2" } }, { @@ -78,8 +87,8 @@ "repositoryURL": "https://github.com/apple/swift-protobuf.git", "state": { "branch": null, - "revision": "7f36441e3372665b1b414f8ac93b5905cc42a405", - "version": "1.9.0" + "revision": "e1904bf5a5f79cb7e0ff68a427a53a93b652fcd1", + "version": "1.15.0" } }, { diff --git a/Package.swift b/Package.swift index d6fa4934..ad7e82d2 100644 --- a/Package.swift +++ b/Package.swift @@ -37,8 +37,7 @@ let package = Package( .package(name: "Opentracing", url: "https://github.com/undefinedlabs/opentracing-objc", from: "0.5.2"), .package(name: "Thrift", url: "https://github.com/undefinedlabs/Thrift-Swift", from: "1.1.1"), .package(name: "swift-nio", url: "https://github.com/apple/swift-nio.git", from: "2.0.0"), - .package(name: "grpc-swift", url: "https://github.com/grpc/grpc-swift.git", .exact("1.0.0-alpha.12")), - .package(name: "SwiftProtobuf", url: "https://github.com/apple/swift-protobuf.git", from: "1.6.0"), + .package(name: "grpc-swift", url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"), .package(name: "swift-atomics", url: "https://github.com/apple/swift-atomics.git", from: "0.0.1") ], targets: [ diff --git a/Sources/Exporters/DatadogExporter/Spans/SpanEncoder.swift b/Sources/Exporters/DatadogExporter/Spans/SpanEncoder.swift index 0c836763..bfc9a5ad 100644 --- a/Sources/Exporters/DatadogExporter/Spans/SpanEncoder.swift +++ b/Sources/Exporters/DatadogExporter/Spans/SpanEncoder.swift @@ -17,7 +17,7 @@ import Foundation import OpenTelemetryApi import OpenTelemetrySdk -internal struct Constants { +internal enum Constants { static let ddsource = "ios" } @@ -91,16 +91,17 @@ internal struct DDSpan: Encodable { self.startTime = spanData.startTime.timeIntervalSince1970.toNanoseconds self.duration = spanData.endTime.timeIntervalSince(spanData.startTime).toNanoseconds - if spanData.status.isError { - self.error = true - self.errorType = spanData.attributes["error.type"]?.description ?? spanData.status.description - self.errorMessage = spanData.attributes["error.message"]?.description - self.errorStack = spanData.attributes["error.stack"]?.description - } else { - self.error = false - self.errorMessage = nil - self.errorType = nil - self.errorStack = nil + switch spanData.status { + case .error(let errorDescription): + self.error = true + self.errorType = spanData.attributes["error.type"]?.description ?? errorDescription + self.errorMessage = spanData.attributes["error.message"]?.description + self.errorStack = spanData.attributes["error.stack"]?.description + default: + self.error = false + self.errorMessage = nil + self.errorType = nil + self.errorStack = nil } let spanType = spanData.attributes["type"] ?? spanData.attributes["db.type"] diff --git a/Sources/Exporters/Jaeger/Adapter.swift b/Sources/Exporters/Jaeger/Adapter.swift index ce5cd8dc..34906fc8 100644 --- a/Sources/Exporters/Jaeger/Adapter.swift +++ b/Sources/Exporters/Jaeger/Adapter.swift @@ -60,8 +60,7 @@ final class Adapter { logs.append(contentsOf: toJaegerLogs(events: span.events)) references.append(contentsOf: toSpanRefs(links: span.links)) - if let parentId = span.parentSpanId, - parentId.isValid { + if let parentId = span.parentSpanId, parentId.isValid { let parentTraceIdHigh = traceIdHigh let parentTraceIdLow = traceIdLow @@ -75,8 +74,12 @@ final class Adapter { } tags.append(Tag(key: Adapter.keySpanKind, vType: .string, vStr: span.kind.rawValue.uppercased(), vDouble: nil, vBool: nil, vLong: nil, vBinary: nil)) - tags.append(Tag(key: Adapter.keySpanStatusMessage, vType: .string, vStr: span.status.statusDescription ?? "", vDouble: nil, vBool: nil, vLong: nil, vBinary: nil)) - tags.append(Tag(key: Adapter.keySpanStatusCode, vType: .long, vStr: nil, vDouble: nil, vBool: nil, vLong: Int64(span.status.statusCode.rawValue), vBinary: nil)) + if case let Status.error(description) = span.status { + tags.append(Tag(key: Adapter.keySpanStatusMessage, vType: .string, vStr: description, vDouble: nil, vBool: nil, vLong: nil, vBinary: nil)) + } else { + tags.append(Tag(key: Adapter.keySpanStatusMessage, vType: .string, vStr: "", vDouble: nil, vBool: nil, vLong: nil, vBinary: nil)) + } + tags.append(Tag(key: Adapter.keySpanStatusCode, vType: .long, vStr: nil, vDouble: nil, vBool: nil, vLong: Int64(span.status.code), vBinary: nil)) if span.status != .ok { tags.append(Tag(key: keyError, vType: .bool, vStr: nil, vDouble: nil, vBool: true, vLong: nil, vBinary: nil)) diff --git a/Sources/Exporters/OpenTelemetryProtocol/metric/MetricsAdapter.swift b/Sources/Exporters/OpenTelemetryProtocol/metric/MetricsAdapter.swift index da767861..5aea6940 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/metric/MetricsAdapter.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/metric/MetricsAdapter.swift @@ -16,7 +16,6 @@ import Foundation import OpenTelemetryApi import OpenTelemetrySdk - struct MetricsAdapter { static func toProtoResourceMetrics(metricDataList: [Metric]) -> [Opentelemetry_Proto_Metrics_V1_ResourceMetrics] { let resourceAndLibraryMap = groupByResouceAndLibrary(metricDataList: metricDataList) @@ -26,7 +25,7 @@ struct MetricsAdapter { var instrumentationLibraryMetrics = [Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics]() resMap.value.forEach { instLibrary in var protoInst = - Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics() + Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics() protoInst.instrumentationLibrary = CommonAdapter.toProtoInstrumentationLibrary(instrumentationLibraryInfo: instLibrary.key) instLibrary.value.forEach { @@ -38,19 +37,16 @@ struct MetricsAdapter { resourceMetric.resource = ResourceAdapter.toProtoResource(resource: resMap.key) resourceMetric.instrumentationLibraryMetrics.append(contentsOf: instrumentationLibraryMetrics) resourceMetrics.append(resourceMetric) - } - - return resourceMetrics } - private static func groupByResouceAndLibrary(metricDataList: [Metric]) -> [Resource :[InstrumentationLibraryInfo : [Opentelemetry_Proto_Metrics_V1_Metric]]] { - var results = [Resource : [InstrumentationLibraryInfo : [Opentelemetry_Proto_Metrics_V1_Metric]]]() + private static func groupByResouceAndLibrary(metricDataList: [Metric]) -> [Resource: [InstrumentationLibraryInfo: [Opentelemetry_Proto_Metrics_V1_Metric]]] { + var results = [Resource: [InstrumentationLibraryInfo: [Opentelemetry_Proto_Metrics_V1_Metric]]]() metricDataList.forEach { - results[$0.resource, default:[InstrumentationLibraryInfo : [Opentelemetry_Proto_Metrics_V1_Metric]]()][$0.instrumentationLibraryInfo,default:[Opentelemetry_Proto_Metrics_V1_Metric]()] + results[$0.resource, default: [InstrumentationLibraryInfo: [Opentelemetry_Proto_Metrics_V1_Metric]]()][$0.instrumentationLibraryInfo, default: [Opentelemetry_Proto_Metrics_V1_Metric]()] .append(toProtoMetric(metric: $0)) } @@ -58,92 +54,84 @@ struct MetricsAdapter { } static func toProtoMetric(metric: Metric) -> Opentelemetry_Proto_Metrics_V1_Metric { - var protoMetric = Opentelemetry_Proto_Metrics_V1_Metric() protoMetric.name = metric.name protoMetric.description_p = metric.description - metric.data.forEach { - switch metric.aggregationType { - case .doubleSum: - guard let sumData = $0 as? SumData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_DoubleDataPoint() - protoDataPoint.value = sumData.sum - sumData.labels.forEach { - var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() - kvp.key = $0.key - kvp.value = $0.value - protoDataPoint.labels.append(kvp) - } + switch metric.aggregationType { + case .doubleSum: + guard let sumData = $0 as? SumData else { + break + } + var protoDataPoint = Opentelemetry_Proto_Metrics_V1_DoubleDataPoint() + protoDataPoint.value = sumData.sum + sumData.labels.forEach { + var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() + kvp.key = $0.key + kvp.value = $0.value + protoDataPoint.labels.append(kvp) + } - protoMetric.doubleSum.dataPoints.append(protoDataPoint) - break - case .doubleSummary: + protoMetric.doubleSum.dataPoints.append(protoDataPoint) + case .doubleSummary: - guard let summaryData = $0 as? SummaryData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_DoubleHistogramDataPoint() - protoDataPoint.sum = summaryData.sum - protoDataPoint.count = UInt64(summaryData.count) - protoDataPoint.explicitBounds = [summaryData.min, summaryData.max] + guard let summaryData = $0 as? SummaryData else { + break + } + var protoDataPoint = Opentelemetry_Proto_Metrics_V1_DoubleHistogramDataPoint() + protoDataPoint.sum = summaryData.sum + protoDataPoint.count = UInt64(summaryData.count) + protoDataPoint.explicitBounds = [summaryData.min, summaryData.max] - protoDataPoint.startTimeUnixNano = summaryData.startTimestamp.timeIntervalSince1970.toNanoseconds - protoDataPoint.timeUnixNano = summaryData.timestamp.timeIntervalSince1970.toNanoseconds + protoDataPoint.startTimeUnixNano = summaryData.startTimestamp.timeIntervalSince1970.toNanoseconds + protoDataPoint.timeUnixNano = summaryData.timestamp.timeIntervalSince1970.toNanoseconds - summaryData.labels.forEach { - var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() - kvp.key = $0.key - kvp.value = $0.value - protoDataPoint.labels.append(kvp) - } + summaryData.labels.forEach { + var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() + kvp.key = $0.key + kvp.value = $0.value + protoDataPoint.labels.append(kvp) + } - protoMetric.doubleHistogram.dataPoints.append(protoDataPoint) + protoMetric.doubleHistogram.dataPoints.append(protoDataPoint) - break - case .intSum: - guard let sumData = $0 as? SumData else { - break; - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_IntDataPoint() - protoDataPoint.value = Int64(sumData.sum) - sumData.labels.forEach { - var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() - kvp.key = $0.key - kvp.value = $0.value - protoDataPoint.labels.append(kvp) - } + case .intSum: + guard let sumData = $0 as? SumData else { + break + } + var protoDataPoint = Opentelemetry_Proto_Metrics_V1_IntDataPoint() + protoDataPoint.value = Int64(sumData.sum) + sumData.labels.forEach { + var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() + kvp.key = $0.key + kvp.value = $0.value + protoDataPoint.labels.append(kvp) + } - protoMetric.intSum.dataPoints.append(protoDataPoint) + protoMetric.intSum.dataPoints.append(protoDataPoint) - break - case .intSummary: - guard let summaryData = $0 as? SummaryData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_IntHistogramDataPoint() - protoDataPoint.sum = Int64(summaryData.sum) - protoDataPoint.count = UInt64(summaryData.count) - protoDataPoint.bucketCounts = [UInt64(summaryData.min), UInt64(summaryData.max)] - protoDataPoint.startTimeUnixNano = summaryData.startTimestamp.timeIntervalSince1970.toNanoseconds - protoDataPoint.timeUnixNano = summaryData.timestamp.timeIntervalSince1970.toNanoseconds + case .intSummary: + guard let summaryData = $0 as? SummaryData else { + break + } + var protoDataPoint = Opentelemetry_Proto_Metrics_V1_IntHistogramDataPoint() + protoDataPoint.sum = Int64(summaryData.sum) + protoDataPoint.count = UInt64(summaryData.count) + protoDataPoint.bucketCounts = [UInt64(summaryData.min), UInt64(summaryData.max)] + protoDataPoint.startTimeUnixNano = summaryData.startTimestamp.timeIntervalSince1970.toNanoseconds + protoDataPoint.timeUnixNano = summaryData.timestamp.timeIntervalSince1970.toNanoseconds - summaryData.labels.forEach { - var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() - kvp.key = $0.key - kvp.value = $0.value - protoDataPoint.labels.append(kvp) - } - - protoMetric.intHistogram.dataPoints.append(protoDataPoint) + summaryData.labels.forEach { + var kvp = Opentelemetry_Proto_Common_V1_StringKeyValue() + kvp.key = $0.key + kvp.value = $0.value + protoDataPoint.labels.append(kvp) + } - break + protoMetric.intHistogram.dataPoints.append(protoDataPoint) } } return protoMetric } - } diff --git a/Sources/Exporters/OpenTelemetryProtocol/metric/OtelpMetricExporter.swift b/Sources/Exporters/OpenTelemetryProtocol/metric/OtelpMetricExporter.swift index c5807bb7..34fffc06 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/metric/OtelpMetricExporter.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/metric/OtelpMetricExporter.swift @@ -15,35 +15,33 @@ import Foundation import GRPC +import NIO import OpenTelemetryApi import OpenTelemetrySdk -public class OtelpMetricExporter : MetricExporter { - - let channel : GRPCChannel +public class OtelpMetricExporter: MetricExporter { + let channel: GRPCChannel let metricClient: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient - let deadlineMS : Int - - public init(channel: GRPCChannel, timeoutMS: Int = 0) { + let timeoutNanos: Int64 + + public init(channel: GRPCChannel, timeoutNanos: Int64 = 0) { self.channel = channel - self.deadlineMS = timeoutMS + self.timeoutNanos = timeoutNanos self.metricClient = Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient(channel: self.channel) } - public func export(metrics: [Metric], shouldCancel: (() -> Bool)?) -> MetricExporterResultCode { let exportRequest = Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest .with { $0.resourceMetrics = MetricsAdapter.toProtoResourceMetrics(metricDataList: metrics) } - if deadlineMS > 0 { - metricClient.defaultCallOptions.timeout = try! GRPCTimeout.milliseconds(deadlineMS) + if timeoutNanos > 0 { + metricClient.defaultCallOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(timeoutNanos)) } let export = metricClient.export(exportRequest) - do { _ = try export.response.wait() return .success @@ -57,8 +55,6 @@ public class OtelpMetricExporter : MetricExporter { } public func shutdown() { - _ = channel.close() + _ = channel.close() } - - } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/common.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/common.pb.swift index 7e64cba3..8c45cfb6 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/common.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/common.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/common/v1/common.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -43,57 +44,54 @@ public struct Opentelemetry_Proto_Common_V1_AnyValue { /// The value is one of the listed fields. It is valid for all values to be unspecified /// in which case this AnyValue is considered to be "null". - public var value: OneOf_Value? { - get {return _storage._value} - set {_uniqueStorage()._value = newValue} - } + public var value: Opentelemetry_Proto_Common_V1_AnyValue.OneOf_Value? = nil public var stringValue: String { get { - if case .stringValue(let v)? = _storage._value {return v} + if case .stringValue(let v)? = value {return v} return String() } - set {_uniqueStorage()._value = .stringValue(newValue)} + set {value = .stringValue(newValue)} } public var boolValue: Bool { get { - if case .boolValue(let v)? = _storage._value {return v} + if case .boolValue(let v)? = value {return v} return false } - set {_uniqueStorage()._value = .boolValue(newValue)} + set {value = .boolValue(newValue)} } public var intValue: Int64 { get { - if case .intValue(let v)? = _storage._value {return v} + if case .intValue(let v)? = value {return v} return 0 } - set {_uniqueStorage()._value = .intValue(newValue)} + set {value = .intValue(newValue)} } public var doubleValue: Double { get { - if case .doubleValue(let v)? = _storage._value {return v} + if case .doubleValue(let v)? = value {return v} return 0 } - set {_uniqueStorage()._value = .doubleValue(newValue)} + set {value = .doubleValue(newValue)} } public var arrayValue: Opentelemetry_Proto_Common_V1_ArrayValue { get { - if case .arrayValue(let v)? = _storage._value {return v} + if case .arrayValue(let v)? = value {return v} return Opentelemetry_Proto_Common_V1_ArrayValue() } - set {_uniqueStorage()._value = .arrayValue(newValue)} + set {value = .arrayValue(newValue)} } public var kvlistValue: Opentelemetry_Proto_Common_V1_KeyValueList { get { - if case .kvlistValue(let v)? = _storage._value {return v} + if case .kvlistValue(let v)? = value {return v} return Opentelemetry_Proto_Common_V1_KeyValueList() } - set {_uniqueStorage()._value = .kvlistValue(newValue)} + set {value = .kvlistValue(newValue)} } public var unknownFields = SwiftProtobuf.UnknownStorage() @@ -110,13 +108,34 @@ public struct Opentelemetry_Proto_Common_V1_AnyValue { #if !swift(>=4.1) public static func ==(lhs: Opentelemetry_Proto_Common_V1_AnyValue.OneOf_Value, rhs: Opentelemetry_Proto_Common_V1_AnyValue.OneOf_Value) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch (lhs, rhs) { - case (.stringValue(let l), .stringValue(let r)): return l == r - case (.boolValue(let l), .boolValue(let r)): return l == r - case (.intValue(let l), .intValue(let r)): return l == r - case (.doubleValue(let l), .doubleValue(let r)): return l == r - case (.arrayValue(let l), .arrayValue(let r)): return l == r - case (.kvlistValue(let l), .kvlistValue(let r)): return l == r + case (.stringValue, .stringValue): return { + guard case .stringValue(let l) = lhs, case .stringValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.boolValue, .boolValue): return { + guard case .boolValue(let l) = lhs, case .boolValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.intValue, .intValue): return { + guard case .intValue(let l) = lhs, case .intValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.doubleValue, .doubleValue): return { + guard case .doubleValue(let l) = lhs, case .doubleValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.arrayValue, .arrayValue): return { + guard case .arrayValue(let l) = lhs, case .arrayValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.kvlistValue, .kvlistValue): return { + guard case .kvlistValue(let l) = lhs, case .kvlistValue(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -124,8 +143,6 @@ public struct Opentelemetry_Proto_Common_V1_AnyValue { } public init() {} - - fileprivate var _storage = _StorageClass.defaultInstance } /// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message @@ -169,25 +186,22 @@ public struct Opentelemetry_Proto_Common_V1_KeyValue { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - public var key: String { - get {return _storage._key} - set {_uniqueStorage()._key = newValue} - } + public var key: String = String() public var value: Opentelemetry_Proto_Common_V1_AnyValue { - get {return _storage._value ?? Opentelemetry_Proto_Common_V1_AnyValue()} - set {_uniqueStorage()._value = newValue} + get {return _value ?? Opentelemetry_Proto_Common_V1_AnyValue()} + set {_value = newValue} } /// Returns true if `value` has been explicitly set. - public var hasValue: Bool {return _storage._value != nil} + public var hasValue: Bool {return self._value != nil} /// Clears the value of `value`. Subsequent reads from it will return its default value. - public mutating func clearValue() {_uniqueStorage()._value = nil} + public mutating func clearValue() {self._value = nil} public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _value: Opentelemetry_Proto_Common_V1_AnyValue? = nil } /// StringKeyValue is a pair of key/value strings. This is the simpler (and faster) version @@ -213,6 +227,7 @@ public struct Opentelemetry_Proto_Common_V1_InstrumentationLibrary { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// An empty instrumentation library name means the name is unknown. public var name: String = String() public var version: String = String() @@ -237,103 +252,95 @@ extension Opentelemetry_Proto_Common_V1_AnyValue: SwiftProtobuf.Message, SwiftPr 6: .standard(proto: "kvlist_value"), ] - fileprivate class _StorageClass { - var _value: Opentelemetry_Proto_Common_V1_AnyValue.OneOf_Value? - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _value = source._value - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: - if _storage._value != nil {try decoder.handleConflictingOneOf()} - var v: String? - try decoder.decodeSingularStringField(value: &v) - if let v = v {_storage._value = .stringValue(v)} - case 2: - if _storage._value != nil {try decoder.handleConflictingOneOf()} - var v: Bool? - try decoder.decodeSingularBoolField(value: &v) - if let v = v {_storage._value = .boolValue(v)} - case 3: - if _storage._value != nil {try decoder.handleConflictingOneOf()} - var v: Int64? - try decoder.decodeSingularInt64Field(value: &v) - if let v = v {_storage._value = .intValue(v)} - case 4: - if _storage._value != nil {try decoder.handleConflictingOneOf()} - var v: Double? - try decoder.decodeSingularDoubleField(value: &v) - if let v = v {_storage._value = .doubleValue(v)} - case 5: - var v: Opentelemetry_Proto_Common_V1_ArrayValue? - if let current = _storage._value { - try decoder.handleConflictingOneOf() - if case .arrayValue(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._value = .arrayValue(v)} - case 6: - var v: Opentelemetry_Proto_Common_V1_KeyValueList? - if let current = _storage._value { - try decoder.handleConflictingOneOf() - if case .kvlistValue(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._value = .kvlistValue(v)} - default: break + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { + if self.value != nil {try decoder.handleConflictingOneOf()} + var v: String? + try decoder.decodeSingularStringField(value: &v) + if let v = v {self.value = .stringValue(v)} + }() + case 2: try { + if self.value != nil {try decoder.handleConflictingOneOf()} + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v {self.value = .boolValue(v)} + }() + case 3: try { + if self.value != nil {try decoder.handleConflictingOneOf()} + var v: Int64? + try decoder.decodeSingularInt64Field(value: &v) + if let v = v {self.value = .intValue(v)} + }() + case 4: try { + if self.value != nil {try decoder.handleConflictingOneOf()} + var v: Double? + try decoder.decodeSingularDoubleField(value: &v) + if let v = v {self.value = .doubleValue(v)} + }() + case 5: try { + var v: Opentelemetry_Proto_Common_V1_ArrayValue? + if let current = self.value { + try decoder.handleConflictingOneOf() + if case .arrayValue(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.value = .arrayValue(v)} + }() + case 6: try { + var v: Opentelemetry_Proto_Common_V1_KeyValueList? + if let current = self.value { + try decoder.handleConflictingOneOf() + if case .kvlistValue(let m) = current {v = m} } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.value = .kvlistValue(v)} + }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - switch _storage._value { - case .stringValue(let v)?: - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - case .boolValue(let v)?: - try visitor.visitSingularBoolField(value: v, fieldNumber: 2) - case .intValue(let v)?: - try visitor.visitSingularInt64Field(value: v, fieldNumber: 3) - case .doubleValue(let v)?: - try visitor.visitSingularDoubleField(value: v, fieldNumber: 4) - case .arrayValue(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - case .kvlistValue(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 6) - case nil: break - } + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch self.value { + case .stringValue?: try { + guard case .stringValue(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + }() + case .boolValue?: try { + guard case .boolValue(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + }() + case .intValue?: try { + guard case .intValue(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularInt64Field(value: v, fieldNumber: 3) + }() + case .doubleValue?: try { + guard case .doubleValue(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularDoubleField(value: v, fieldNumber: 4) + }() + case .arrayValue?: try { + guard case .arrayValue(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .kvlistValue?: try { + guard case .kvlistValue(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case nil: break } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Common_V1_AnyValue, rhs: Opentelemetry_Proto_Common_V1_AnyValue) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._value != rhs_storage._value {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.value != rhs.value {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -347,8 +354,11 @@ extension Opentelemetry_Proto_Common_V1_ArrayValue: SwiftProtobuf.Message, Swift public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.values) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.values) }() default: break } } @@ -376,8 +386,11 @@ extension Opentelemetry_Proto_Common_V1_KeyValueList: SwiftProtobuf.Message, Swi public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.values) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.values) }() default: break } } @@ -404,63 +417,32 @@ extension Opentelemetry_Proto_Common_V1_KeyValue: SwiftProtobuf.Message, SwiftPr 2: .same(proto: "value"), ] - fileprivate class _StorageClass { - var _key: String = String() - var _value: Opentelemetry_Proto_Common_V1_AnyValue? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _key = source._key - _value = source._value - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularStringField(value: &_storage._key) - case 2: try decoder.decodeSingularMessageField(value: &_storage._value) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.key) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._value) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if !_storage._key.isEmpty { - try visitor.visitSingularStringField(value: _storage._key, fieldNumber: 1) - } - if let v = _storage._value { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } + if !self.key.isEmpty { + try visitor.visitSingularStringField(value: self.key, fieldNumber: 1) + } + if let v = self._value { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Common_V1_KeyValue, rhs: Opentelemetry_Proto_Common_V1_KeyValue) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._key != rhs_storage._key {return false} - if _storage._value != rhs_storage._value {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.key != rhs.key {return false} + if lhs._value != rhs._value {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -475,9 +457,12 @@ extension Opentelemetry_Proto_Common_V1_StringKeyValue: SwiftProtobuf.Message, S public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularStringField(value: &self.key) - case 2: try decoder.decodeSingularStringField(value: &self.value) + case 1: try { try decoder.decodeSingularStringField(value: &self.key) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.value) }() default: break } } @@ -510,9 +495,12 @@ extension Opentelemetry_Proto_Common_V1_InstrumentationLibrary: SwiftProtobuf.Me public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularStringField(value: &self.name) - case 2: try decoder.decodeSingularStringField(value: &self.version) + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.version) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/logs.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/logs.pb.swift index db94d230..8552b943 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/logs.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/logs.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/logs/v1/logs.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -37,7 +38,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP public enum Opentelemetry_Proto_Logs_V1_SeverityNumber: SwiftProtobuf.Enum { public typealias RawValue = Int - /// UNSPECIFIED is the default SeverityNumber, it MUST not be used. + /// UNSPECIFIED is the default SeverityNumber, it MUST NOT be used. case unspecified // = 0 case trace // = 1 case trace2 // = 2 @@ -216,27 +217,24 @@ public struct Opentelemetry_Proto_Logs_V1_ResourceLogs { // methods supported on all messages. /// The resource for the logs in this message. - /// If this field is not set then no resource info is known. + /// If this field is not set then resource info is unknown. public var resource: Opentelemetry_Proto_Resource_V1_Resource { - get {return _storage._resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_uniqueStorage()._resource = newValue} + get {return _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} + set {_resource = newValue} } /// Returns true if `resource` has been explicitly set. - public var hasResource: Bool {return _storage._resource != nil} + public var hasResource: Bool {return self._resource != nil} /// Clears the value of `resource`. Subsequent reads from it will return its default value. - public mutating func clearResource() {_uniqueStorage()._resource = nil} + public mutating func clearResource() {self._resource = nil} /// A list of InstrumentationLibraryLogs that originate from a resource. - public var instrumentationLibraryLogs: [Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs] { - get {return _storage._instrumentationLibraryLogs} - set {_uniqueStorage()._instrumentationLibraryLogs = newValue} - } + public var instrumentationLibraryLogs: [Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs] = [] public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil } /// A collection of Logs produced by an InstrumentationLibrary. @@ -246,27 +244,25 @@ public struct Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs { // methods supported on all messages. /// The instrumentation library information for the logs in this message. - /// If this field is not set then no library info is known. + /// Semantically when InstrumentationLibrary isn't set, it is equivalent with + /// an empty instrumentation library name (unknown). public var instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary { - get {return _storage._instrumentationLibrary ?? Opentelemetry_Proto_Common_V1_InstrumentationLibrary()} - set {_uniqueStorage()._instrumentationLibrary = newValue} + get {return _instrumentationLibrary ?? Opentelemetry_Proto_Common_V1_InstrumentationLibrary()} + set {_instrumentationLibrary = newValue} } /// Returns true if `instrumentationLibrary` has been explicitly set. - public var hasInstrumentationLibrary: Bool {return _storage._instrumentationLibrary != nil} + public var hasInstrumentationLibrary: Bool {return self._instrumentationLibrary != nil} /// Clears the value of `instrumentationLibrary`. Subsequent reads from it will return its default value. - public mutating func clearInstrumentationLibrary() {_uniqueStorage()._instrumentationLibrary = nil} + public mutating func clearInstrumentationLibrary() {self._instrumentationLibrary = nil} /// A list of log records. - public var logs: [Opentelemetry_Proto_Logs_V1_LogRecord] { - get {return _storage._logs} - set {_uniqueStorage()._logs = newValue} - } + public var logs: [Opentelemetry_Proto_Logs_V1_LogRecord] = [] public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary? = nil } /// A log record according to OpenTelemetry Log Data Model: @@ -279,89 +275,62 @@ public struct Opentelemetry_Proto_Logs_V1_LogRecord { /// time_unix_nano is the time when the event occurred. /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. /// Value of 0 indicates unknown or missing timestamp. - public var timeUnixNano: UInt64 { - get {return _storage._timeUnixNano} - set {_uniqueStorage()._timeUnixNano = newValue} - } + public var timeUnixNano: UInt64 = 0 /// Numerical value of the severity, normalized to values described in Log Data Model. /// [Optional]. - public var severityNumber: Opentelemetry_Proto_Logs_V1_SeverityNumber { - get {return _storage._severityNumber} - set {_uniqueStorage()._severityNumber = newValue} - } + public var severityNumber: Opentelemetry_Proto_Logs_V1_SeverityNumber = .unspecified /// The severity text (also known as log level). The original string representation as /// it is known at the source. [Optional]. - public var severityText: String { - get {return _storage._severityText} - set {_uniqueStorage()._severityText = newValue} - } + public var severityText: String = String() /// Short event identifier that does not contain varying parts. Name describes /// what happened (e.g. "ProcessStarted"). Recommended to be no longer than 50 /// characters. Not guaranteed to be unique in any way. [Optional]. - public var name: String { - get {return _storage._name} - set {_uniqueStorage()._name = newValue} - } + public var name: String = String() /// A value containing the body of the log record. Can be for example a human-readable /// string message (including multi-line) describing the event in a free form or it can /// be a structured data composed of arrays and maps of other values. [Optional]. public var body: Opentelemetry_Proto_Common_V1_AnyValue { - get {return _storage._body ?? Opentelemetry_Proto_Common_V1_AnyValue()} - set {_uniqueStorage()._body = newValue} + get {return _body ?? Opentelemetry_Proto_Common_V1_AnyValue()} + set {_body = newValue} } /// Returns true if `body` has been explicitly set. - public var hasBody: Bool {return _storage._body != nil} + public var hasBody: Bool {return self._body != nil} /// Clears the value of `body`. Subsequent reads from it will return its default value. - public mutating func clearBody() {_uniqueStorage()._body = nil} + public mutating func clearBody() {self._body = nil} /// Additional attributes that describe the specific event occurrence. [Optional]. - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] { - get {return _storage._attributes} - set {_uniqueStorage()._attributes = newValue} - } + public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - public var droppedAttributesCount: UInt32 { - get {return _storage._droppedAttributesCount} - set {_uniqueStorage()._droppedAttributesCount = newValue} - } + public var droppedAttributesCount: UInt32 = 0 /// Flags, a bit field. 8 least significant bits are the trace flags as /// defined in W3C Trace Context specification. 24 most significant bits are reserved /// and must be set to 0. Readers must not assume that 24 most significant bits /// will be zero and must correctly mask the bits when reading 8-bit trace flag (use /// flags & TRACE_FLAGS_MASK). [Optional]. - public var flags: UInt32 { - get {return _storage._flags} - set {_uniqueStorage()._flags = newValue} - } + public var flags: UInt32 = 0 /// A unique identifier for a trace. All logs from the same trace share /// the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes /// is considered invalid. Can be set for logs that are part of request processing /// and have an assigned trace id. [Optional]. - public var traceID: Data { - get {return _storage._traceID} - set {_uniqueStorage()._traceID = newValue} - } + public var traceID: Data = Data() /// A unique identifier for a span within a trace, assigned when the span /// is created. The ID is an 8-byte array. An ID with all zeroes is considered /// invalid. Can be set for logs that are part of a particular processing span. /// If span_id is present trace_id SHOULD be also present. [Optional]. - public var spanID: Data { - get {return _storage._spanID} - set {_uniqueStorage()._spanID = newValue} - } + public var spanID: Data = Data() public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _body: Opentelemetry_Proto_Common_V1_AnyValue? = nil } // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -412,63 +381,32 @@ extension Opentelemetry_Proto_Logs_V1_ResourceLogs: SwiftProtobuf.Message, Swift 2: .standard(proto: "instrumentation_library_logs"), ] - fileprivate class _StorageClass { - var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil - var _instrumentationLibraryLogs: [Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs] = [] - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _resource = source._resource - _instrumentationLibraryLogs = source._instrumentationLibraryLogs - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularMessageField(value: &_storage._resource) - case 2: try decoder.decodeRepeatedMessageField(value: &_storage._instrumentationLibraryLogs) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._resource) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.instrumentationLibraryLogs) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if !_storage._instrumentationLibraryLogs.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._instrumentationLibraryLogs, fieldNumber: 2) - } + if let v = self._resource { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.instrumentationLibraryLogs.isEmpty { + try visitor.visitRepeatedMessageField(value: self.instrumentationLibraryLogs, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Logs_V1_ResourceLogs, rhs: Opentelemetry_Proto_Logs_V1_ResourceLogs) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._resource != rhs_storage._resource {return false} - if _storage._instrumentationLibraryLogs != rhs_storage._instrumentationLibraryLogs {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._resource != rhs._resource {return false} + if lhs.instrumentationLibraryLogs != rhs.instrumentationLibraryLogs {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -481,63 +419,32 @@ extension Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs: SwiftProtobuf. 2: .same(proto: "logs"), ] - fileprivate class _StorageClass { - var _instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary? = nil - var _logs: [Opentelemetry_Proto_Logs_V1_LogRecord] = [] - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _instrumentationLibrary = source._instrumentationLibrary - _logs = source._logs - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularMessageField(value: &_storage._instrumentationLibrary) - case 2: try decoder.decodeRepeatedMessageField(value: &_storage._logs) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._instrumentationLibrary) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.logs) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._instrumentationLibrary { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if !_storage._logs.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._logs, fieldNumber: 2) - } + if let v = self._instrumentationLibrary { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.logs.isEmpty { + try visitor.visitRepeatedMessageField(value: self.logs, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs, rhs: Opentelemetry_Proto_Logs_V1_InstrumentationLibraryLogs) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._instrumentationLibrary != rhs_storage._instrumentationLibrary {return false} - if _storage._logs != rhs_storage._logs {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._instrumentationLibrary != rhs._instrumentationLibrary {return false} + if lhs.logs != rhs.logs {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -558,119 +465,72 @@ extension Opentelemetry_Proto_Logs_V1_LogRecord: SwiftProtobuf.Message, SwiftPro 10: .standard(proto: "span_id"), ] - fileprivate class _StorageClass { - var _timeUnixNano: UInt64 = 0 - var _severityNumber: Opentelemetry_Proto_Logs_V1_SeverityNumber = .unspecified - var _severityText: String = String() - var _name: String = String() - var _body: Opentelemetry_Proto_Common_V1_AnyValue? = nil - var _attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - var _droppedAttributesCount: UInt32 = 0 - var _flags: UInt32 = 0 - var _traceID: Data = SwiftProtobuf.Internal.emptyData - var _spanID: Data = SwiftProtobuf.Internal.emptyData - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _timeUnixNano = source._timeUnixNano - _severityNumber = source._severityNumber - _severityText = source._severityText - _name = source._name - _body = source._body - _attributes = source._attributes - _droppedAttributesCount = source._droppedAttributesCount - _flags = source._flags - _traceID = source._traceID - _spanID = source._spanID - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularFixed64Field(value: &_storage._timeUnixNano) - case 2: try decoder.decodeSingularEnumField(value: &_storage._severityNumber) - case 3: try decoder.decodeSingularStringField(value: &_storage._severityText) - case 4: try decoder.decodeSingularStringField(value: &_storage._name) - case 5: try decoder.decodeSingularMessageField(value: &_storage._body) - case 6: try decoder.decodeRepeatedMessageField(value: &_storage._attributes) - case 7: try decoder.decodeSingularUInt32Field(value: &_storage._droppedAttributesCount) - case 8: try decoder.decodeSingularFixed32Field(value: &_storage._flags) - case 9: try decoder.decodeSingularBytesField(value: &_storage._traceID) - case 10: try decoder.decodeSingularBytesField(value: &_storage._spanID) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.severityNumber) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.severityText) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 5: try { try decoder.decodeSingularMessageField(value: &self._body) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() + case 7: try { try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) }() + case 8: try { try decoder.decodeSingularFixed32Field(value: &self.flags) }() + case 9: try { try decoder.decodeSingularBytesField(value: &self.traceID) }() + case 10: try { try decoder.decodeSingularBytesField(value: &self.spanID) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if _storage._timeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: _storage._timeUnixNano, fieldNumber: 1) - } - if _storage._severityNumber != .unspecified { - try visitor.visitSingularEnumField(value: _storage._severityNumber, fieldNumber: 2) - } - if !_storage._severityText.isEmpty { - try visitor.visitSingularStringField(value: _storage._severityText, fieldNumber: 3) - } - if !_storage._name.isEmpty { - try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 4) - } - if let v = _storage._body { - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - } - if !_storage._attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._attributes, fieldNumber: 6) - } - if _storage._droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: _storage._droppedAttributesCount, fieldNumber: 7) - } - if _storage._flags != 0 { - try visitor.visitSingularFixed32Field(value: _storage._flags, fieldNumber: 8) - } - if !_storage._traceID.isEmpty { - try visitor.visitSingularBytesField(value: _storage._traceID, fieldNumber: 9) - } - if !_storage._spanID.isEmpty { - try visitor.visitSingularBytesField(value: _storage._spanID, fieldNumber: 10) - } + if self.timeUnixNano != 0 { + try visitor.visitSingularFixed64Field(value: self.timeUnixNano, fieldNumber: 1) + } + if self.severityNumber != .unspecified { + try visitor.visitSingularEnumField(value: self.severityNumber, fieldNumber: 2) + } + if !self.severityText.isEmpty { + try visitor.visitSingularStringField(value: self.severityText, fieldNumber: 3) + } + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 4) + } + if let v = self._body { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } + if !self.attributes.isEmpty { + try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 6) + } + if self.droppedAttributesCount != 0 { + try visitor.visitSingularUInt32Field(value: self.droppedAttributesCount, fieldNumber: 7) + } + if self.flags != 0 { + try visitor.visitSingularFixed32Field(value: self.flags, fieldNumber: 8) + } + if !self.traceID.isEmpty { + try visitor.visitSingularBytesField(value: self.traceID, fieldNumber: 9) + } + if !self.spanID.isEmpty { + try visitor.visitSingularBytesField(value: self.spanID, fieldNumber: 10) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Logs_V1_LogRecord, rhs: Opentelemetry_Proto_Logs_V1_LogRecord) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._timeUnixNano != rhs_storage._timeUnixNano {return false} - if _storage._severityNumber != rhs_storage._severityNumber {return false} - if _storage._severityText != rhs_storage._severityText {return false} - if _storage._name != rhs_storage._name {return false} - if _storage._body != rhs_storage._body {return false} - if _storage._attributes != rhs_storage._attributes {return false} - if _storage._droppedAttributesCount != rhs_storage._droppedAttributesCount {return false} - if _storage._flags != rhs_storage._flags {return false} - if _storage._traceID != rhs_storage._traceID {return false} - if _storage._spanID != rhs_storage._spanID {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.timeUnixNano != rhs.timeUnixNano {return false} + if lhs.severityNumber != rhs.severityNumber {return false} + if lhs.severityText != rhs.severityText {return false} + if lhs.name != rhs.name {return false} + if lhs._body != rhs._body {return false} + if lhs.attributes != rhs.attributes {return false} + if lhs.droppedAttributesCount != rhs.droppedAttributesCount {return false} + if lhs.flags != rhs.flags {return false} + if lhs.traceID != rhs.traceID {return false} + if lhs.spanID != rhs.spanID {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.grpc.swift index 383c57e2..22b90549 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.grpc.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.grpc.swift @@ -20,74 +20,120 @@ // See the License for the specific language governing permissions and // limitations under the License. // -import Foundation import GRPC import NIO -import NIOHTTP1 import SwiftProtobuf -/// Usage: instantiate Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClient, then call methods of this protocol to make API calls. -public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol { - func export(_ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, callOptions: CallOptions?) -> UnaryCall +/// Service that can be used to push logs between one Application instrumented with +/// OpenTelemetry and an collector, or between an collector and a central collector (in this +/// case logs are sent/received to/from multiple Applications). +/// +/// Usage: instantiate `Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClient`, then call methods of this protocol to make API calls. +public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol: GRPCClient { + var serviceName: String { get } + var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? { get } + + func export( + _ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, + callOptions: CallOptions? + ) -> UnaryCall +} + +extension Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol { + public var serviceName: String { + return "opentelemetry.proto.collector.logs.v1.LogsService" + } + + /// For performance reasons, it is recommended to keep this RPC + /// alive for the entire life of the application. + /// + /// - Parameters: + /// - request: Request to send to Export. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func export( + _ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: "/opentelemetry.proto.collector.logs.v1.LogsService/Export", + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExportInterceptors() ?? [] + ) + } +} + +public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol { + + /// - Returns: Interceptors to use when invoking 'export'. + func makeExportInterceptors() -> [ClientInterceptor] } -public final class Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClient: GRPCClient, Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol { +public final class Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClient: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol { public let channel: GRPCChannel public var defaultCallOptions: CallOptions + public var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? /// Creates a client for the opentelemetry.proto.collector.logs.v1.LogsService service. /// /// - Parameters: /// - channel: `GRPCChannel` to the service host. /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. - public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? = nil + ) { self.channel = channel self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors } - - /// For performance reasons, it is recommended to keep this RPC - /// alive for the entire life of the application. - /// - /// - Parameters: - /// - request: Request to send to Export. - /// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`. - /// - Returns: A `UnaryCall` with futures for the metadata, status and response. - public func export(_ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, callOptions: CallOptions? = nil) -> UnaryCall { - return self.makeUnaryCall(path: "/opentelemetry.proto.collector.logs.v1.LogsService/Export", - request: request, - callOptions: callOptions ?? self.defaultCallOptions) - } - } +/// Service that can be used to push logs between one Application instrumented with +/// OpenTelemetry and an collector, or between an collector and a central collector (in this +/// case logs are sent/received to/from multiple Applications). +/// /// To build a server, implement a class that conforms to this protocol. public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceProvider: CallHandlerProvider { + var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerInterceptorFactoryProtocol? { get } + /// For performance reasons, it is recommended to keep this RPC /// alive for the entire life of the application. func export(request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, context: StatusOnlyCallContext) -> EventLoopFuture } extension Opentelemetry_Proto_Collector_Logs_V1_LogsServiceProvider { - public var serviceName: String { return "opentelemetry.proto.collector.logs.v1.LogsService" } + public var serviceName: Substring { return "opentelemetry.proto.collector.logs.v1.LogsService" } /// Determines, calls and returns the appropriate request handler, depending on the request's method. /// Returns nil for methods not handled by this service. - public func handleMethod(_ methodName: String, callHandlerContext: CallHandlerContext) -> GRPCCallHandler? { - switch methodName { + public func handle( + method name: Substring, + context: CallHandlerContext + ) -> GRPCServerHandlerProtocol? { + switch name { case "Export": - return UnaryCallHandler(callHandlerContext: callHandlerContext) { context in - return { request in - self.export(request: request, context: context) - } - } + return UnaryServerHandler( + context: context, + requestDeserializer: ProtobufDeserializer(), + responseSerializer: ProtobufSerializer(), + interceptors: self.interceptors?.makeExportInterceptors() ?? [], + userFunction: self.export(request:context:) + ) - default: return nil + default: + return nil } } } +public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerInterceptorFactoryProtocol { -// Provides conformance to `GRPCPayload` -extension Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest: GRPCProtobufPayload {} -extension Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse: GRPCProtobufPayload {} + /// - Returns: Interceptors to use when handling 'export'. + /// Defaults to calling `self.makeInterceptors()`. + func makeExportInterceptors() -> [ServerInterceptor] +} diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.pb.swift index 3ebdda53..d8ee7dcd 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/logs_service.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/collector/logs/v1/logs_service.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -72,8 +73,11 @@ extension Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest: SwiftP public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.resourceLogs) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.resourceLogs) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/metrics.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/metrics.pb.swift index 4edd4daf..6a8cd5e3 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/metrics.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/metrics.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/metrics/v1/metrics.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -68,7 +69,7 @@ public enum Opentelemetry_Proto_Metrics_V1_AggregationTemporality: SwiftProtobuf /// t_0+2 with a value of 2. case delta // = 1 - /// CUMULATIVE is an AggregationTemporality for a metic aggregator which + /// CUMULATIVE is an AggregationTemporality for a metric aggregator which /// reports changes since a fixed start time. This means that current values /// of a CUMULATIVE metric depend on all previous measurements since the /// start time. Because of this, the sender is required to retain this state @@ -152,25 +153,22 @@ public struct Opentelemetry_Proto_Metrics_V1_ResourceMetrics { /// The resource for the metrics in this message. /// If this field is not set then no resource info is known. public var resource: Opentelemetry_Proto_Resource_V1_Resource { - get {return _storage._resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_uniqueStorage()._resource = newValue} + get {return _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} + set {_resource = newValue} } /// Returns true if `resource` has been explicitly set. - public var hasResource: Bool {return _storage._resource != nil} + public var hasResource: Bool {return self._resource != nil} /// Clears the value of `resource`. Subsequent reads from it will return its default value. - public mutating func clearResource() {_uniqueStorage()._resource = nil} + public mutating func clearResource() {self._resource = nil} /// A list of metrics that originate from a resource. - public var instrumentationLibraryMetrics: [Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics] { - get {return _storage._instrumentationLibraryMetrics} - set {_uniqueStorage()._instrumentationLibraryMetrics = newValue} - } + public var instrumentationLibraryMetrics: [Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics] = [] public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil } /// A collection of Metrics produced by an InstrumentationLibrary. @@ -180,27 +178,25 @@ public struct Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics { // methods supported on all messages. /// The instrumentation library information for the metrics in this message. - /// If this field is not set then no library info is known. + /// Semantically when InstrumentationLibrary isn't set, it is equivalent with + /// an empty instrumentation library name (unknown). public var instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary { - get {return _storage._instrumentationLibrary ?? Opentelemetry_Proto_Common_V1_InstrumentationLibrary()} - set {_uniqueStorage()._instrumentationLibrary = newValue} + get {return _instrumentationLibrary ?? Opentelemetry_Proto_Common_V1_InstrumentationLibrary()} + set {_instrumentationLibrary = newValue} } /// Returns true if `instrumentationLibrary` has been explicitly set. - public var hasInstrumentationLibrary: Bool {return _storage._instrumentationLibrary != nil} + public var hasInstrumentationLibrary: Bool {return self._instrumentationLibrary != nil} /// Clears the value of `instrumentationLibrary`. Subsequent reads from it will return its default value. - public mutating func clearInstrumentationLibrary() {_uniqueStorage()._instrumentationLibrary = nil} + public mutating func clearInstrumentationLibrary() {self._instrumentationLibrary = nil} /// A list of metrics that originate from an instrumentation library. - public var metrics: [Opentelemetry_Proto_Metrics_V1_Metric] { - get {return _storage._metrics} - set {_uniqueStorage()._metrics = newValue} - } + public var metrics: [Opentelemetry_Proto_Metrics_V1_Metric] = [] public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary? = nil } /// Defines a Metric which has one or more timeseries. @@ -220,11 +216,11 @@ public struct Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics { /// +------------+ /// |name | /// |description | -/// |unit | +---------------------------+ -/// |data |---> |Gauge, Sum, Histogram, ... | -/// +------------+ +---------------------------+ +/// |unit | +------------------------------------+ +/// |data |---> |Gauge, Sum, Histogram, Summary, ... | +/// +------------+ +------------------------------------+ /// -/// Data [One of Gauge, Sum, Histogram, ...] +/// Data [One of Gauge, Sum, Histogram, Summary, ...] /// +-----------+ /// |... | // Metadata about the Data. /// |points |--+ @@ -267,23 +263,14 @@ public struct Opentelemetry_Proto_Metrics_V1_Metric { // methods supported on all messages. /// name of the metric, including its DNS name prefix. It must be unique. - public var name: String { - get {return _storage._name} - set {_uniqueStorage()._name = newValue} - } + public var name: String = String() /// description of the metric, which can be used in documentation. - public var description_p: String { - get {return _storage._description_p} - set {_uniqueStorage()._description_p = newValue} - } + public var description_p: String = String() /// unit in which the metric value is reported. Follows the format /// described by http://unitsofmeasure.org/ucum.html. - public var unit: String { - get {return _storage._unit} - set {_uniqueStorage()._unit = newValue} - } + public var unit: String = String() /// Data determines the aggregation type (if any) of the metric, what is the /// reported value type for the data points, as well as the relatationship to @@ -302,57 +289,62 @@ public struct Opentelemetry_Proto_Metrics_V1_Metric { /// SumObserver Sum(aggregation_temporality=cumulative;is_monotonic=true) /// UpDownSumObserver Sum(aggregation_temporality=cumulative;is_monotonic=false) /// ValueObserver Gauge() - public var data: OneOf_Data? { - get {return _storage._data} - set {_uniqueStorage()._data = newValue} - } + public var data: Opentelemetry_Proto_Metrics_V1_Metric.OneOf_Data? = nil public var intGauge: Opentelemetry_Proto_Metrics_V1_IntGauge { get { - if case .intGauge(let v)? = _storage._data {return v} + if case .intGauge(let v)? = data {return v} return Opentelemetry_Proto_Metrics_V1_IntGauge() } - set {_uniqueStorage()._data = .intGauge(newValue)} + set {data = .intGauge(newValue)} } public var doubleGauge: Opentelemetry_Proto_Metrics_V1_DoubleGauge { get { - if case .doubleGauge(let v)? = _storage._data {return v} + if case .doubleGauge(let v)? = data {return v} return Opentelemetry_Proto_Metrics_V1_DoubleGauge() } - set {_uniqueStorage()._data = .doubleGauge(newValue)} + set {data = .doubleGauge(newValue)} } public var intSum: Opentelemetry_Proto_Metrics_V1_IntSum { get { - if case .intSum(let v)? = _storage._data {return v} + if case .intSum(let v)? = data {return v} return Opentelemetry_Proto_Metrics_V1_IntSum() } - set {_uniqueStorage()._data = .intSum(newValue)} + set {data = .intSum(newValue)} } public var doubleSum: Opentelemetry_Proto_Metrics_V1_DoubleSum { get { - if case .doubleSum(let v)? = _storage._data {return v} + if case .doubleSum(let v)? = data {return v} return Opentelemetry_Proto_Metrics_V1_DoubleSum() } - set {_uniqueStorage()._data = .doubleSum(newValue)} + set {data = .doubleSum(newValue)} } public var intHistogram: Opentelemetry_Proto_Metrics_V1_IntHistogram { get { - if case .intHistogram(let v)? = _storage._data {return v} + if case .intHistogram(let v)? = data {return v} return Opentelemetry_Proto_Metrics_V1_IntHistogram() } - set {_uniqueStorage()._data = .intHistogram(newValue)} + set {data = .intHistogram(newValue)} } public var doubleHistogram: Opentelemetry_Proto_Metrics_V1_DoubleHistogram { get { - if case .doubleHistogram(let v)? = _storage._data {return v} + if case .doubleHistogram(let v)? = data {return v} return Opentelemetry_Proto_Metrics_V1_DoubleHistogram() } - set {_uniqueStorage()._data = .doubleHistogram(newValue)} + set {data = .doubleHistogram(newValue)} + } + + public var doubleSummary: Opentelemetry_Proto_Metrics_V1_DoubleSummary { + get { + if case .doubleSummary(let v)? = data {return v} + return Opentelemetry_Proto_Metrics_V1_DoubleSummary() + } + set {data = .doubleSummary(newValue)} } public var unknownFields = SwiftProtobuf.UnknownStorage() @@ -381,16 +373,42 @@ public struct Opentelemetry_Proto_Metrics_V1_Metric { case doubleSum(Opentelemetry_Proto_Metrics_V1_DoubleSum) case intHistogram(Opentelemetry_Proto_Metrics_V1_IntHistogram) case doubleHistogram(Opentelemetry_Proto_Metrics_V1_DoubleHistogram) + case doubleSummary(Opentelemetry_Proto_Metrics_V1_DoubleSummary) #if !swift(>=4.1) public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_Metric.OneOf_Data, rhs: Opentelemetry_Proto_Metrics_V1_Metric.OneOf_Data) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch (lhs, rhs) { - case (.intGauge(let l), .intGauge(let r)): return l == r - case (.doubleGauge(let l), .doubleGauge(let r)): return l == r - case (.intSum(let l), .intSum(let r)): return l == r - case (.doubleSum(let l), .doubleSum(let r)): return l == r - case (.intHistogram(let l), .intHistogram(let r)): return l == r - case (.doubleHistogram(let l), .doubleHistogram(let r)): return l == r + case (.intGauge, .intGauge): return { + guard case .intGauge(let l) = lhs, case .intGauge(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.doubleGauge, .doubleGauge): return { + guard case .doubleGauge(let l) = lhs, case .doubleGauge(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.intSum, .intSum): return { + guard case .intSum(let l) = lhs, case .intSum(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.doubleSum, .doubleSum): return { + guard case .doubleSum(let l) = lhs, case .doubleSum(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.intHistogram, .intHistogram): return { + guard case .intHistogram(let l) = lhs, case .intHistogram(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.doubleHistogram, .doubleHistogram): return { + guard case .doubleHistogram(let l) = lhs, case .doubleHistogram(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.doubleSummary, .doubleSummary): return { + guard case .doubleSummary(let l) = lhs, case .doubleSummary(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -398,8 +416,6 @@ public struct Opentelemetry_Proto_Metrics_V1_Metric { } public init() {} - - fileprivate var _storage = _StorageClass.defaultInstance } /// Gauge represents the type of a int scalar metric that always exports the @@ -522,6 +538,24 @@ public struct Opentelemetry_Proto_Metrics_V1_DoubleHistogram { public init() {} } +/// DoubleSummary metric data are used to convey quantile summaries, +/// a Prometheus (see: https://prometheus.io/docs/concepts/metric_types/#summary) +/// and OpenMetrics (see: https://github.com/OpenObservability/OpenMetrics/blob/4dbf6075567ab43296eed941037c12951faafb92/protos/prometheus.proto#L45) +/// data type. These data points cannot always be merged in a meaningful way. +/// While they can be useful in some applications, histogram data points are +/// recommended for new applications. +public struct Opentelemetry_Proto_Metrics_V1_DoubleSummary { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var dataPoints: [Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + /// IntDataPoint is a single data point in a timeseries that describes the /// time-varying values of a int64 metric. public struct Opentelemetry_Proto_Metrics_V1_IntDataPoint { @@ -758,6 +792,77 @@ public struct Opentelemetry_Proto_Metrics_V1_DoubleHistogramDataPoint { public init() {} } +/// DoubleSummaryDataPoint is a single data point in a timeseries that describes the +/// time-varying values of a Summary metric. +public struct Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The set of labels that uniquely identify this timeseries. + public var labels: [Opentelemetry_Proto_Common_V1_StringKeyValue] = [] + + /// start_time_unix_nano is the last time when the aggregation value was reset + /// to "zero". For some metric types this is ignored, see data types for more + /// details. + /// + /// The aggregation value is over the time interval (start_time_unix_nano, + /// time_unix_nano]. + /// + /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + /// 1970. + /// + /// Value of 0 indicates that the timestamp is unspecified. In that case the + /// timestamp may be decided by the backend. + public var startTimeUnixNano: UInt64 = 0 + + /// time_unix_nano is the moment when this aggregation value was reported. + /// + /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + /// 1970. + public var timeUnixNano: UInt64 = 0 + + /// count is the number of values in the population. Must be non-negative. + public var count: UInt64 = 0 + + /// sum of the values in the population. If count is zero then this field + /// must be zero. + public var sum: Double = 0 + + /// (Optional) list of values at different quantiles of the distribution calculated + /// from the current snapshot. The quantiles must be strictly increasing. + public var quantileValues: [Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint.ValueAtQuantile] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Represents the value at a given quantile of a distribution. + /// + /// To record Min and Max values following conventions are used: + /// - The 1.0 quantile is equivalent to the maximum value observed. + /// - The 0.0 quantile is equivalent to the minimum value observed. + /// + /// See the following issue for more context: + /// https://github.com/open-telemetry/opentelemetry-proto/issues/125 + public struct ValueAtQuantile { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The quantile of a distribution. Must be in the interval + /// [0.0, 1.0]. + public var quantile: Double = 0 + + /// The value at the given quantile of a distribution. + public var value: Double = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + } + + public init() {} +} + /// A representation of an exemplar, which is a sample input int measurement. /// Exemplars also hold information about the environment when the measurement /// was recorded, for example the span and trace ID of the active span when the @@ -784,12 +889,12 @@ public struct Opentelemetry_Proto_Metrics_V1_IntExemplar { /// (Optional) Span ID of the exemplar trace. /// span_id may be missing if the measurement is not recorded inside a trace /// or if the trace is not sampled. - public var spanID: Data = SwiftProtobuf.Internal.emptyData + public var spanID: Data = Data() /// (Optional) Trace ID of the exemplar trace. /// trace_id may be missing if the measurement is not recorded inside a trace /// or if the trace is not sampled. - public var traceID: Data = SwiftProtobuf.Internal.emptyData + public var traceID: Data = Data() public var unknownFields = SwiftProtobuf.UnknownStorage() @@ -822,12 +927,12 @@ public struct Opentelemetry_Proto_Metrics_V1_DoubleExemplar { /// (Optional) Span ID of the exemplar trace. /// span_id may be missing if the measurement is not recorded inside a trace /// or if the trace is not sampled. - public var spanID: Data = SwiftProtobuf.Internal.emptyData + public var spanID: Data = Data() /// (Optional) Trace ID of the exemplar trace. /// trace_id may be missing if the measurement is not recorded inside a trace /// or if the trace is not sampled. - public var traceID: Data = SwiftProtobuf.Internal.emptyData + public var traceID: Data = Data() public var unknownFields = SwiftProtobuf.UnknownStorage() @@ -853,63 +958,32 @@ extension Opentelemetry_Proto_Metrics_V1_ResourceMetrics: SwiftProtobuf.Message, 2: .standard(proto: "instrumentation_library_metrics"), ] - fileprivate class _StorageClass { - var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil - var _instrumentationLibraryMetrics: [Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics] = [] - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _resource = source._resource - _instrumentationLibraryMetrics = source._instrumentationLibraryMetrics - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularMessageField(value: &_storage._resource) - case 2: try decoder.decodeRepeatedMessageField(value: &_storage._instrumentationLibraryMetrics) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._resource) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.instrumentationLibraryMetrics) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if !_storage._instrumentationLibraryMetrics.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._instrumentationLibraryMetrics, fieldNumber: 2) - } + if let v = self._resource { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.instrumentationLibraryMetrics.isEmpty { + try visitor.visitRepeatedMessageField(value: self.instrumentationLibraryMetrics, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_ResourceMetrics, rhs: Opentelemetry_Proto_Metrics_V1_ResourceMetrics) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._resource != rhs_storage._resource {return false} - if _storage._instrumentationLibraryMetrics != rhs_storage._instrumentationLibraryMetrics {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._resource != rhs._resource {return false} + if lhs.instrumentationLibraryMetrics != rhs.instrumentationLibraryMetrics {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -922,63 +996,32 @@ extension Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics: SwiftPro 2: .same(proto: "metrics"), ] - fileprivate class _StorageClass { - var _instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary? = nil - var _metrics: [Opentelemetry_Proto_Metrics_V1_Metric] = [] - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _instrumentationLibrary = source._instrumentationLibrary - _metrics = source._metrics - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularMessageField(value: &_storage._instrumentationLibrary) - case 2: try decoder.decodeRepeatedMessageField(value: &_storage._metrics) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._instrumentationLibrary) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.metrics) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._instrumentationLibrary { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if !_storage._metrics.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._metrics, fieldNumber: 2) - } + if let v = self._instrumentationLibrary { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.metrics.isEmpty { + try visitor.visitRepeatedMessageField(value: self.metrics, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics, rhs: Opentelemetry_Proto_Metrics_V1_InstrumentationLibraryMetrics) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._instrumentationLibrary != rhs_storage._instrumentationLibrary {return false} - if _storage._metrics != rhs_storage._metrics {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._instrumentationLibrary != rhs._instrumentationLibrary {return false} + if lhs.metrics != rhs.metrics {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -996,138 +1039,138 @@ extension Opentelemetry_Proto_Metrics_V1_Metric: SwiftProtobuf.Message, SwiftPro 7: .standard(proto: "double_sum"), 8: .standard(proto: "int_histogram"), 9: .standard(proto: "double_histogram"), + 11: .standard(proto: "double_summary"), ] - fileprivate class _StorageClass { - var _name: String = String() - var _description_p: String = String() - var _unit: String = String() - var _data: Opentelemetry_Proto_Metrics_V1_Metric.OneOf_Data? - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _name = source._name - _description_p = source._description_p - _unit = source._unit - _data = source._data - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularStringField(value: &_storage._name) - case 2: try decoder.decodeSingularStringField(value: &_storage._description_p) - case 3: try decoder.decodeSingularStringField(value: &_storage._unit) - case 4: - var v: Opentelemetry_Proto_Metrics_V1_IntGauge? - if let current = _storage._data { - try decoder.handleConflictingOneOf() - if case .intGauge(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._data = .intGauge(v)} - case 5: - var v: Opentelemetry_Proto_Metrics_V1_DoubleGauge? - if let current = _storage._data { - try decoder.handleConflictingOneOf() - if case .doubleGauge(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._data = .doubleGauge(v)} - case 6: - var v: Opentelemetry_Proto_Metrics_V1_IntSum? - if let current = _storage._data { - try decoder.handleConflictingOneOf() - if case .intSum(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._data = .intSum(v)} - case 7: - var v: Opentelemetry_Proto_Metrics_V1_DoubleSum? - if let current = _storage._data { - try decoder.handleConflictingOneOf() - if case .doubleSum(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._data = .doubleSum(v)} - case 8: - var v: Opentelemetry_Proto_Metrics_V1_IntHistogram? - if let current = _storage._data { - try decoder.handleConflictingOneOf() - if case .intHistogram(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._data = .intHistogram(v)} - case 9: - var v: Opentelemetry_Proto_Metrics_V1_DoubleHistogram? - if let current = _storage._data { - try decoder.handleConflictingOneOf() - if case .doubleHistogram(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._data = .doubleHistogram(v)} - default: break + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.description_p) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.unit) }() + case 4: try { + var v: Opentelemetry_Proto_Metrics_V1_IntGauge? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .intGauge(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .intGauge(v)} + }() + case 5: try { + var v: Opentelemetry_Proto_Metrics_V1_DoubleGauge? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .doubleGauge(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .doubleGauge(v)} + }() + case 6: try { + var v: Opentelemetry_Proto_Metrics_V1_IntSum? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .intSum(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .intSum(v)} + }() + case 7: try { + var v: Opentelemetry_Proto_Metrics_V1_DoubleSum? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .doubleSum(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .doubleSum(v)} + }() + case 8: try { + var v: Opentelemetry_Proto_Metrics_V1_IntHistogram? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .intHistogram(let m) = current {v = m} } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .intHistogram(v)} + }() + case 9: try { + var v: Opentelemetry_Proto_Metrics_V1_DoubleHistogram? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .doubleHistogram(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .doubleHistogram(v)} + }() + case 11: try { + var v: Opentelemetry_Proto_Metrics_V1_DoubleSummary? + if let current = self.data { + try decoder.handleConflictingOneOf() + if case .doubleSummary(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.data = .doubleSummary(v)} + }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if !_storage._name.isEmpty { - try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1) - } - if !_storage._description_p.isEmpty { - try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 2) - } - if !_storage._unit.isEmpty { - try visitor.visitSingularStringField(value: _storage._unit, fieldNumber: 3) - } - switch _storage._data { - case .intGauge(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - case .doubleGauge(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - case .intSum(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 6) - case .doubleSum(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - case .intHistogram(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - case .doubleHistogram(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 9) - case nil: break - } + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if !self.description_p.isEmpty { + try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 2) + } + if !self.unit.isEmpty { + try visitor.visitSingularStringField(value: self.unit, fieldNumber: 3) + } + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch self.data { + case .intGauge?: try { + guard case .intGauge(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .doubleGauge?: try { + guard case .doubleGauge(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .intSum?: try { + guard case .intSum(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case .doubleSum?: try { + guard case .doubleSum(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case .intHistogram?: try { + guard case .intHistogram(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + }() + case .doubleHistogram?: try { + guard case .doubleHistogram(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + }() + case .doubleSummary?: try { + guard case .doubleSummary(let v)? = self.data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 11) + }() + case nil: break } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_Metric, rhs: Opentelemetry_Proto_Metrics_V1_Metric) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._name != rhs_storage._name {return false} - if _storage._description_p != rhs_storage._description_p {return false} - if _storage._unit != rhs_storage._unit {return false} - if _storage._data != rhs_storage._data {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.name != rhs.name {return false} + if lhs.description_p != rhs.description_p {return false} + if lhs.unit != rhs.unit {return false} + if lhs.data != rhs.data {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -1141,8 +1184,11 @@ extension Opentelemetry_Proto_Metrics_V1_IntGauge: SwiftProtobuf.Message, SwiftP public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.dataPoints) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() default: break } } @@ -1170,8 +1216,11 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleGauge: SwiftProtobuf.Message, Swi public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.dataPoints) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() default: break } } @@ -1201,10 +1250,13 @@ extension Opentelemetry_Proto_Metrics_V1_IntSum: SwiftProtobuf.Message, SwiftPro public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.dataPoints) - case 2: try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) - case 3: try decoder.decodeSingularBoolField(value: &self.isMonotonic) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.isMonotonic) }() default: break } } @@ -1242,10 +1294,13 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleSum: SwiftProtobuf.Message, Swift public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.dataPoints) - case 2: try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) - case 3: try decoder.decodeSingularBoolField(value: &self.isMonotonic) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.isMonotonic) }() default: break } } @@ -1282,9 +1337,12 @@ extension Opentelemetry_Proto_Metrics_V1_IntHistogram: SwiftProtobuf.Message, Sw public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.dataPoints) - case 2: try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() default: break } } @@ -1317,9 +1375,12 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleHistogram: SwiftProtobuf.Message, public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.dataPoints) - case 2: try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() default: break } } @@ -1343,6 +1404,38 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleHistogram: SwiftProtobuf.Message, } } +extension Opentelemetry_Proto_Metrics_V1_DoubleSummary: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".DoubleSummary" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "data_points"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.dataPoints) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.dataPoints.isEmpty { + try visitor.visitRepeatedMessageField(value: self.dataPoints, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_DoubleSummary, rhs: Opentelemetry_Proto_Metrics_V1_DoubleSummary) -> Bool { + if lhs.dataPoints != rhs.dataPoints {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension Opentelemetry_Proto_Metrics_V1_IntDataPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".IntDataPoint" public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -1355,12 +1448,15 @@ extension Opentelemetry_Proto_Metrics_V1_IntDataPoint: SwiftProtobuf.Message, Sw public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.labels) - case 2: try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) - case 3: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 4: try decoder.decodeSingularSFixed64Field(value: &self.value) - case 5: try decoder.decodeRepeatedMessageField(value: &self.exemplars) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.labels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) }() + case 3: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 4: try { try decoder.decodeSingularSFixed64Field(value: &self.value) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.exemplars) }() default: break } } @@ -1408,12 +1504,15 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleDataPoint: SwiftProtobuf.Message, public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.labels) - case 2: try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) - case 3: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 4: try decoder.decodeSingularDoubleField(value: &self.value) - case 5: try decoder.decodeRepeatedMessageField(value: &self.exemplars) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.labels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) }() + case 3: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 4: try { try decoder.decodeSingularDoubleField(value: &self.value) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.exemplars) }() default: break } } @@ -1464,15 +1563,18 @@ extension Opentelemetry_Proto_Metrics_V1_IntHistogramDataPoint: SwiftProtobuf.Me public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.labels) - case 2: try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) - case 3: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 4: try decoder.decodeSingularFixed64Field(value: &self.count) - case 5: try decoder.decodeSingularSFixed64Field(value: &self.sum) - case 6: try decoder.decodeRepeatedFixed64Field(value: &self.bucketCounts) - case 7: try decoder.decodeRepeatedDoubleField(value: &self.explicitBounds) - case 8: try decoder.decodeRepeatedMessageField(value: &self.exemplars) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.labels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) }() + case 3: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 4: try { try decoder.decodeSingularFixed64Field(value: &self.count) }() + case 5: try { try decoder.decodeSingularSFixed64Field(value: &self.sum) }() + case 6: try { try decoder.decodeRepeatedFixed64Field(value: &self.bucketCounts) }() + case 7: try { try decoder.decodeRepeatedDoubleField(value: &self.explicitBounds) }() + case 8: try { try decoder.decodeRepeatedMessageField(value: &self.exemplars) }() default: break } } @@ -1535,15 +1637,18 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleHistogramDataPoint: SwiftProtobuf public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.labels) - case 2: try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) - case 3: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 4: try decoder.decodeSingularFixed64Field(value: &self.count) - case 5: try decoder.decodeSingularDoubleField(value: &self.sum) - case 6: try decoder.decodeRepeatedFixed64Field(value: &self.bucketCounts) - case 7: try decoder.decodeRepeatedDoubleField(value: &self.explicitBounds) - case 8: try decoder.decodeRepeatedMessageField(value: &self.exemplars) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.labels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) }() + case 3: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 4: try { try decoder.decodeSingularFixed64Field(value: &self.count) }() + case 5: try { try decoder.decodeSingularDoubleField(value: &self.sum) }() + case 6: try { try decoder.decodeRepeatedFixed64Field(value: &self.bucketCounts) }() + case 7: try { try decoder.decodeRepeatedDoubleField(value: &self.explicitBounds) }() + case 8: try { try decoder.decodeRepeatedMessageField(value: &self.exemplars) }() default: break } } @@ -1591,6 +1696,106 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleHistogramDataPoint: SwiftProtobuf } } +extension Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".DoubleSummaryDataPoint" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "labels"), + 2: .standard(proto: "start_time_unix_nano"), + 3: .standard(proto: "time_unix_nano"), + 4: .same(proto: "count"), + 5: .same(proto: "sum"), + 6: .standard(proto: "quantile_values"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.labels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) }() + case 3: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 4: try { try decoder.decodeSingularFixed64Field(value: &self.count) }() + case 5: try { try decoder.decodeSingularDoubleField(value: &self.sum) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &self.quantileValues) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.labels.isEmpty { + try visitor.visitRepeatedMessageField(value: self.labels, fieldNumber: 1) + } + if self.startTimeUnixNano != 0 { + try visitor.visitSingularFixed64Field(value: self.startTimeUnixNano, fieldNumber: 2) + } + if self.timeUnixNano != 0 { + try visitor.visitSingularFixed64Field(value: self.timeUnixNano, fieldNumber: 3) + } + if self.count != 0 { + try visitor.visitSingularFixed64Field(value: self.count, fieldNumber: 4) + } + if self.sum != 0 { + try visitor.visitSingularDoubleField(value: self.sum, fieldNumber: 5) + } + if !self.quantileValues.isEmpty { + try visitor.visitRepeatedMessageField(value: self.quantileValues, fieldNumber: 6) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint, rhs: Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint) -> Bool { + if lhs.labels != rhs.labels {return false} + if lhs.startTimeUnixNano != rhs.startTimeUnixNano {return false} + if lhs.timeUnixNano != rhs.timeUnixNano {return false} + if lhs.count != rhs.count {return false} + if lhs.sum != rhs.sum {return false} + if lhs.quantileValues != rhs.quantileValues {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint.ValueAtQuantile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint.protoMessageName + ".ValueAtQuantile" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "quantile"), + 2: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularDoubleField(value: &self.quantile) }() + case 2: try { try decoder.decodeSingularDoubleField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.quantile != 0 { + try visitor.visitSingularDoubleField(value: self.quantile, fieldNumber: 1) + } + if self.value != 0 { + try visitor.visitSingularDoubleField(value: self.value, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint.ValueAtQuantile, rhs: Opentelemetry_Proto_Metrics_V1_DoubleSummaryDataPoint.ValueAtQuantile) -> Bool { + if lhs.quantile != rhs.quantile {return false} + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension Opentelemetry_Proto_Metrics_V1_IntExemplar: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".IntExemplar" public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -1603,12 +1808,15 @@ extension Opentelemetry_Proto_Metrics_V1_IntExemplar: SwiftProtobuf.Message, Swi public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.filteredLabels) - case 2: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 3: try decoder.decodeSingularSFixed64Field(value: &self.value) - case 4: try decoder.decodeSingularBytesField(value: &self.spanID) - case 5: try decoder.decodeSingularBytesField(value: &self.traceID) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.filteredLabels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 3: try { try decoder.decodeSingularSFixed64Field(value: &self.value) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.spanID) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.traceID) }() default: break } } @@ -1656,12 +1864,15 @@ extension Opentelemetry_Proto_Metrics_V1_DoubleExemplar: SwiftProtobuf.Message, public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.filteredLabels) - case 2: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 3: try decoder.decodeSingularDoubleField(value: &self.value) - case 4: try decoder.decodeSingularBytesField(value: &self.spanID) - case 5: try decoder.decodeSingularBytesField(value: &self.traceID) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.filteredLabels) }() + case 2: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 3: try { try decoder.decodeSingularDoubleField(value: &self.value) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.spanID) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.traceID) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.grpc.swift index e5d8824b..784c81b4 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.grpc.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.grpc.swift @@ -20,74 +20,120 @@ // See the License for the specific language governing permissions and // limitations under the License. // -import Foundation import GRPC import NIO -import NIOHTTP1 import SwiftProtobuf -/// Usage: instantiate Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient, then call methods of this protocol to make API calls. -public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol { - func export(_ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, callOptions: CallOptions?) -> UnaryCall +/// Service that can be used to push metrics between one Application +/// instrumented with OpenTelemetry and a collector, or between a collector and a +/// central collector. +/// +/// Usage: instantiate `Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient`, then call methods of this protocol to make API calls. +public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol: GRPCClient { + var serviceName: String { get } + var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? { get } + + func export( + _ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, + callOptions: CallOptions? + ) -> UnaryCall +} + +extension Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol { + public var serviceName: String { + return "opentelemetry.proto.collector.metrics.v1.MetricsService" + } + + /// For performance reasons, it is recommended to keep this RPC + /// alive for the entire life of the application. + /// + /// - Parameters: + /// - request: Request to send to Export. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func export( + _ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExportInterceptors() ?? [] + ) + } +} + +public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol { + + /// - Returns: Interceptors to use when invoking 'export'. + func makeExportInterceptors() -> [ClientInterceptor] } -public final class Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient: GRPCClient, Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol { +public final class Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol { public let channel: GRPCChannel public var defaultCallOptions: CallOptions + public var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? /// Creates a client for the opentelemetry.proto.collector.metrics.v1.MetricsService service. /// /// - Parameters: /// - channel: `GRPCChannel` to the service host. /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. - public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? = nil + ) { self.channel = channel self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors } - - /// For performance reasons, it is recommended to keep this RPC - /// alive for the entire life of the application. - /// - /// - Parameters: - /// - request: Request to send to Export. - /// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`. - /// - Returns: A `UnaryCall` with futures for the metadata, status and response. - public func export(_ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, callOptions: CallOptions? = nil) -> UnaryCall { - return self.makeUnaryCall(path: "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", - request: request, - callOptions: callOptions ?? self.defaultCallOptions) - } - } +/// Service that can be used to push metrics between one Application +/// instrumented with OpenTelemetry and a collector, or between a collector and a +/// central collector. +/// /// To build a server, implement a class that conforms to this protocol. public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceProvider: CallHandlerProvider { + var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerInterceptorFactoryProtocol? { get } + /// For performance reasons, it is recommended to keep this RPC /// alive for the entire life of the application. func export(request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, context: StatusOnlyCallContext) -> EventLoopFuture } extension Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceProvider { - public var serviceName: String { return "opentelemetry.proto.collector.metrics.v1.MetricsService" } + public var serviceName: Substring { return "opentelemetry.proto.collector.metrics.v1.MetricsService" } /// Determines, calls and returns the appropriate request handler, depending on the request's method. /// Returns nil for methods not handled by this service. - public func handleMethod(_ methodName: String, callHandlerContext: CallHandlerContext) -> GRPCCallHandler? { - switch methodName { + public func handle( + method name: Substring, + context: CallHandlerContext + ) -> GRPCServerHandlerProtocol? { + switch name { case "Export": - return UnaryCallHandler(callHandlerContext: callHandlerContext) { context in - return { request in - self.export(request: request, context: context) - } - } + return UnaryServerHandler( + context: context, + requestDeserializer: ProtobufDeserializer(), + responseSerializer: ProtobufSerializer(), + interceptors: self.interceptors?.makeExportInterceptors() ?? [], + userFunction: self.export(request:context:) + ) - default: return nil + default: + return nil } } } +public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerInterceptorFactoryProtocol { -// Provides conformance to `GRPCPayload` -extension Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest: GRPCProtobufPayload {} -extension Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse: GRPCProtobufPayload {} + /// - Returns: Interceptors to use when handling 'export'. + /// Defaults to calling `self.makeInterceptors()`. + func makeExportInterceptors() -> [ServerInterceptor] +} diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.pb.swift index c0fdbfa5..90b636c0 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/metrics_service.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -72,8 +73,11 @@ extension Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest: public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.resourceMetrics) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.resourceMetrics) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/resource.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/resource.pb.swift index 4a775357..0a1a7e63 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/resource.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/resource.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/resource/v1/resource.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -64,9 +65,12 @@ extension Opentelemetry_Proto_Resource_V1_Resource: SwiftProtobuf.Message, Swift public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.attributes) - case 2: try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/trace.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/trace.pb.swift index 5531c28c..927623e4 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/trace.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/trace.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/trace/v1/trace.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -42,25 +43,22 @@ public struct Opentelemetry_Proto_Trace_V1_ResourceSpans { /// The resource for the spans in this message. /// If this field is not set then no resource info is known. public var resource: Opentelemetry_Proto_Resource_V1_Resource { - get {return _storage._resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_uniqueStorage()._resource = newValue} + get {return _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} + set {_resource = newValue} } /// Returns true if `resource` has been explicitly set. - public var hasResource: Bool {return _storage._resource != nil} + public var hasResource: Bool {return self._resource != nil} /// Clears the value of `resource`. Subsequent reads from it will return its default value. - public mutating func clearResource() {_uniqueStorage()._resource = nil} + public mutating func clearResource() {self._resource = nil} /// A list of InstrumentationLibrarySpans that originate from a resource. - public var instrumentationLibrarySpans: [Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans] { - get {return _storage._instrumentationLibrarySpans} - set {_uniqueStorage()._instrumentationLibrarySpans = newValue} - } + public var instrumentationLibrarySpans: [Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans] = [] public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil } /// A collection of Spans produced by an InstrumentationLibrary. @@ -70,27 +68,25 @@ public struct Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans { // methods supported on all messages. /// The instrumentation library information for the spans in this message. - /// If this field is not set then no library info is known. + /// Semantically when InstrumentationLibrary isn't set, it is equivalent with + /// an empty instrumentation library name (unknown). public var instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary { - get {return _storage._instrumentationLibrary ?? Opentelemetry_Proto_Common_V1_InstrumentationLibrary()} - set {_uniqueStorage()._instrumentationLibrary = newValue} + get {return _instrumentationLibrary ?? Opentelemetry_Proto_Common_V1_InstrumentationLibrary()} + set {_instrumentationLibrary = newValue} } /// Returns true if `instrumentationLibrary` has been explicitly set. - public var hasInstrumentationLibrary: Bool {return _storage._instrumentationLibrary != nil} + public var hasInstrumentationLibrary: Bool {return self._instrumentationLibrary != nil} /// Clears the value of `instrumentationLibrary`. Subsequent reads from it will return its default value. - public mutating func clearInstrumentationLibrary() {_uniqueStorage()._instrumentationLibrary = nil} + public mutating func clearInstrumentationLibrary() {self._instrumentationLibrary = nil} /// A list of Spans that originate from an instrumentation library. - public var spans: [Opentelemetry_Proto_Trace_V1_Span] { - get {return _storage._spans} - set {_uniqueStorage()._spans = newValue} - } + public var spans: [Opentelemetry_Proto_Trace_V1_Span] = [] public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary? = nil } /// Span represents a single operation within a trace. Spans can be @@ -356,10 +352,10 @@ public struct Opentelemetry_Proto_Trace_V1_Span { /// A unique identifier of a trace that this linked span is part of. The ID is a /// 16-byte array. - public var traceID: Data = SwiftProtobuf.Internal.emptyData + public var traceID: Data = Data() /// A unique identifier for the linked span. The ID is an 8-byte array. - public var spanID: Data = SwiftProtobuf.Internal.emptyData + public var spanID: Data = Data() /// The trace_state associated with the link. public var traceState: String = String() @@ -583,63 +579,32 @@ extension Opentelemetry_Proto_Trace_V1_ResourceSpans: SwiftProtobuf.Message, Swi 2: .standard(proto: "instrumentation_library_spans"), ] - fileprivate class _StorageClass { - var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil - var _instrumentationLibrarySpans: [Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans] = [] - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _resource = source._resource - _instrumentationLibrarySpans = source._instrumentationLibrarySpans - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularMessageField(value: &_storage._resource) - case 2: try decoder.decodeRepeatedMessageField(value: &_storage._instrumentationLibrarySpans) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._resource) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.instrumentationLibrarySpans) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if !_storage._instrumentationLibrarySpans.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._instrumentationLibrarySpans, fieldNumber: 2) - } + if let v = self._resource { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.instrumentationLibrarySpans.isEmpty { + try visitor.visitRepeatedMessageField(value: self.instrumentationLibrarySpans, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Trace_V1_ResourceSpans, rhs: Opentelemetry_Proto_Trace_V1_ResourceSpans) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._resource != rhs_storage._resource {return false} - if _storage._instrumentationLibrarySpans != rhs_storage._instrumentationLibrarySpans {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._resource != rhs._resource {return false} + if lhs.instrumentationLibrarySpans != rhs.instrumentationLibrarySpans {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -652,63 +617,32 @@ extension Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans: SwiftProtobu 2: .same(proto: "spans"), ] - fileprivate class _StorageClass { - var _instrumentationLibrary: Opentelemetry_Proto_Common_V1_InstrumentationLibrary? = nil - var _spans: [Opentelemetry_Proto_Trace_V1_Span] = [] - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _instrumentationLibrary = source._instrumentationLibrary - _spans = source._spans - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeSingularMessageField(value: &_storage._instrumentationLibrary) - case 2: try decoder.decodeRepeatedMessageField(value: &_storage._spans) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._instrumentationLibrary) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.spans) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._instrumentationLibrary { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if !_storage._spans.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._spans, fieldNumber: 2) - } + if let v = self._instrumentationLibrary { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.spans.isEmpty { + try visitor.visitRepeatedMessageField(value: self.spans, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans, rhs: Opentelemetry_Proto_Trace_V1_InstrumentationLibrarySpans) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._instrumentationLibrary != rhs_storage._instrumentationLibrary {return false} - if _storage._spans != rhs_storage._spans {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._instrumentationLibrary != rhs._instrumentationLibrary {return false} + if lhs.spans != rhs.spans {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -735,10 +669,10 @@ extension Opentelemetry_Proto_Trace_V1_Span: SwiftProtobuf.Message, SwiftProtobu ] fileprivate class _StorageClass { - var _traceID: Data = SwiftProtobuf.Internal.emptyData - var _spanID: Data = SwiftProtobuf.Internal.emptyData + var _traceID: Data = Data() + var _spanID: Data = Data() var _traceState: String = String() - var _parentSpanID: Data = SwiftProtobuf.Internal.emptyData + var _parentSpanID: Data = Data() var _name: String = String() var _kind: Opentelemetry_Proto_Trace_V1_Span.SpanKind = .unspecified var _startTimeUnixNano: UInt64 = 0 @@ -785,22 +719,25 @@ extension Opentelemetry_Proto_Trace_V1_Span: SwiftProtobuf.Message, SwiftProtobu _ = _uniqueStorage() try withExtendedLifetime(_storage) { (_storage: _StorageClass) in while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularBytesField(value: &_storage._traceID) - case 2: try decoder.decodeSingularBytesField(value: &_storage._spanID) - case 3: try decoder.decodeSingularStringField(value: &_storage._traceState) - case 4: try decoder.decodeSingularBytesField(value: &_storage._parentSpanID) - case 5: try decoder.decodeSingularStringField(value: &_storage._name) - case 6: try decoder.decodeSingularEnumField(value: &_storage._kind) - case 7: try decoder.decodeSingularFixed64Field(value: &_storage._startTimeUnixNano) - case 8: try decoder.decodeSingularFixed64Field(value: &_storage._endTimeUnixNano) - case 9: try decoder.decodeRepeatedMessageField(value: &_storage._attributes) - case 10: try decoder.decodeSingularUInt32Field(value: &_storage._droppedAttributesCount) - case 11: try decoder.decodeRepeatedMessageField(value: &_storage._events) - case 12: try decoder.decodeSingularUInt32Field(value: &_storage._droppedEventsCount) - case 13: try decoder.decodeRepeatedMessageField(value: &_storage._links) - case 14: try decoder.decodeSingularUInt32Field(value: &_storage._droppedLinksCount) - case 15: try decoder.decodeSingularMessageField(value: &_storage._status) + case 1: try { try decoder.decodeSingularBytesField(value: &_storage._traceID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &_storage._spanID) }() + case 3: try { try decoder.decodeSingularStringField(value: &_storage._traceState) }() + case 4: try { try decoder.decodeSingularBytesField(value: &_storage._parentSpanID) }() + case 5: try { try decoder.decodeSingularStringField(value: &_storage._name) }() + case 6: try { try decoder.decodeSingularEnumField(value: &_storage._kind) }() + case 7: try { try decoder.decodeSingularFixed64Field(value: &_storage._startTimeUnixNano) }() + case 8: try { try decoder.decodeSingularFixed64Field(value: &_storage._endTimeUnixNano) }() + case 9: try { try decoder.decodeRepeatedMessageField(value: &_storage._attributes) }() + case 10: try { try decoder.decodeSingularUInt32Field(value: &_storage._droppedAttributesCount) }() + case 11: try { try decoder.decodeRepeatedMessageField(value: &_storage._events) }() + case 12: try { try decoder.decodeSingularUInt32Field(value: &_storage._droppedEventsCount) }() + case 13: try { try decoder.decodeRepeatedMessageField(value: &_storage._links) }() + case 14: try { try decoder.decodeSingularUInt32Field(value: &_storage._droppedLinksCount) }() + case 15: try { try decoder.decodeSingularMessageField(value: &_storage._status) }() default: break } } @@ -909,11 +846,14 @@ extension Opentelemetry_Proto_Trace_V1_Span.Event: SwiftProtobuf.Message, SwiftP public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) - case 2: try decoder.decodeSingularStringField(value: &self.name) - case 3: try decoder.decodeRepeatedMessageField(value: &self.attributes) - case 4: try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) + case 1: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) }() default: break } } @@ -957,12 +897,15 @@ extension Opentelemetry_Proto_Trace_V1_Span.Link: SwiftProtobuf.Message, SwiftPr public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularBytesField(value: &self.traceID) - case 2: try decoder.decodeSingularBytesField(value: &self.spanID) - case 3: try decoder.decodeSingularStringField(value: &self.traceState) - case 4: try decoder.decodeRepeatedMessageField(value: &self.attributes) - case 5: try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) + case 1: try { try decoder.decodeSingularBytesField(value: &self.traceID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.spanID) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.traceState) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() + case 5: try { try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) }() default: break } } @@ -1008,10 +951,13 @@ extension Opentelemetry_Proto_Trace_V1_Status: SwiftProtobuf.Message, SwiftProto public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularEnumField(value: &self.deprecatedCode) - case 2: try decoder.decodeSingularStringField(value: &self.message) - case 3: try decoder.decodeSingularEnumField(value: &self.code) + case 1: try { try decoder.decodeSingularEnumField(value: &self.deprecatedCode) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.message) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self.code) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/trace_config.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/trace_config.pb.swift index e0703f44..58119a02 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/trace_config.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/trace_config.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/trace/v1/trace_config.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -41,64 +42,46 @@ public struct Opentelemetry_Proto_Trace_V1_TraceConfig { // methods supported on all messages. /// The global default sampler used to make decisions on span sampling. - public var sampler: OneOf_Sampler? { - get {return _storage._sampler} - set {_uniqueStorage()._sampler = newValue} - } + public var sampler: Opentelemetry_Proto_Trace_V1_TraceConfig.OneOf_Sampler? = nil public var constantSampler: Opentelemetry_Proto_Trace_V1_ConstantSampler { get { - if case .constantSampler(let v)? = _storage._sampler {return v} + if case .constantSampler(let v)? = sampler {return v} return Opentelemetry_Proto_Trace_V1_ConstantSampler() } - set {_uniqueStorage()._sampler = .constantSampler(newValue)} + set {sampler = .constantSampler(newValue)} } public var traceIDRatioBased: Opentelemetry_Proto_Trace_V1_TraceIdRatioBased { get { - if case .traceIDRatioBased(let v)? = _storage._sampler {return v} + if case .traceIDRatioBased(let v)? = sampler {return v} return Opentelemetry_Proto_Trace_V1_TraceIdRatioBased() } - set {_uniqueStorage()._sampler = .traceIDRatioBased(newValue)} + set {sampler = .traceIDRatioBased(newValue)} } public var rateLimitingSampler: Opentelemetry_Proto_Trace_V1_RateLimitingSampler { get { - if case .rateLimitingSampler(let v)? = _storage._sampler {return v} + if case .rateLimitingSampler(let v)? = sampler {return v} return Opentelemetry_Proto_Trace_V1_RateLimitingSampler() } - set {_uniqueStorage()._sampler = .rateLimitingSampler(newValue)} + set {sampler = .rateLimitingSampler(newValue)} } /// The global default max number of attributes per span. - public var maxNumberOfAttributes: Int64 { - get {return _storage._maxNumberOfAttributes} - set {_uniqueStorage()._maxNumberOfAttributes = newValue} - } + public var maxNumberOfAttributes: Int64 = 0 /// The global default max number of annotation events per span. - public var maxNumberOfTimedEvents: Int64 { - get {return _storage._maxNumberOfTimedEvents} - set {_uniqueStorage()._maxNumberOfTimedEvents = newValue} - } + public var maxNumberOfTimedEvents: Int64 = 0 /// The global default max number of attributes per timed event. - public var maxNumberOfAttributesPerTimedEvent: Int64 { - get {return _storage._maxNumberOfAttributesPerTimedEvent} - set {_uniqueStorage()._maxNumberOfAttributesPerTimedEvent = newValue} - } + public var maxNumberOfAttributesPerTimedEvent: Int64 = 0 /// The global default max number of link entries per span. - public var maxNumberOfLinks: Int64 { - get {return _storage._maxNumberOfLinks} - set {_uniqueStorage()._maxNumberOfLinks = newValue} - } + public var maxNumberOfLinks: Int64 = 0 /// The global default max number of attributes per span. - public var maxNumberOfAttributesPerLink: Int64 { - get {return _storage._maxNumberOfAttributesPerLink} - set {_uniqueStorage()._maxNumberOfAttributesPerLink = newValue} - } + public var maxNumberOfAttributesPerLink: Int64 = 0 public var unknownFields = SwiftProtobuf.UnknownStorage() @@ -110,10 +93,22 @@ public struct Opentelemetry_Proto_Trace_V1_TraceConfig { #if !swift(>=4.1) public static func ==(lhs: Opentelemetry_Proto_Trace_V1_TraceConfig.OneOf_Sampler, rhs: Opentelemetry_Proto_Trace_V1_TraceConfig.OneOf_Sampler) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch (lhs, rhs) { - case (.constantSampler(let l), .constantSampler(let r)): return l == r - case (.traceIDRatioBased(let l), .traceIDRatioBased(let r)): return l == r - case (.rateLimitingSampler(let l), .rateLimitingSampler(let r)): return l == r + case (.constantSampler, .constantSampler): return { + guard case .constantSampler(let l) = lhs, case .constantSampler(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.traceIDRatioBased, .traceIDRatioBased): return { + guard case .traceIDRatioBased(let l) = lhs, case .traceIDRatioBased(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rateLimitingSampler, .rateLimitingSampler): return { + guard case .rateLimitingSampler(let l) = lhs, case .rateLimitingSampler(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -121,8 +116,6 @@ public struct Opentelemetry_Proto_Trace_V1_TraceConfig { } public init() {} - - fileprivate var _storage = _StorageClass.defaultInstance } /// Sampler that always makes a constant decision on span sampling. @@ -232,120 +225,93 @@ extension Opentelemetry_Proto_Trace_V1_TraceConfig: SwiftProtobuf.Message, Swift 8: .standard(proto: "max_number_of_attributes_per_link"), ] - fileprivate class _StorageClass { - var _sampler: Opentelemetry_Proto_Trace_V1_TraceConfig.OneOf_Sampler? - var _maxNumberOfAttributes: Int64 = 0 - var _maxNumberOfTimedEvents: Int64 = 0 - var _maxNumberOfAttributesPerTimedEvent: Int64 = 0 - var _maxNumberOfLinks: Int64 = 0 - var _maxNumberOfAttributesPerLink: Int64 = 0 - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _sampler = source._sampler - _maxNumberOfAttributes = source._maxNumberOfAttributes - _maxNumberOfTimedEvents = source._maxNumberOfTimedEvents - _maxNumberOfAttributesPerTimedEvent = source._maxNumberOfAttributesPerTimedEvent - _maxNumberOfLinks = source._maxNumberOfLinks - _maxNumberOfAttributesPerLink = source._maxNumberOfAttributesPerLink - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: - var v: Opentelemetry_Proto_Trace_V1_ConstantSampler? - if let current = _storage._sampler { - try decoder.handleConflictingOneOf() - if case .constantSampler(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._sampler = .constantSampler(v)} - case 2: - var v: Opentelemetry_Proto_Trace_V1_TraceIdRatioBased? - if let current = _storage._sampler { - try decoder.handleConflictingOneOf() - if case .traceIDRatioBased(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._sampler = .traceIDRatioBased(v)} - case 3: - var v: Opentelemetry_Proto_Trace_V1_RateLimitingSampler? - if let current = _storage._sampler { - try decoder.handleConflictingOneOf() - if case .rateLimitingSampler(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v {_storage._sampler = .rateLimitingSampler(v)} - case 4: try decoder.decodeSingularInt64Field(value: &_storage._maxNumberOfAttributes) - case 5: try decoder.decodeSingularInt64Field(value: &_storage._maxNumberOfTimedEvents) - case 6: try decoder.decodeSingularInt64Field(value: &_storage._maxNumberOfAttributesPerTimedEvent) - case 7: try decoder.decodeSingularInt64Field(value: &_storage._maxNumberOfLinks) - case 8: try decoder.decodeSingularInt64Field(value: &_storage._maxNumberOfAttributesPerLink) - default: break + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { + var v: Opentelemetry_Proto_Trace_V1_ConstantSampler? + if let current = self.sampler { + try decoder.handleConflictingOneOf() + if case .constantSampler(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.sampler = .constantSampler(v)} + }() + case 2: try { + var v: Opentelemetry_Proto_Trace_V1_TraceIdRatioBased? + if let current = self.sampler { + try decoder.handleConflictingOneOf() + if case .traceIDRatioBased(let m) = current {v = m} } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.sampler = .traceIDRatioBased(v)} + }() + case 3: try { + var v: Opentelemetry_Proto_Trace_V1_RateLimitingSampler? + if let current = self.sampler { + try decoder.handleConflictingOneOf() + if case .rateLimitingSampler(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v {self.sampler = .rateLimitingSampler(v)} + }() + case 4: try { try decoder.decodeSingularInt64Field(value: &self.maxNumberOfAttributes) }() + case 5: try { try decoder.decodeSingularInt64Field(value: &self.maxNumberOfTimedEvents) }() + case 6: try { try decoder.decodeSingularInt64Field(value: &self.maxNumberOfAttributesPerTimedEvent) }() + case 7: try { try decoder.decodeSingularInt64Field(value: &self.maxNumberOfLinks) }() + case 8: try { try decoder.decodeSingularInt64Field(value: &self.maxNumberOfAttributesPerLink) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - switch _storage._sampler { - case .constantSampler(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - case .traceIDRatioBased(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - case .rateLimitingSampler(let v)?: - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - case nil: break - } - if _storage._maxNumberOfAttributes != 0 { - try visitor.visitSingularInt64Field(value: _storage._maxNumberOfAttributes, fieldNumber: 4) - } - if _storage._maxNumberOfTimedEvents != 0 { - try visitor.visitSingularInt64Field(value: _storage._maxNumberOfTimedEvents, fieldNumber: 5) - } - if _storage._maxNumberOfAttributesPerTimedEvent != 0 { - try visitor.visitSingularInt64Field(value: _storage._maxNumberOfAttributesPerTimedEvent, fieldNumber: 6) - } - if _storage._maxNumberOfLinks != 0 { - try visitor.visitSingularInt64Field(value: _storage._maxNumberOfLinks, fieldNumber: 7) - } - if _storage._maxNumberOfAttributesPerLink != 0 { - try visitor.visitSingularInt64Field(value: _storage._maxNumberOfAttributesPerLink, fieldNumber: 8) - } + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch self.sampler { + case .constantSampler?: try { + guard case .constantSampler(let v)? = self.sampler else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + }() + case .traceIDRatioBased?: try { + guard case .traceIDRatioBased(let v)? = self.sampler else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case .rateLimitingSampler?: try { + guard case .rateLimitingSampler(let v)? = self.sampler else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case nil: break + } + if self.maxNumberOfAttributes != 0 { + try visitor.visitSingularInt64Field(value: self.maxNumberOfAttributes, fieldNumber: 4) + } + if self.maxNumberOfTimedEvents != 0 { + try visitor.visitSingularInt64Field(value: self.maxNumberOfTimedEvents, fieldNumber: 5) + } + if self.maxNumberOfAttributesPerTimedEvent != 0 { + try visitor.visitSingularInt64Field(value: self.maxNumberOfAttributesPerTimedEvent, fieldNumber: 6) + } + if self.maxNumberOfLinks != 0 { + try visitor.visitSingularInt64Field(value: self.maxNumberOfLinks, fieldNumber: 7) + } + if self.maxNumberOfAttributesPerLink != 0 { + try visitor.visitSingularInt64Field(value: self.maxNumberOfAttributesPerLink, fieldNumber: 8) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Opentelemetry_Proto_Trace_V1_TraceConfig, rhs: Opentelemetry_Proto_Trace_V1_TraceConfig) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._sampler != rhs_storage._sampler {return false} - if _storage._maxNumberOfAttributes != rhs_storage._maxNumberOfAttributes {return false} - if _storage._maxNumberOfTimedEvents != rhs_storage._maxNumberOfTimedEvents {return false} - if _storage._maxNumberOfAttributesPerTimedEvent != rhs_storage._maxNumberOfAttributesPerTimedEvent {return false} - if _storage._maxNumberOfLinks != rhs_storage._maxNumberOfLinks {return false} - if _storage._maxNumberOfAttributesPerLink != rhs_storage._maxNumberOfAttributesPerLink {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.sampler != rhs.sampler {return false} + if lhs.maxNumberOfAttributes != rhs.maxNumberOfAttributes {return false} + if lhs.maxNumberOfTimedEvents != rhs.maxNumberOfTimedEvents {return false} + if lhs.maxNumberOfAttributesPerTimedEvent != rhs.maxNumberOfAttributesPerTimedEvent {return false} + if lhs.maxNumberOfLinks != rhs.maxNumberOfLinks {return false} + if lhs.maxNumberOfAttributesPerLink != rhs.maxNumberOfAttributesPerLink {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -359,8 +325,11 @@ extension Opentelemetry_Proto_Trace_V1_ConstantSampler: SwiftProtobuf.Message, S public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularEnumField(value: &self.decision) + case 1: try { try decoder.decodeSingularEnumField(value: &self.decision) }() default: break } } @@ -396,8 +365,11 @@ extension Opentelemetry_Proto_Trace_V1_TraceIdRatioBased: SwiftProtobuf.Message, public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularDoubleField(value: &self.samplingRatio) + case 1: try { try decoder.decodeSingularDoubleField(value: &self.samplingRatio) }() default: break } } @@ -425,8 +397,11 @@ extension Opentelemetry_Proto_Trace_V1_RateLimitingSampler: SwiftProtobuf.Messag public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularInt64Field(value: &self.qps) + case 1: try { try decoder.decodeSingularInt64Field(value: &self.qps) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.grpc.swift index 6e4eb5f1..85fe79b5 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.grpc.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.grpc.swift @@ -20,74 +20,120 @@ // See the License for the specific language governing permissions and // limitations under the License. // -import Foundation import GRPC import NIO -import NIOHTTP1 import SwiftProtobuf -/// Usage: instantiate Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient, then call methods of this protocol to make API calls. -public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol { - func export(_ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, callOptions: CallOptions?) -> UnaryCall +/// Service that can be used to push spans between one Application instrumented with +/// OpenTelemetry and an collector, or between an collector and a central collector (in this +/// case spans are sent/received to/from multiple Applications). +/// +/// Usage: instantiate `Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient`, then call methods of this protocol to make API calls. +public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol: GRPCClient { + var serviceName: String { get } + var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? { get } + + func export( + _ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, + callOptions: CallOptions? + ) -> UnaryCall +} + +extension Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol { + public var serviceName: String { + return "opentelemetry.proto.collector.trace.v1.TraceService" + } + + /// For performance reasons, it is recommended to keep this RPC + /// alive for the entire life of the application. + /// + /// - Parameters: + /// - request: Request to send to Export. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func export( + _ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: "/opentelemetry.proto.collector.trace.v1.TraceService/Export", + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExportInterceptors() ?? [] + ) + } +} + +public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol { + + /// - Returns: Interceptors to use when invoking 'export'. + func makeExportInterceptors() -> [ClientInterceptor] } -public final class Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient: GRPCClient, Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol { +public final class Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol { public let channel: GRPCChannel public var defaultCallOptions: CallOptions + public var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? /// Creates a client for the opentelemetry.proto.collector.trace.v1.TraceService service. /// /// - Parameters: /// - channel: `GRPCChannel` to the service host. /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. - public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? = nil + ) { self.channel = channel self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors } - - /// For performance reasons, it is recommended to keep this RPC - /// alive for the entire life of the application. - /// - /// - Parameters: - /// - request: Request to send to Export. - /// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`. - /// - Returns: A `UnaryCall` with futures for the metadata, status and response. - public func export(_ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, callOptions: CallOptions? = nil) -> UnaryCall { - return self.makeUnaryCall(path: "/opentelemetry.proto.collector.trace.v1.TraceService/Export", - request: request, - callOptions: callOptions ?? self.defaultCallOptions) - } - } +/// Service that can be used to push spans between one Application instrumented with +/// OpenTelemetry and an collector, or between an collector and a central collector (in this +/// case spans are sent/received to/from multiple Applications). +/// /// To build a server, implement a class that conforms to this protocol. public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceProvider: CallHandlerProvider { + var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerInterceptorFactoryProtocol? { get } + /// For performance reasons, it is recommended to keep this RPC /// alive for the entire life of the application. func export(request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, context: StatusOnlyCallContext) -> EventLoopFuture } extension Opentelemetry_Proto_Collector_Trace_V1_TraceServiceProvider { - public var serviceName: String { return "opentelemetry.proto.collector.trace.v1.TraceService" } + public var serviceName: Substring { return "opentelemetry.proto.collector.trace.v1.TraceService" } /// Determines, calls and returns the appropriate request handler, depending on the request's method. /// Returns nil for methods not handled by this service. - public func handleMethod(_ methodName: String, callHandlerContext: CallHandlerContext) -> GRPCCallHandler? { - switch methodName { + public func handle( + method name: Substring, + context: CallHandlerContext + ) -> GRPCServerHandlerProtocol? { + switch name { case "Export": - return UnaryCallHandler(callHandlerContext: callHandlerContext) { context in - return { request in - self.export(request: request, context: context) - } - } + return UnaryServerHandler( + context: context, + requestDeserializer: ProtobufDeserializer(), + responseSerializer: ProtobufSerializer(), + interceptors: self.interceptors?.makeExportInterceptors() ?? [], + userFunction: self.export(request:context:) + ) - default: return nil + default: + return nil } } } +public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerInterceptorFactoryProtocol { -// Provides conformance to `GRPCPayload` -extension Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest: GRPCProtobufPayload {} -extension Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse: GRPCProtobufPayload {} + /// - Returns: Interceptors to use when handling 'export'. + /// Defaults to calling `self.makeInterceptors()`. + func makeExportInterceptors() -> [ServerInterceptor] +} diff --git a/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.pb.swift index 5ae5594b..3dc5db84 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.pb.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/proto/trace_service.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: opentelemetry/proto/collector/trace/v1/trace_service.proto @@ -26,7 +27,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -72,8 +73,11 @@ extension Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest: Swif public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeRepeatedMessageField(value: &self.resourceSpans) + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.resourceSpans) }() default: break } } diff --git a/Sources/Exporters/OpenTelemetryProtocol/trace/OtlpTraceExporter.swift b/Sources/Exporters/OpenTelemetryProtocol/trace/OtlpTraceExporter.swift index d18627c9..b905e89a 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/trace/OtlpTraceExporter.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/trace/OtlpTraceExporter.swift @@ -15,18 +15,19 @@ import Foundation import GRPC +import NIO import OpenTelemetryApi import OpenTelemetrySdk public class OtlpTraceExporter: SpanExporter { let channel: GRPCChannel let traceClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient - let deadlineMS: Int + let timeoutNanos: Int64 - public init(channel: GRPCChannel, deadlineMS: Int = 0) { + public init(channel: GRPCChannel, timeoutNanos: Int64 = 0) { self.channel = channel traceClient = Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient(channel: channel) - self.deadlineMS = deadlineMS + self.timeoutNanos = timeoutNanos } public func export(spans: [SpanData]) -> SpanExporterResultCode { @@ -34,15 +35,15 @@ public class OtlpTraceExporter: SpanExporter { $0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans) } - if deadlineMS > 0 { - traceClient.defaultCallOptions.timeout = try! GRPCTimeout.milliseconds(deadlineMS) + if timeoutNanos > 0 { + traceClient.defaultCallOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(timeoutNanos)) } let export = traceClient.export(exportRequest) do { // wait() on the response to stop the program from exiting before the response is received. - _ = try export.response.wait() + _ = try export.response.wait() return .success } catch { return .failure diff --git a/Sources/Exporters/OpenTelemetryProtocol/trace/SpanAdapter.swift b/Sources/Exporters/OpenTelemetryProtocol/trace/SpanAdapter.swift index 8bafe7f6..99578658 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/trace/SpanAdapter.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/trace/SpanAdapter.swift @@ -43,9 +43,9 @@ struct SpanAdapter { private static func groupByResourceAndLibrary(spanDataList: [SpanData]) -> [Resource: [InstrumentationLibraryInfo: [Opentelemetry_Proto_Trace_V1_Span]]] { var result = [Resource: [InstrumentationLibraryInfo: [Opentelemetry_Proto_Trace_V1_Span]]]() spanDataList.forEach { - result[$0.resource,default:[InstrumentationLibraryInfo:[Opentelemetry_Proto_Trace_V1_Span]]()][$0.instrumentationLibraryInfo,default:[Opentelemetry_Proto_Trace_V1_Span]()] + result[$0.resource, default: [InstrumentationLibraryInfo: [Opentelemetry_Proto_Trace_V1_Span]]()][$0.instrumentationLibraryInfo, default: [Opentelemetry_Proto_Trace_V1_Span]()] .append(toProtoSpan(spanData: $0)) - } + } return result } @@ -114,16 +114,14 @@ struct SpanAdapter { static func toStatusProto(status: Status) -> Opentelemetry_Proto_Trace_V1_Status { var statusProto = Opentelemetry_Proto_Trace_V1_Status() - switch status.statusCode { + switch status { case .ok: statusProto.code = .ok case .unset: statusProto.code = .unset - case .error: + case .error(let description): statusProto.code = .error - } - if let desc = status.statusDescription { - statusProto.message = desc + statusProto.message = description } return statusProto } diff --git a/Sources/Exporters/OpenTelemetryProtocol/trace/utils/TraceProtoUtils.swift b/Sources/Exporters/OpenTelemetryProtocol/trace/utils/TraceProtoUtils.swift index e589e7a1..9610ddee 100644 --- a/Sources/Exporters/OpenTelemetryProtocol/trace/utils/TraceProtoUtils.swift +++ b/Sources/Exporters/OpenTelemetryProtocol/trace/utils/TraceProtoUtils.swift @@ -31,18 +31,17 @@ struct TraceProtoUtils { return traceIdData } - static func traceConfigFromProto(protoTraceConfig: Opentelemetry_Proto_Trace_V1_TraceConfig) -> TraceConfig { - let traceConfig = TraceConfig() - traceConfig.settingSampler(fromProtoSampler(protoTraceConfig: protoTraceConfig)) - .settingMaxNumberOfAttributes(Int(protoTraceConfig.maxNumberOfAttributes)) - .settingMaxNumberOfEvents(Int(protoTraceConfig.maxNumberOfTimedEvents)) - .settingMaxNumberOfLinks(Int(protoTraceConfig.maxNumberOfLinks)) - .settingMaxNumberOfAttributesPerEvent(Int(protoTraceConfig.maxNumberOfAttributesPerTimedEvent)) - .settingMaxNumberOfAttributesPerLink(Int(protoTraceConfig.maxNumberOfAttributesPerLink)) - return traceConfig + static func spanLimitsFromProto(protoTraceConfig: Opentelemetry_Proto_Trace_V1_TraceConfig) -> SpanLimits { + let spanLimits = SpanLimits() + spanLimits.settingAttributeCountLimit(UInt(protoTraceConfig.maxNumberOfAttributes)) + .settingEventCountLimit(UInt(protoTraceConfig.maxNumberOfTimedEvents)) + .settingLinkCountLimit(UInt(protoTraceConfig.maxNumberOfLinks)) + .settingAttributePerEventCountLimit(UInt(protoTraceConfig.maxNumberOfAttributesPerTimedEvent)) + .settingAttributePerLinkCountLimit(UInt(protoTraceConfig.maxNumberOfAttributesPerLink)) + return spanLimits } - static func fromProtoSampler( protoTraceConfig: Opentelemetry_Proto_Trace_V1_TraceConfig) -> Sampler { + static func fromProtoSampler(protoTraceConfig: Opentelemetry_Proto_Trace_V1_TraceConfig) -> Sampler { guard protoTraceConfig.sampler != nil else { return Samplers.alwaysOff } @@ -56,15 +55,15 @@ struct TraceProtoUtils { return Samplers.alwaysOn case .alwaysParent: // TODO: add support for alwaysParent - break; - case .UNRECOGNIZED(_): - break; + break + case .UNRECOGNIZED: + break } case .traceIDRatioBased(let ratio): - return Samplers.probability(probability: ratio.samplingRatio) - case .rateLimitingSampler(_): + return Samplers.traceIdRatio(ratio: ratio.samplingRatio) + case .rateLimitingSampler: // TODO: add support for RateLimiting Sampler - break; + break } return Samplers.alwaysOff } diff --git a/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift b/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift index 6fe2ae7f..15a70349 100644 --- a/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift +++ b/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift @@ -77,9 +77,9 @@ struct ZipkinConversionExtension { let status = otelSpan.status if status.isOk { - attributeEnumerationState.tags[statusCode] = "\(status.statusCode)".capitalized - if status.statusDescription != nil { - attributeEnumerationState.tags[statusDescription] = status.statusDescription + attributeEnumerationState.tags[statusCode] = "\(status.name)".capitalized + if case let Status.error(description) = status { + attributeEnumerationState.tags[statusDescription] = description } } @@ -132,8 +132,7 @@ struct ZipkinConversionExtension { } private static func processAttributes(state: inout AttributeEnumerationState, key: String, value: AttributeValue) { - if case let .string(val) = value, - let priority = remoteEndpointServiceNameKeyResolution[key] { + if case let .string(val) = value, let priority = remoteEndpointServiceNameKeyResolution[key] { if state.RemoteEndpointServiceName == nil || priority < state.remoteEndpointServiceNamePriority ?? 5 { state.RemoteEndpointServiceName = val state.remoteEndpointServiceNamePriority = priority diff --git a/Sources/OpenTelemetryApi/Trace/DefaultTracer.swift b/Sources/OpenTelemetryApi/Trace/DefaultTracer.swift index 324207f9..2eb155f2 100644 --- a/Sources/OpenTelemetryApi/Trace/DefaultTracer.swift +++ b/Sources/OpenTelemetryApi/Trace/DefaultTracer.swift @@ -19,7 +19,7 @@ import Foundation public class DefaultTracer: Tracer { public static var instance = DefaultTracer() - private init() {} + public init() {} public var activeSpan: Span? { return ContextUtils.getCurrentSpan() diff --git a/Sources/OpenTelemetryApi/Trace/Span.swift b/Sources/OpenTelemetryApi/Trace/Span.swift index 282c8f13..60b666e6 100644 --- a/Sources/OpenTelemetryApi/Trace/Span.swift +++ b/Sources/OpenTelemetryApi/Trace/Span.swift @@ -82,56 +82,56 @@ public protocol Span: AnyObject, CustomStringConvertible { func end(time: Date) } -extension Span { - public func hash(into hasher: inout Hasher) { +public extension Span { + func hash(into hasher: inout Hasher) { hasher.combine(context.spanId) } - public static func == (lhs: Span, rhs: Span) -> Bool { + static func == (lhs: Span, rhs: Span) -> Bool { return lhs.context.spanId == rhs.context.spanId } } -extension Span { - public func setAttribute(key: String, value: String) { +public extension Span { + func setAttribute(key: String, value: String) { return setAttribute(key: key, value: AttributeValue.string(value)) } - public func setAttribute(key: String, value: Int) { + func setAttribute(key: String, value: Int) { return setAttribute(key: key, value: AttributeValue.int(value)) } - public func setAttribute(key: String, value: Double) { + func setAttribute(key: String, value: Double) { return setAttribute(key: key, value: AttributeValue.double(value)) } - public func setAttribute(key: String, value: Bool) { + func setAttribute(key: String, value: Bool) { return setAttribute(key: key, value: AttributeValue.bool(value)) } - public func setAttribute(key: SemanticAttributes, value: String) { + func setAttribute(key: SemanticAttributes, value: String) { return setAttribute(key: key.rawValue, value: AttributeValue.string(value)) } - public func setAttribute(key: SemanticAttributes, value: Int) { + func setAttribute(key: SemanticAttributes, value: Int) { return setAttribute(key: key.rawValue, value: AttributeValue.int(value)) } - public func setAttribute(key: SemanticAttributes, value: Double) { + func setAttribute(key: SemanticAttributes, value: Double) { return setAttribute(key: key.rawValue, value: AttributeValue.double(value)) } - public func setAttribute(key: SemanticAttributes, value: Bool) { + func setAttribute(key: SemanticAttributes, value: Bool) { return setAttribute(key: key.rawValue, value: AttributeValue.bool(value)) } } -extension Span { +public extension Span { /// Helper method that populates span properties from host and port /// - Parameters: /// - hostName: Hostr name. /// - port: Port number. - public func putHttpHostAttribute(string hostName: String, int port: Int) { + func putHttpHostAttribute(string hostName: String, int port: Int) { if port == 80 || port == 443 { setAttribute(key: .httpHost, value: hostName) } else { @@ -143,17 +143,17 @@ extension Span { /// - Parameters: /// - statusCode: Http status code. /// - reasonPhrase: Http reason phrase. - public func putHttpStatusCode(statusCode: Int, reasonPhrase: String) { + func putHttpStatusCode(statusCode: Int, reasonPhrase: String) { setAttribute(key: .httpStatusCode, value: statusCode) - var newStatus: Status = .ok + var newStatus: Status switch statusCode { case 200 ..< 400: newStatus = .ok case 400 ..< 600: - newStatus = .error + newStatus = .error(description: description) default: newStatus = .unset } - status = newStatus.withDescription(description: reasonPhrase) + status = newStatus } } diff --git a/Sources/OpenTelemetryApi/Trace/SpanBuilder.swift b/Sources/OpenTelemetryApi/Trace/SpanBuilder.swift index d17bd972..fe526013 100644 --- a/Sources/OpenTelemetryApi/Trace/SpanBuilder.swift +++ b/Sources/OpenTelemetryApi/Trace/SpanBuilder.swift @@ -65,14 +65,6 @@ public protocol SpanBuilder: class { /// - attributes: the attributes of the Link @discardableResult func addLink(spanContext: SpanContext, attributes: [String: AttributeValue]) -> Self - /// Adds a Link to the newly created Span. - /// - /// Links are used to link Spans in different traces. Used (for example) in batching - /// operations, where a single batch handler processes multiple requests from different traces or - /// the same trace. - /// - Parameter link: the Link to be added. -// @discardableResult func addLink(_ link: Link) -> Self - /// Sets an attribute to the newly created Span. If SpanBuilder previously /// contained a mapping for the key, the old value is replaced by the specified value. /// - Parameters: @@ -128,24 +120,20 @@ public protocol SpanBuilder: class { func startSpan() -> Span } -extension SpanBuilder { - @discardableResult public func setAttribute(key: String, value: String) -> Self { +public extension SpanBuilder { + @discardableResult func setAttribute(key: String, value: String) -> Self { return setAttribute(key: key, value: AttributeValue.string(value)) } - @discardableResult public func setAttribute(key: String, value: Int) -> Self { + @discardableResult func setAttribute(key: String, value: Int) -> Self { return setAttribute(key: key, value: AttributeValue.int(value)) } - @discardableResult public func setAttribute(key: String, value: Double) -> Self { + @discardableResult func setAttribute(key: String, value: Double) -> Self { return setAttribute(key: key, value: AttributeValue.double(value)) } - @discardableResult public func setAttribute(key: String, value: Bool) -> Self { + @discardableResult func setAttribute(key: String, value: Bool) -> Self { return setAttribute(key: key, value: AttributeValue.bool(value)) } - -// @discardableResult public func setStartTimestamp(timestamp: Date) -> Self { -// return setStartTimestamp(timestamp: UInt64(timestamp.timeIntervalSince1970.toNanoseconds) ) -// } } diff --git a/Sources/OpenTelemetryApi/Trace/Status.swift b/Sources/OpenTelemetryApi/Trace/Status.swift index 37758e7f..9cc79f3a 100644 --- a/Sources/OpenTelemetryApi/Trace/Status.swift +++ b/Sources/OpenTelemetryApi/Trace/Status.swift @@ -17,60 +17,56 @@ import Foundation /// The set of canonical status codes. If new codes are added over time they must choose a numerical /// value that does not collide with any previously used value. -public struct Status: Equatable { - /// The set of canonical status codes. If new codes are added over time they must choose a - /// numerical value that does not collide with any previously used value. - public enum StatusCode: Int { - /// The operation has been validated by an Application developers or Operator to have completed successfully. - case ok = 0 - /// The default status. - case unset = 1 - /// The operation contains an error. - case error = 2 - } - - // A pseudo-enum of Status instances mapped 1:1 with values in StatusCode. This simplifies - // construction patterns for derived instances of Status. - - /// The default status. - public static let unset = Status(statusCode: StatusCode.unset) +public enum Status: Equatable { /// The operation has been validated by an Application developers or Operator to have completed successfully. - public static let ok = Status(statusCode: StatusCode.ok) + case ok + /// The default status. + case unset /// The operation contains an error. - public static let error = Status(statusCode: StatusCode.error) + case error(description: String) - - public private(set) var statusCode: StatusCode - // An additional error message. - public private(set) var statusDescription: String? - - private init(statusCode: StatusCode, description: String? = nil) { - self.statusCode = statusCode - statusDescription = description + /// True if this Status is OK + public var isOk: Bool { + return self == .ok } - /// Creates a derived instance of Status with the given description. - /// - Parameter description: the new description of the Status - public func withDescription(description: String?) -> Status { - if statusDescription == description { - return self + /// True if this Status is an Error + public var isError: Bool { + if case .error = self { + return true } - return Status(statusCode: statusCode, description: description) + return false } - /// True if this Status is OK - public var isOk: Bool { - return StatusCode.ok == statusCode + public var name: String { + switch self { + case .ok: + return "ok" + case .unset: + return "unset" + case .error(description: _): + return "error" + } } - /// True if this Status is an Error - public var isError: Bool { - return StatusCode.error == statusCode + public var code: Int { + switch self { + case .ok: + return 0 + case .unset: + return 1 + case .error(description: _): + return 2 + } } } extension Status: CustomStringConvertible { public var description: String { - return "Status{statusCode=\(statusCode), description=\(statusDescription ?? "")" + if case let Status.error(description) = self { + return "Status{statusCode=\(name), description=\(description)}" + } else { + return "Status{statusCode=\(name)}" + } } } diff --git a/Sources/OpenTelemetryApi/Trace/TraceState.swift b/Sources/OpenTelemetryApi/Trace/TraceState.swift index 42782915..1060625b 100644 --- a/Sources/OpenTelemetryApi/Trace/TraceState.swift +++ b/Sources/OpenTelemetryApi/Trace/TraceState.swift @@ -49,7 +49,7 @@ public struct TraceState: Equatable { /// - Parameters: /// - key: the key for the Entry to be added. /// - value: the value for the Entry to be added. - public mutating func set(key: String, value: String) { + internal mutating func set(key: String, value: String) { // Initially create the Entry to validate input. guard let entry = Entry(key: key, value: value) else { return } if entries.contains(where: { $0.key == entry.key }) { @@ -72,7 +72,7 @@ public struct TraceState: Equatable { /// Removes the Entry that has the given key if it is present. /// - Parameter key: the key for the Entry to be removed. - public mutating func remove(key: String) { + internal mutating func remove(key: String) { if let index = entries.firstIndex(where: { $0.key == key }) { entries.remove(at: index) } diff --git a/Sources/OpenTelemetrySdk/Trace/Config/TraceConfig.swift b/Sources/OpenTelemetrySdk/Trace/Config/TraceConfig.swift deleted file mode 100644 index f262427c..00000000 --- a/Sources/OpenTelemetrySdk/Trace/Config/TraceConfig.swift +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2020, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -import OpenTelemetryApi - -/// Struct that holds global trace parameters. -public struct TraceConfig: Equatable { - // These values are the default values for all the global parameters. - // TODO: decide which default sampler to use - - /// Returns the global default Sampler which is used when constructing a new Span - public private(set) var sampler: Sampler = Samplers.alwaysOn - - /// The global default max number of attributes perSpan. - public private(set) var maxNumberOfAttributes: Int = 1000 { - didSet { - maxNumberOfAttributes < 0 ? maxNumberOfAttributes = 0 : Void() - } - } - - /// the global default max number of Events per Span. - public private(set) var maxNumberOfEvents: Int = 1000 { - didSet { - maxNumberOfEvents < 0 ? maxNumberOfEvents = 0 : Void() - } - } - - /// the global default max number of Link entries per Span. - public private(set) var maxNumberOfLinks: Int = 1000 { - didSet { - maxNumberOfLinks < 0 ? maxNumberOfLinks = 0 : Void() - } - } - - /// the global default max number of attributes per Event. - public private(set) var maxNumberOfAttributesPerEvent: Int = 32 { - didSet { - maxNumberOfAttributesPerEvent < 0 ? maxNumberOfAttributesPerEvent = 0 : Void() - } - } - - /// the global default max number of attributes per Link. - public private(set) var maxNumberOfAttributesPerLink: Int = 32 { - didSet { - maxNumberOfAttributesPerLink < 0 ? maxNumberOfAttributesPerLink = 0 : Void() - } - } - - /// Returns the defaultTraceConfig. - public init() { - } - - @discardableResult public func settingSampler(_ sampler: Sampler) -> Self { - var traceConfig = self - traceConfig.sampler = sampler - return traceConfig - } - - @discardableResult public func settingMaxNumberOfAttributes(_ number: Int) -> Self { - var traceConfig = self - traceConfig.maxNumberOfAttributes = number - return traceConfig - } - - @discardableResult public func settingMaxNumberOfEvents(_ number: Int) -> Self { - var traceConfig = self - traceConfig.maxNumberOfEvents = number - return traceConfig - } - - @discardableResult public func settingMaxNumberOfLinks(_ number: Int) -> Self { - var traceConfig = self - traceConfig.maxNumberOfLinks = number - return traceConfig - } - - @discardableResult public func settingMaxNumberOfAttributesPerEvent(_ number: Int) -> Self { - var traceConfig = self - traceConfig.maxNumberOfAttributesPerEvent = number - return traceConfig - } - - @discardableResult public func settingMaxNumberOfAttributesPerLink(_ number: Int) -> Self { - var traceConfig = self - traceConfig.maxNumberOfAttributesPerLink = number - return traceConfig - } - - // Sets the global sampler probability - @discardableResult public func settingSamplerProbability(samplerProbability: Double) -> Self { - if samplerProbability >= 1 { - return settingSampler(Samplers.alwaysOn) - } else if samplerProbability <= 0 { - return settingSampler(Samplers.alwaysOff) - } else { - return settingSampler(Samplers.probability(probability: samplerProbability)) - } - } - - public static func == (lhs: TraceConfig, rhs: TraceConfig) -> Bool { - return lhs.sampler === rhs.sampler && - lhs.maxNumberOfAttributes == rhs.maxNumberOfAttributes && - lhs.maxNumberOfEvents == rhs.maxNumberOfEvents && - lhs.maxNumberOfLinks == rhs.maxNumberOfLinks && - lhs.maxNumberOfAttributesPerEvent == rhs.maxNumberOfAttributesPerEvent && - lhs.maxNumberOfAttributesPerLink == rhs.maxNumberOfAttributesPerLink - } -} diff --git a/Sources/OpenTelemetrySdk/Trace/Data/SpanData.swift b/Sources/OpenTelemetrySdk/Trace/Data/SpanData.swift index e02dcc2f..fff2a5b7 100644 --- a/Sources/OpenTelemetrySdk/Trace/Data/SpanData.swift +++ b/Sources/OpenTelemetrySdk/Trace/Data/SpanData.swift @@ -25,20 +25,20 @@ public struct SpanData: Equatable { public private(set) var spanId: SpanId /// The trace flags for this span. - public private(set) var traceFlags: TraceFlags = TraceFlags() + public private(set) var traceFlags = TraceFlags() /// The TraceState for this span. - public private(set) var traceState: TraceState = TraceState() + public private(set) var traceState = TraceState() /// The parent SpanId. If the Span is a root Span, the SpanId /// returned will be nil. public private(set) var parentSpanId: SpanId? /// The resource of this Span. - public private(set) var resource: Resource = Resource() + public private(set) var resource = Resource() /// The instrumentation library specified when creating the tracer which produced this Span - public private(set) var instrumentationLibraryInfo: InstrumentationLibraryInfo = InstrumentationLibraryInfo() + public private(set) var instrumentationLibraryInfo = InstrumentationLibraryInfo() /// The name of this Span. public private(set) var name: String @@ -72,17 +72,17 @@ public struct SpanData: Equatable { /// The total number of {@link TimedEvent} events that were recorded on this span. This /// number may be larger than the number of events that are attached to this span, if the total - /// number recorded was greater than the configured maximum value. See TraceConfig.maxNumberOfEvents + /// number recorded was greater than the configured maximum value. See SpanLimits.maxNumberOfEvents public private(set) var totalRecordedEvents: Int = 0 /// The total number of links that were recorded on this span. This number /// may be larger than the number of links that are attached to this span, if the total number - /// recorded was greater than the configured maximum value. See TraceConfig.maxNumberOfLinks + /// recorded was greater than the configured maximum value. See SpanLimits.maxNumberOfLinks public private(set) var totalRecordedLinks: Int = 0 /// The total number of attributes that were recorded on this span. This number may be larger than /// the number of attributes that are attached to this span, if the total number recorded was - /// greater than the configured maximum value. See TraceConfig.maxNumberOfAttributes + /// greater than the configured maximum value. See SpanLimits.maxNumberOfAttributes public private(set) var totalAttributeCount: Int = 0 public static func == (lhs: SpanData, rhs: SpanData) -> Bool { diff --git a/Sources/OpenTelemetrySdk/Trace/Export/BatchSpanProcessor.swift b/Sources/OpenTelemetrySdk/Trace/Export/BatchSpanProcessor.swift index 94a3af2d..6f67add5 100644 --- a/Sources/OpenTelemetrySdk/Trace/Export/BatchSpanProcessor.swift +++ b/Sources/OpenTelemetrySdk/Trace/Export/BatchSpanProcessor.swift @@ -25,16 +25,17 @@ import OpenTelemetryApi /// exports the spans to wake up and start a new export cycle. /// This batchSpanProcessor can cause high contention in a very high traffic service. public struct BatchSpanProcessor: SpanProcessor { - var sampled: Bool fileprivate var worker: BatchWorker - public init(spanExporter: SpanExporter, sampled: Bool = true, scheduleDelay: TimeInterval = 5, maxQueueSize: Int = 2048, maxExportBatchSize: Int = 512) { + public init(spanExporter: SpanExporter, scheduleDelay: TimeInterval = 5, exportTimeout: TimeInterval = 30, + maxQueueSize: Int = 2048, maxExportBatchSize: Int = 512) + { worker = BatchWorker(spanExporter: spanExporter, scheduleDelay: scheduleDelay, + exportTimeout: exportTimeout, maxQueueSize: maxQueueSize, maxExportBatchSize: maxExportBatchSize) worker.start() - self.sampled = sampled } public let isStartRequired = false @@ -43,7 +44,7 @@ public struct BatchSpanProcessor: SpanProcessor { public func onStart(parentContext: SpanContext?, span: ReadableSpan) {} public func onEnd(span: ReadableSpan) { - if sampled, !span.context.traceFlags.sampled { + if !span.context.traceFlags.sampled { return } worker.addSpan(span: span) @@ -66,17 +67,23 @@ private class BatchWorker: Thread { let spanExporter: SpanExporter let scheduleDelay: TimeInterval let maxQueueSize: Int + let exportTimeout: TimeInterval let maxExportBatchSize: Int let halfMaxQueueSize: Int private let cond = NSCondition() var spanList = [ReadableSpan]() + var queue: OperationQueue - init(spanExporter: SpanExporter, scheduleDelay: TimeInterval, maxQueueSize: Int, maxExportBatchSize: Int) { + init(spanExporter: SpanExporter, scheduleDelay: TimeInterval, exportTimeout:TimeInterval, maxQueueSize: Int, maxExportBatchSize: Int) { self.spanExporter = spanExporter self.scheduleDelay = scheduleDelay + self.exportTimeout = exportTimeout self.maxQueueSize = maxQueueSize halfMaxQueueSize = maxQueueSize >> 1 self.maxExportBatchSize = maxExportBatchSize + queue = OperationQueue() + queue.name = "BatchWorker Queue" + queue.maxConcurrentOperationCount = 1 } func addSpan(span: ReadableSpan) { @@ -109,7 +116,7 @@ private class BatchWorker: Thread { spansCopy = spanList spanList.removeAll() cond.unlock() - exportBatches(spanList: spansCopy) + self.exportBatch(spanList: spansCopy) } } while true } @@ -126,10 +133,23 @@ private class BatchWorker: Thread { spanList.removeAll() cond.unlock() // Execute the batch export outside the synchronized to not block all producers. - exportBatches(spanList: spansCopy) + exportBatch(spanList: spansCopy) } - private func exportBatches(spanList: [ReadableSpan]) { + private func exportBatch(spanList: [ReadableSpan]) { + let exportOperation = BlockOperation { [weak self] in + self?.exportAction(spanList: spanList) + } + let timeoutTimer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()) + timeoutTimer.setEventHandler{ exportOperation.cancel() } + timeoutTimer.schedule(deadline: .now() + .milliseconds(Int(exportTimeout.toMilliseconds)), leeway: .milliseconds(1)) + timeoutTimer.activate() + queue.addOperation(exportOperation) + queue.waitUntilAllOperationsAreFinished() + timeoutTimer.cancel() + } + + private func exportAction(spanList: [ReadableSpan]) { stride(from: 0, to: spanList.endIndex, by: maxExportBatchSize).forEach { spanExporter.export(spans: spanList[$0 ..< min($0 + maxExportBatchSize, spanList.count)].map { $0.toSpanData() }) } diff --git a/Sources/OpenTelemetrySdk/Trace/IdsGenerator.swift b/Sources/OpenTelemetrySdk/Trace/IdGenerator.swift similarity index 96% rename from Sources/OpenTelemetrySdk/Trace/IdsGenerator.swift rename to Sources/OpenTelemetrySdk/Trace/IdGenerator.swift index 7130cb81..b3dd66cb 100644 --- a/Sources/OpenTelemetrySdk/Trace/IdsGenerator.swift +++ b/Sources/OpenTelemetrySdk/Trace/IdGenerator.swift @@ -17,7 +17,7 @@ import Foundation import OpenTelemetryApi /// Interface that is used by the TracerSdk to generate new SpanId and TraceId. -public protocol IdsGenerator { +public protocol IdGenerator { /// Generates a new valid SpanId func generateSpanId() -> SpanId diff --git a/Sources/OpenTelemetrySdk/Trace/RandomIdsGenerator.swift b/Sources/OpenTelemetrySdk/Trace/RandomIdsGenerator.swift index 401f6bc9..67be379e 100644 --- a/Sources/OpenTelemetrySdk/Trace/RandomIdsGenerator.swift +++ b/Sources/OpenTelemetrySdk/Trace/RandomIdsGenerator.swift @@ -16,7 +16,7 @@ import Foundation import OpenTelemetryApi -public struct RandomIdsGenerator: IdsGenerator { +public struct RandomIdGenerator: IdGenerator { public init() {} public func generateSpanId() -> SpanId { diff --git a/Sources/OpenTelemetrySdk/Trace/RecordEventsReadableSpan.swift b/Sources/OpenTelemetrySdk/Trace/RecordEventsReadableSpan.swift index 48c93877..3e2b4b9c 100644 --- a/Sources/OpenTelemetrySdk/Trace/RecordEventsReadableSpan.swift +++ b/Sources/OpenTelemetrySdk/Trace/RecordEventsReadableSpan.swift @@ -13,9 +13,9 @@ // limitations under the License. // +import Atomics import Foundation import OpenTelemetryApi -import Atomics /// Implementation for the Span class that records trace events. public class RecordEventsReadableSpan: ReadableSpan { @@ -30,7 +30,7 @@ public class RecordEventsReadableSpan: ReadableSpan { } // The config used when constructing this Span. - public private(set) var traceConfig: TraceConfig + public private(set) var spanLimits: SpanLimits /// Contains the identifiers associated with this Span. public private(set) var context: SpanContext /// The parent SpanId of this span. Invalid if this is a root span. @@ -68,7 +68,7 @@ public class RecordEventsReadableSpan: ReadableSpan { /// Number of events recorded. public private(set) var totalRecordedEvents = 0 /// The status of the span. - public var status: Status = Status.unset { + public var status = Status.unset { didSet { if hasEnded { status = oldValue @@ -89,9 +89,7 @@ public class RecordEventsReadableSpan: ReadableSpan { /// True if the span is ended. fileprivate var endAtomic = ManagedAtomic(false) public var hasEnded: Bool { - get { - return self.endAtomic.load(ordering: .relaxed) - } + return self.endAtomic.load(ordering: .relaxed) } private let eventsSyncLock = Lock() @@ -103,20 +101,21 @@ public class RecordEventsReadableSpan: ReadableSpan { kind: SpanKind, parentContext: SpanContext?, hasRemoteParent: Bool, - traceConfig: TraceConfig, + spanLimits: SpanLimits, spanProcessor: SpanProcessor, clock: Clock, resource: Resource, attributes: AttributesDictionary, links: [SpanData.Link], totalRecordedLinks: Int, - startTime: Date?) { + startTime: Date?) + { self.context = context self.name = name self.instrumentationLibraryInfo = instrumentationLibraryInfo self.parentContext = parentContext self.hasRemoteParent = hasRemoteParent - self.traceConfig = traceConfig + self.spanLimits = spanLimits self.links = links self.totalRecordedLinks = totalRecordedLinks self.kind = kind @@ -125,9 +124,9 @@ public class RecordEventsReadableSpan: ReadableSpan { self.resource = resource self.startTime = startTime ?? clock.now self.attributes = attributes - events = ArrayWithCapacity(capacity: traceConfig.maxNumberOfEvents) - maxNumberOfAttributes = traceConfig.maxNumberOfAttributes - maxNumberOfAttributesPerEvent = traceConfig.maxNumberOfAttributesPerEvent + events = ArrayWithCapacity(capacity: spanLimits.eventCountLimit) + maxNumberOfAttributes = spanLimits.attributeCountLimit + maxNumberOfAttributesPerEvent = spanLimits.attributePerEventCountLimit } /// Creates and starts a span with the given configuration. @@ -138,7 +137,7 @@ public class RecordEventsReadableSpan: ReadableSpan { /// - kind: the span kind. /// - parentSpanId: the span_id of the parent span, or nil if the new span is a root span. /// - hasRemoteParent: true if the parentContext is remote, false if this is a root span. - /// - traceConfig: trace parameters like sampler and probability. + /// - spanLimits: trace parameters like sampler and probability. /// - spanProcessor: handler called when the span starts and ends. /// - clock: the clock used to get the time. /// - resource: the resource associated with this span. @@ -152,21 +151,22 @@ public class RecordEventsReadableSpan: ReadableSpan { kind: SpanKind, parentContext: SpanContext?, hasRemoteParent: Bool, - traceConfig: TraceConfig, + spanLimits: SpanLimits, spanProcessor: SpanProcessor, clock: Clock, resource: Resource, attributes: AttributesDictionary, links: [SpanData.Link], totalRecordedLinks: Int, - startTime: Date) -> RecordEventsReadableSpan { + startTime: Date) -> RecordEventsReadableSpan + { let span = RecordEventsReadableSpan(context: context, name: name, instrumentationLibraryInfo: instrumentationLibraryInfo, kind: kind, parentContext: parentContext, hasRemoteParent: hasRemoteParent, - traceConfig: traceConfig, + spanLimits: spanLimits, spanProcessor: spanProcessor, clock: clock, resource: resource, @@ -273,8 +273,8 @@ public class RecordEventsReadableSpan: ReadableSpan { if endAtomic.exchange(true, ordering: .relaxed) { return } - eventsSyncLock.withLockVoid{ - attributesSyncLock.withLockVoid{ + eventsSyncLock.withLockVoid { + attributesSyncLock.withLockVoid { isRecording = false } } diff --git a/Sources/OpenTelemetrySdk/Trace/Samplers/Samplers.swift b/Sources/OpenTelemetrySdk/Trace/Samplers/Samplers.swift index a79fbf36..a7aa2a9b 100644 --- a/Sources/OpenTelemetrySdk/Trace/Samplers/Samplers.swift +++ b/Sources/OpenTelemetrySdk/Trace/Samplers/Samplers.swift @@ -17,16 +17,32 @@ import Foundation import OpenTelemetryApi /// Struct to access a set of pre-defined Samplers. -public struct Samplers { +public enum Samplers { /// A Sampler that always makes a "yes" decision on Span sampling. public static var alwaysOn: Sampler = AlwaysOnSampler() /// Sampler that always makes a "no" decision on Span sampling. public static var alwaysOff: Sampler = AlwaysOffSampler() - /// Returns a new Probability Sampler. The probability of sampling a trace is equal to that + /// Returns a new TraceIdRatioBased Sampler. The probability of sampling a trace is equal to that /// of the specified probability. /// - Parameter probability: The desired probability of sampling. Must be within [0.0, 1.0]. - public static func probability(probability: Double) -> Sampler { - return Probability(probability: probability) + public static func traceIdRatio(ratio: Double) -> Sampler { + return TraceIdRatioBased(ratio: ratio) + } + + /// Returns a new ParentBased Sampler. The probability of sampling a trace is equal to that + /// of the specified probability. + /// - Parameter probability: The desired probability of sampling. Must be within [0.0, 1.0]. + public static func parentBased(root: Sampler, + remoteParentSampled: Sampler? = nil, + remoteParentNotSampled: Sampler? = nil, + localParentSampled: Sampler? = nil, + localParentNotSampled: Sampler? = nil) -> Sampler + { + return ParentBasedSampler(root: root, + remoteParentSampled: remoteParentSampled, + remoteParentNotSampled: remoteParentNotSampled, + localParentSampled: localParentSampled, + localParentNotSampled: localParentNotSampled) } static var alwaysOnDecision: Decision = SimpleDecision(decision: true) @@ -38,13 +54,14 @@ class AlwaysOnSampler: Sampler { traceId: TraceId, name: String, kind: SpanKind, - attributes: [String:AttributeValue], - parentLinks: [SpanData.Link]) -> Decision { + attributes: [String: AttributeValue], + parentLinks: [SpanData.Link]) -> Decision + { return Samplers.alwaysOnDecision } var description: String { - return String(describing: AlwaysOnSampler.self) + return "AlwaysOnSampler" } } @@ -53,13 +70,14 @@ class AlwaysOffSampler: Sampler { traceId: TraceId, name: String, kind: SpanKind, - attributes: [String:AttributeValue], - parentLinks: [SpanData.Link]) -> Decision { + attributes: [String: AttributeValue], + parentLinks: [SpanData.Link]) -> Decision + { return Samplers.alwaysOffDecision } var description: String { - return String(describing: AlwaysOffSampler.self) + return "AlwaysOffSampler" } } @@ -68,18 +86,18 @@ class AlwaysOffSampler: Sampler { /// just compare the absolute value of the id and the bound to see if we are within the desired /// probability range. Using the low bits of the traceId also ensures that systems that only use 64 /// bit ID's will also work with this sampler. -class Probability: Sampler { +class TraceIdRatioBased: Sampler { var probability: Double var idUpperBound: UInt - init(probability: Double) { - self.probability = probability - if probability <= 0.0 { + init(ratio: Double) { + self.probability = ratio + if ratio <= 0.0 { idUpperBound = UInt.min - } else if probability >= 1.0 { + } else if ratio >= 1.0 { idUpperBound = UInt.max } else { - idUpperBound = UInt(probability * Double(UInt.max)) + idUpperBound = UInt(ratio * Double(UInt.max)) } } @@ -87,8 +105,9 @@ class Probability: Sampler { traceId: TraceId, name: String, kind: SpanKind, - attributes: [String:AttributeValue], - parentLinks: [SpanData.Link]) -> Decision { + attributes: [String: AttributeValue], + parentLinks: [SpanData.Link]) -> Decision + { /// If the parent is sampled keep the sampling decision. if parentContext?.traceFlags.sampled ?? false { return Samplers.alwaysOnDecision @@ -115,14 +134,13 @@ class Probability: Sampler { } var description: String { - return String(format: "ProbabilitySampler{%.6f}", probability) + return String(format: "TraceIdRatioBased{%.6f}", probability) } } /// A Sampler that uses the sampled flag of the parent Span, if present. If the span has no parent, /// this Sampler will use the "root" sampler that it is built with. class ParentBasedSampler: Sampler { - private let root: Sampler private let remoteParentSampled: Sampler private let remoteParentNotSampled: Sampler @@ -130,15 +148,16 @@ class ParentBasedSampler: Sampler { private let localParentNotSampled: Sampler internal init(root: Sampler, - remoteParentSampled: Sampler?, - remoteParentNotSampled: Sampler?, - localParentSampled: Sampler?, - localParentNotSampled: Sampler?) { + remoteParentSampled: Sampler? = nil, + remoteParentNotSampled: Sampler? = nil, + localParentSampled: Sampler? = nil, + localParentNotSampled: Sampler? = nil) + { self.root = root self.remoteParentSampled = remoteParentSampled ?? Samplers.alwaysOn - self.remoteParentNotSampled = remoteParentNotSampled ?? Samplers.alwaysOff + self.remoteParentNotSampled = remoteParentNotSampled ?? Samplers.alwaysOff self.localParentSampled = localParentSampled ?? Samplers.alwaysOn - self.localParentNotSampled = localParentNotSampled ?? Samplers.alwaysOff + self.localParentNotSampled = localParentNotSampled ?? Samplers.alwaysOff } /// If a parent is set, always follows the same sampling decision as the parent. @@ -147,24 +166,25 @@ class ParentBasedSampler: Sampler { traceId: TraceId, name: String, kind: SpanKind, - attributes: [String:AttributeValue], - parentLinks: [SpanData.Link]) -> Decision { + attributes: [String: AttributeValue], + parentLinks: [SpanData.Link]) -> Decision + { guard let parentSpanContext = parentContext, parentSpanContext.isValid else { - return root.shouldSample( parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks); + return root.shouldSample(parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks) } - if (parentSpanContext.isRemote) { + if parentSpanContext.isRemote { return parentSpanContext.isSampled ? remoteParentSampled.shouldSample( parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks) : remoteParentNotSampled.shouldSample( - parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks); + parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks) } return parentSpanContext.isSampled ? localParentSampled.shouldSample( parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks) : localParentNotSampled.shouldSample( - parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks); + parentContext: parentContext, traceId: traceId, name: name, kind: kind, attributes: attributes, parentLinks: parentLinks) } var description: String { diff --git a/Sources/OpenTelemetrySdk/Trace/SpanBuilderSDK.swift b/Sources/OpenTelemetrySdk/Trace/SpanBuilderSDK.swift index 027c4b55..c2d41f41 100644 --- a/Sources/OpenTelemetrySdk/Trace/SpanBuilderSDK.swift +++ b/Sources/OpenTelemetrySdk/Trace/SpanBuilderSDK.swift @@ -30,11 +30,8 @@ public class SpanBuilderSdk: SpanBuilder { private var spanName: String private var instrumentationLibraryInfo: InstrumentationLibraryInfo - private var spanProcessor: SpanProcessor - private var traceConfig: TraceConfig - private var resource: Resource - private var idsGenerator: IdsGenerator - private var clock: Clock + private var tracerSharedState: TracerSharedState + private var spanLimits: SpanLimits private var parent: Span? private var remoteParent: SpanContext? @@ -44,23 +41,18 @@ public class SpanBuilderSdk: SpanBuilder { private var totalNumberOfLinksAdded: Int = 0 private var parentType: ParentType = .currentSpan - private var startTime: Date = Date() + private var startTime = Date() public init(spanName: String, instrumentationLibraryInfo: InstrumentationLibraryInfo, - spanProcessor: SpanProcessor, - traceConfig: TraceConfig, - resource: Resource, - idsGenerator: IdsGenerator, - clock: Clock) { + tracerSharedState: TracerSharedState, + spanLimits: SpanLimits) + { self.spanName = spanName self.instrumentationLibraryInfo = instrumentationLibraryInfo - self.spanProcessor = spanProcessor - self.traceConfig = traceConfig - attributes = AttributesDictionary(capacity: traceConfig.maxNumberOfAttributes) - self.resource = resource - self.idsGenerator = idsGenerator - self.clock = clock + self.tracerSharedState = tracerSharedState + self.spanLimits = spanLimits + attributes = AttributesDictionary(capacity: spanLimits.attributeCountLimit) } @discardableResult public func setParent(_ parent: Span) -> Self { @@ -94,7 +86,7 @@ public class SpanBuilderSdk: SpanBuilder { @discardableResult public func addLink(_ link: SpanData.Link) -> Self { totalNumberOfLinksAdded += 1 - if links.count >= traceConfig.maxNumberOfLinks { + if links.count >= spanLimits.linkCountLimit { return self } links.append(link) @@ -119,23 +111,23 @@ public class SpanBuilderSdk: SpanBuilder { public func startSpan() -> Span { var parentContext = getParentContext(parentType: parentType, explicitParent: parent, remoteParent: remoteParent) let traceId: TraceId - let spanId = idsGenerator.generateSpanId() + let spanId = tracerSharedState.idGenerator.generateSpanId() var traceState = TraceState() if parentContext?.isValid ?? false { traceId = parentContext!.traceId traceState = parentContext!.traceState } else { - traceId = idsGenerator.generateTraceId() + traceId = tracerSharedState.idGenerator.generateTraceId() parentContext = nil } - let samplingDecision = traceConfig.sampler.shouldSample(parentContext: parentContext, - traceId: traceId, - name: spanName, - kind: spanKind, - attributes: attributes.attributes, - parentLinks: links) + let samplingDecision = tracerSharedState.sampler.shouldSample(parentContext: parentContext, + traceId: traceId, + name: spanName, + kind: spanKind, + attributes: attributes.attributes, + parentLinks: links) let spanContext = SpanContext.create(traceId: traceId, spanId: spanId, @@ -154,10 +146,10 @@ public class SpanBuilderSdk: SpanBuilder { kind: spanKind, parentContext: parentContext, hasRemoteParent: parentContext?.isRemote ?? false, - traceConfig: traceConfig, - spanProcessor: spanProcessor, - clock: SpanBuilderSdk.getClock(parent: SpanBuilderSdk.getParentSpan(parentType: parentType, explicitParent: parent), clock: clock), - resource: resource, + spanLimits: spanLimits, + spanProcessor: tracerSharedState.activeSpanProcessor, + clock: SpanBuilderSdk.getClock(parent: SpanBuilderSdk.getParentSpan(parentType: parentType, explicitParent: parent), clock: tracerSharedState.clock), + resource: tracerSharedState.resource, attributes: attributes, links: links, totalRecordedLinks: totalNumberOfLinksAdded, diff --git a/Sources/OpenTelemetrySdk/Trace/SpanLimits.swift b/Sources/OpenTelemetrySdk/Trace/SpanLimits.swift new file mode 100644 index 00000000..86eea779 --- /dev/null +++ b/Sources/OpenTelemetrySdk/Trace/SpanLimits.swift @@ -0,0 +1,74 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import OpenTelemetryApi + +/// Struct that holds global trace parameters. +public struct SpanLimits: Equatable { + // These values are the default values for all the global parameters. + // TODO: decide which default sampler to use + + /// The global default max number of attributes perSpan. + public private(set) var attributeCountLimit: Int = 128 + /// the global default max number of Events per Span. + public private(set) var eventCountLimit: Int = 128 + /// the global default max number of Link entries per Span. + public private(set) var linkCountLimit: Int = 128 + /// the global default max number of attributes per Event. + public private(set) var attributePerEventCountLimit: Int = 128 + /// the global default max number of attributes per Link. + public private(set) var attributePerLinkCountLimit: Int = 128 + /// Returns the defaultSpanLimits. + public init() {} + + @discardableResult public func settingAttributeCountLimit(_ number: UInt) -> Self { + var spanLimits = self + spanLimits.attributeCountLimit = number > 0 ? Int(number) : 0 + return spanLimits + } + + @discardableResult public func settingEventCountLimit(_ number: UInt) -> Self { + var spanLimits = self + spanLimits.eventCountLimit = number > 0 ? Int(number) : 0 + return spanLimits + } + + @discardableResult public func settingLinkCountLimit(_ number: UInt) -> Self { + var spanLimits = self + spanLimits.linkCountLimit = number > 0 ? Int(number) : 0 + return spanLimits + } + + @discardableResult public func settingAttributePerEventCountLimit(_ number: UInt) -> Self { + var spanLimits = self + spanLimits.attributePerEventCountLimit = number > 0 ? Int(number) : 0 + return spanLimits + } + + @discardableResult public func settingAttributePerLinkCountLimit(_ number: UInt) -> Self { + var spanLimits = self + spanLimits.attributePerLinkCountLimit = number > 0 ? Int(number) : 0 + return spanLimits + } + + public static func == (lhs: SpanLimits, rhs: SpanLimits) -> Bool { + return lhs.attributeCountLimit == rhs.attributeCountLimit && + lhs.eventCountLimit == rhs.eventCountLimit && + lhs.linkCountLimit == rhs.linkCountLimit && + lhs.attributePerEventCountLimit == rhs.attributePerEventCountLimit && + lhs.attributePerLinkCountLimit == rhs.attributePerLinkCountLimit + } +} diff --git a/Sources/OpenTelemetrySdk/Trace/TracerSdk.swift b/Sources/OpenTelemetrySdk/Trace/TracerSdk.swift index 2cb07050..92226247 100644 --- a/Sources/OpenTelemetrySdk/Trace/TracerSdk.swift +++ b/Sources/OpenTelemetrySdk/Trace/TracerSdk.swift @@ -33,16 +33,13 @@ public class TracerSdk: Tracer { } public func spanBuilder(spanName: String) -> SpanBuilder { - if sharedState.isStopped { + if sharedState.hasBeenShutdown { return DefaultTracer.instance.spanBuilder(spanName: spanName) } return SpanBuilderSdk(spanName: spanName, instrumentationLibraryInfo: instrumentationLibraryInfo, - spanProcessor: sharedState.activeSpanProcessor, - traceConfig: sharedState.activeTraceConfig, - resource: sharedState.resource, - idsGenerator: sharedState.idsGenerator, - clock: sharedState.clock) + tracerSharedState: sharedState, + spanLimits: sharedState.activeSpanLimits) } @discardableResult public func setActive(_ span: Span) -> Scope { diff --git a/Sources/OpenTelemetrySdk/Trace/TracerSdkProvider.swift b/Sources/OpenTelemetrySdk/Trace/TracerSdkProvider.swift index 244df3cb..16145259 100644 --- a/Sources/OpenTelemetrySdk/Trace/TracerSdkProvider.swift +++ b/Sources/OpenTelemetrySdk/Trace/TracerSdkProvider.swift @@ -19,16 +19,20 @@ import OpenTelemetryApi /// This class is not intended to be used in application code and it is used only by OpenTelemetry. public class TracerSdkProvider: TracerProvider { private var tracerProvider = [InstrumentationLibraryInfo: TracerSdk]() - private var sharedState: TracerSharedState + internal var sharedState: TracerSharedState - /// Returns a new TracerSdkProvider with default Clock, IdsGenerator and Resource. + /// Returns a new TracerSdkProvider with default Clock, IdGenerator and Resource. public init(clock: Clock = MillisClock(), - idsGenerator: IdsGenerator = RandomIdsGenerator(), - resource: Resource = EnvVarResource.resource) { - sharedState = TracerSharedState(clock: clock, idsGenerator: idsGenerator, resource: resource) + idGenerator: IdGenerator = RandomIdGenerator(), + resource: Resource = EnvVarResource.resource) + { + sharedState = TracerSharedState(clock: clock, idGenerator: idGenerator, resource: resource) } public func get(instrumentationName: String, instrumentationVersion: String? = nil) -> Tracer { + if sharedState.hasBeenShutdown { + return DefaultTracer() + } let instrumentationLibraryInfo = InstrumentationLibraryInfo(name: instrumentationName, version: instrumentationVersion ?? "") if let tracer = tracerProvider[instrumentationLibraryInfo] { return tracer @@ -46,14 +50,14 @@ public class TracerSdkProvider: TracerProvider { } } - /// Returns the active TraceConfig. - public func getActiveTraceConfig() -> TraceConfig { - sharedState.activeTraceConfig + /// Returns the active SpanLimits. + public func getActiveSpanLimits() -> SpanLimits { + sharedState.activeSpanLimits } - /// Updates the active TraceConfig. - public func updateActiveTraceConfig(_ traceConfig: TraceConfig) { - sharedState.setActiveTraceConfig(traceConfig) + /// Updates the active SpanLimits. + public func updateActiveSpanLimits(_ spanLimits: SpanLimits) { + sharedState.setActiveSpanLimits(spanLimits) } /// Adds a new SpanProcessor to this Tracer. @@ -70,13 +74,13 @@ public class TracerSdkProvider: TracerProvider { /// off the main application to ensure all data are processed and exported. /// After this is called all the newly created Spanss will be no-op. public func shutdown() { - if sharedState.isStopped { + if sharedState.hasBeenShutdown { return } sharedState.stop() } - ///Requests the active span processor to process all span events that have not yet been processed. + /// Requests the active span processor to process all span events that have not yet been processed. public func forceFlush() { sharedState.activeSpanProcessor.forceFlush() } diff --git a/Sources/OpenTelemetrySdk/Trace/TracerSharedState.swift b/Sources/OpenTelemetrySdk/Trace/TracerSharedState.swift index 8e6f7294..93339f84 100644 --- a/Sources/OpenTelemetrySdk/Trace/TracerSharedState.swift +++ b/Sources/OpenTelemetrySdk/Trace/TracerSharedState.swift @@ -18,18 +18,19 @@ import Foundation /// Represents the shared state/config between all Tracers created by the same TracerProvider. public class TracerSharedState { public private(set) var clock: Clock - public private(set) var idsGenerator: IdsGenerator + public private(set) var idGenerator: IdGenerator public private(set) var resource: Resource - public private(set) var activeTraceConfig = TraceConfig() + public private(set) var sampler: Sampler = ParentBasedSampler(root: Samplers.alwaysOn) + public private(set) var activeSpanLimits = SpanLimits() public private(set) var activeSpanProcessor: SpanProcessor = NoopSpanProcessor() - public private(set) var isStopped = false + public private(set) var hasBeenShutdown = false private var registeredSpanProcessors = [SpanProcessor]() - public init(clock: Clock, idsGenerator: IdsGenerator, resource: Resource) { + public init(clock: Clock, idGenerator: IdGenerator, resource: Resource) { self.clock = clock - self.idsGenerator = idsGenerator + self.idGenerator = idGenerator self.resource = resource } @@ -42,14 +43,29 @@ public class TracerSharedState { /// Stops tracing, including shutting down processors and set to true isStopped. public func stop() { - if isStopped { + if hasBeenShutdown { return } activeSpanProcessor.shutdown() - isStopped = true + hasBeenShutdown = true } - internal func setActiveTraceConfig(_ activeTraceConfig: TraceConfig) { - self.activeTraceConfig = activeTraceConfig + internal func setActiveSpanLimits(_ activeSpanLimits: SpanLimits) { + self.activeSpanLimits = activeSpanLimits + } + + public func setSampler(_ sampler: Sampler) { + self.sampler = sampler + } + + // Sets the global sampler probability + public func setSamplerProbability(samplerProbability: Double) { + if samplerProbability >= 1 { + return setSampler(Samplers.alwaysOn) + } else if samplerProbability <= 0 { + return setSampler(Samplers.alwaysOff) + } else { + return setSampler(Samplers.traceIdRatio(ratio: samplerProbability)) + } } } diff --git a/Sources/OpenTracingShim/SpanShim.swift b/Sources/OpenTracingShim/SpanShim.swift index 24fc676f..1b387b09 100644 --- a/Sources/OpenTracingShim/SpanShim.swift +++ b/Sources/OpenTracingShim/SpanShim.swift @@ -50,7 +50,7 @@ public class SpanShim: OTSpan, BaseShimProtocol { public func setTag(_ key: String, value: String) { if key == SpanShim.OpenTracingErrorTag { let error = Bool(value) ?? false - span.status = error ? .error : .ok + span.status = error ? .error(description: "error") : .ok } else { span.setAttribute(key: key, value: value) } @@ -73,7 +73,7 @@ public class SpanShim: OTSpan, BaseShimProtocol { public func setTag(_ key: String, boolValue value: Bool) { if key == SpanShim.OpenTracingErrorTag { - span.status = value ? .error : .ok + span.status = value ? .error(description: "error") : .ok } else { span.setAttribute(key: key, value: value) } diff --git a/Tests/ExportersTests/Jaeger/AdapterTests.swift b/Tests/ExportersTests/Jaeger/AdapterTests.swift index c40dd1e6..5b2060b9 100644 --- a/Tests/ExportersTests/Jaeger/AdapterTests.swift +++ b/Tests/ExportersTests/Jaeger/AdapterTests.swift @@ -203,7 +203,7 @@ class AdapterTests: XCTestCase { name: "GET /api/endpoint", kind: .server, startTime: Date(timeIntervalSince1970: Double(startMs) / 1000), - status: Status.error, + status: .error(description: "GenericError"), endTime: Date(timeIntervalSince1970: Double(endMs) / 1000), hasRemoteParent: false) @@ -223,7 +223,7 @@ class AdapterTests: XCTestCase { startTime: Date(timeIntervalSince1970: Double(startMs) / 1000), endTime: Date(timeIntervalSince1970: Double(endMs) / 1000)) span.settingHasEnded(true) - span.settingStatus(.error) + span.settingStatus(.error(description: "GenericError")) span.settingAttributes(attributes) let jaegerSpan = Adapter.toJaeger(span: span) diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpMetricExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpMetricExporterTests.swift index 969a010e..3db8ba22 100644 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpMetricExporterTests.swift +++ b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpMetricExporterTests.swift @@ -1,21 +1,20 @@ import Foundation -import NIO import GRPC +import NIO import OpenTelemetryApi -@testable import OpenTelemetrySdk @testable import OpenTelemetryProtocolExporter +@testable import OpenTelemetrySdk import XCTest -class OtlpMetricExproterTests : XCTestCase { - +class OtlpMetricExproterTests: XCTestCase { var fakeCollector: FakeMetricCollector! var server: EventLoopFuture! var channel: ClientConnection! let channelGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) let serverGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) - + override func setUp() { fakeCollector = FakeMetricCollector() server = startServer() @@ -37,7 +36,7 @@ class OtlpMetricExproterTests : XCTestCase { XCTAssertEqual(fakeCollector.receivedMetrics, MetricsAdapter.toProtoResourceMetrics(metricDataList: [metric])) exporter.shutdown() } - + func testExportMultipleMetrics() { var metrics = [Metric]() for _ in 0 ..< 10 { @@ -51,7 +50,7 @@ class OtlpMetricExproterTests : XCTestCase { XCTAssertEqual(fakeCollector.receivedMetrics, MetricsAdapter.toProtoResourceMetrics(metricDataList: metrics)) exporter.shutdown() } - + func testExportAfterShutdown() { let metric = generateSumMetric() let exporter = OtelpMetricExporter(channel: channel) @@ -61,8 +60,7 @@ class OtlpMetricExproterTests : XCTestCase { } XCTAssertEqual(result, MetricExporterResultCode.failureRetryable) } - - + func testExportCancelled() { fakeCollector.returnedStatus = GRPCStatus(code: .cancelled, message: nil) let exporter = OtelpMetricExporter(channel: channel) @@ -72,7 +70,7 @@ class OtlpMetricExproterTests : XCTestCase { } XCTAssertEqual(result, MetricExporterResultCode.failureRetryable) } - + func startServer() -> EventLoopFuture { // Start the server and print its address once it has started. let server = Server.insecure(group: serverGroup) @@ -93,22 +91,23 @@ class OtlpMetricExproterTests : XCTestCase { return channel } - func generateSumMetric() -> Metric { let library = InstrumentationLibraryInfo(name: "lib", version: "semver:0.0.0") var metric = Metric(namespace: "namespace", name: "metric", desc: "description", type: .doubleSum, resource: Resource(), instrumentationLibraryInfo: library) - let data = SumData(startTimestamp: Date(), timestamp: Date(), labels: ["hello":"world"], sum: 1) + let data = SumData(startTimestamp: Date(), timestamp: Date(), labels: ["hello": "world"], sum: 1) metric.data.append(data) return metric } } -class FakeMetricCollector : Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceProvider -{ +class FakeMetricCollector: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceProvider { + var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerInterceptorFactoryProtocol? + var receivedMetrics = [Opentelemetry_Proto_Metrics_V1_ResourceMetrics]() var returnedStatus = GRPCStatus.ok func export(request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, context: StatusOnlyCallContext) -> - EventLoopFuture { + EventLoopFuture + { receivedMetrics.append(contentsOf: request.resourceMetrics) if returnedStatus != GRPCStatus.ok { return context.eventLoop.makeFailedFuture(returnedStatus) diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift index 54cd0113..b703de22 100644 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift +++ b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift @@ -125,6 +125,7 @@ class OtlpTraceExporterTests: XCTestCase { class FakeCollector: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceProvider { var receivedSpans = [Opentelemetry_Proto_Trace_V1_ResourceSpans]() var returnedStatus = GRPCStatus.ok + var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerInterceptorFactoryProtocol? = nil func export(request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, context: StatusOnlyCallContext) -> EventLoopFuture { receivedSpans.append(contentsOf: request.resourceSpans) diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift index 1f5e99ca..8f5f528b 100644 --- a/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift +++ b/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift @@ -36,14 +36,13 @@ class SpanAdapterTests: XCTestCase { func testToPRotoResourceSpans() { let libInfo = InstrumentationLibraryInfo(name: "testLibrary", version: "semver:0.0.1") - let event = RecordEventsReadableSpan.startSpan(context: spanContext, name: "GET /api/endpoint", instrumentationLibraryInfo: libInfo, kind: SpanKind.server, parentContext: nil, hasRemoteParent: false, traceConfig: TraceConfig(), spanProcessor: NoopSpanProcessor(), clock: MillisClock(), resource: Resource(), attributes: AttributesDictionary(capacity: 0), links: [], totalRecordedLinks: 0, startTime: Date()) - + let event = RecordEventsReadableSpan.startSpan(context: spanContext, name: "GET /api/endpoint", instrumentationLibraryInfo: libInfo, kind: SpanKind.server, parentContext: nil, hasRemoteParent: false, spanLimits: SpanLimits(), spanProcessor: NoopSpanProcessor(), clock: MillisClock(), resource: Resource(), attributes: AttributesDictionary(capacity: 0), links: [], totalRecordedLinks: 0, startTime: Date()) + let result = SpanAdapter.toProtoResourceSpans(spanDataList: [event.toSpanData()]) - - XCTAssertTrue(result[0].instrumentationLibrarySpans.count > 0) + XCTAssertTrue(result[0].instrumentationLibrarySpans.count > 0) } - + func testToProtoSpan() { var testData = SpanData(traceId: traceId, spanId: spanId, name: "GET /api/endpoint", kind: SpanKind.server, startTime: Date(timeIntervalSince1970: 12345), endTime: Date(timeIntervalSince1970: 12349)) testData.settingHasEnded(false) @@ -104,13 +103,12 @@ class SpanAdapterTests: XCTestCase { status = Opentelemetry_Proto_Trace_V1_Status() status.code = .ok - status.message = "SUCCESS" - XCTAssertEqual(SpanAdapter.toStatusProto(status: Status.ok.withDescription(description: "SUCCESS")), status) + XCTAssertEqual(SpanAdapter.toStatusProto(status: .ok), status) status = Opentelemetry_Proto_Trace_V1_Status() status.code = .error status.message = "ERROR" - XCTAssertEqual(SpanAdapter.toStatusProto(status: Status.error.withDescription(description: "ERROR")), status) + XCTAssertEqual(SpanAdapter.toStatusProto(status: .error(description: "ERROR")), status) } func testToProtoSpanEvent() { diff --git a/Tests/OpenTelemetryApiTests/Trace/StatusTests.swift b/Tests/OpenTelemetryApiTests/Trace/StatusTests.swift index e747a539..9e25bcdd 100644 --- a/Tests/OpenTelemetryApiTests/Trace/StatusTests.swift +++ b/Tests/OpenTelemetryApiTests/Trace/StatusTests.swift @@ -17,26 +17,21 @@ import OpenTelemetryApi import XCTest final class StatusTests: XCTestCase { - func testStatus_Ok() { - XCTAssertEqual(Status.ok.statusCode, Status.StatusCode.ok) - XCTAssertNil(Status.ok.statusDescription) - XCTAssertTrue(Status.ok.isOk) + func testStatusIsOk() { + let statusOK = Status.ok + XCTAssertTrue(statusOK.isOk) + let statusUnset = Status.unset + XCTAssertFalse(statusUnset.isOk) + let statusError = Status.error(description: "Error") + XCTAssertFalse(statusError.isOk) } - func testCreateStatus_WithDescription() { - let status = Status.unset.withDescription(description: "This is an error.") - XCTAssertEqual(status.statusCode, Status.StatusCode.unset) - XCTAssertEqual(status.statusDescription, "This is an error.") - XCTAssertFalse(status.isOk) - } - - func testStatus_EqualsAndHashCode() { - XCTAssertEqual(Status.ok, Status.ok.withDescription(description: nil)) - XCTAssertNotEqual(Status.ok, Status.unset.withDescription(description: "ThisIsAnError")) - XCTAssertNotEqual(Status.ok, Status.error.withDescription(description: "ThisIsAnError")) - XCTAssertNotEqual(Status.ok.withDescription(description: nil), Status.error.withDescription(description: "ThisIsAnError")) - XCTAssertNotEqual(Status.ok.withDescription(description: nil), Status.unset.withDescription(description: "ThisIsAnError")) - XCTAssertEqual(Status.error.withDescription(description: "ThisIsAnError"), Status.error.withDescription(description: "ThisIsAnError")) - XCTAssertNotEqual(Status.error.withDescription(description: "ThisIsAnError"), Status.unset.withDescription(description: "ThisIsAnError")) + func testStatusIsError() { + let statusOK = Status.ok + XCTAssertFalse(statusOK.isError) + let statusUnset = Status.unset + XCTAssertFalse(statusUnset.isError) + let statusError = Status.error(description: "Error") + XCTAssertTrue(statusError.isError) } } diff --git a/Tests/OpenTelemetrySdkTests/Trace/Config/TraceConfigTests.swift b/Tests/OpenTelemetrySdkTests/Trace/Config/TraceConfigTests.swift deleted file mode 100644 index 29ab9c01..00000000 --- a/Tests/OpenTelemetrySdkTests/Trace/Config/TraceConfigTests.swift +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2020, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import OpenTelemetryApi -import OpenTelemetrySdk -import XCTest - -class TraceConfigTests: XCTestCase { - func testDefaultTraceConfig() { - XCTAssertTrue(TraceConfig().sampler === Samplers.alwaysOn) - XCTAssertEqual(TraceConfig().maxNumberOfAttributes, 1000) - XCTAssertEqual(TraceConfig().maxNumberOfEvents, 1000) - XCTAssertEqual(TraceConfig().maxNumberOfLinks, 1000) - XCTAssertEqual(TraceConfig().maxNumberOfAttributesPerEvent, 32) - XCTAssertEqual(TraceConfig().maxNumberOfAttributesPerLink, 32) - } - - func testUpdateTraceConfig_OffSamplerProbability() { - let traceConfig = TraceConfig().settingSamplerProbability(samplerProbability: 0) - XCTAssert(traceConfig.sampler === Samplers.alwaysOff) - } - - func testUpdateTraceConfig_OnSamplerProbability() { - let traceConfig = TraceConfig().settingSamplerProbability(samplerProbability: 1) - XCTAssert(traceConfig.sampler === Samplers.alwaysOn) - } - - func testUpdateTraceConfig_All() { - let traceConfig = TraceConfig().settingSampler(Samplers.alwaysOff).settingMaxNumberOfAttributes(8).settingMaxNumberOfEvents(10).settingMaxNumberOfLinks(11).settingMaxNumberOfAttributesPerEvent(1).settingMaxNumberOfAttributesPerLink(2) - XCTAssertTrue(traceConfig.sampler === Samplers.alwaysOff) - XCTAssertEqual(traceConfig.maxNumberOfAttributes, 8) - XCTAssertEqual(traceConfig.maxNumberOfEvents, 10) - XCTAssertEqual(traceConfig.maxNumberOfLinks, 11) - XCTAssertEqual(traceConfig.maxNumberOfAttributesPerEvent, 1) - XCTAssertEqual(traceConfig.maxNumberOfAttributesPerLink, 2) - } -} diff --git a/Tests/OpenTelemetrySdkTests/Trace/Export/BatchSpansProcessorTests.swift b/Tests/OpenTelemetrySdkTests/Trace/Export/BatchSpansProcessorTests.swift index 6681006d..e75d5f6d 100644 --- a/Tests/OpenTelemetrySdkTests/Trace/Export/BatchSpansProcessorTests.swift +++ b/Tests/OpenTelemetrySdkTests/Trace/Export/BatchSpansProcessorTests.swift @@ -35,7 +35,7 @@ class BatchSpansProcessorTests: XCTestCase { } @discardableResult private func createSampledEndedSpan(spanName: String) -> ReadableSpan { - let span = TestUtils.startSpanWithSampler(tracerSdkFactory: tracerSdkFactory, + let span = TestUtils.createSpanWithSampler(tracerSdkFactory: tracerSdkFactory, tracer: tracer, spanName: spanName, sampler: Samplers.alwaysOn) @@ -45,7 +45,7 @@ class BatchSpansProcessorTests: XCTestCase { } private func createNotSampledEndedSpan(spanName: String) { - TestUtils.startSpanWithSampler(tracerSdkFactory: tracerSdkFactory, + TestUtils.createSpanWithSampler(tracerSdkFactory: tracerSdkFactory, tracer: tracer, spanName: spanName, sampler: Samplers.alwaysOff) diff --git a/Tests/OpenTelemetrySdkTests/Trace/RecordEventsReadableSpanTests.swift b/Tests/OpenTelemetrySdkTests/Trace/RecordEventsReadableSpanTests.swift index 6d27d751..f3327436 100644 --- a/Tests/OpenTelemetrySdkTests/Trace/RecordEventsReadableSpanTests.swift +++ b/Tests/OpenTelemetrySdkTests/Trace/RecordEventsReadableSpanTests.swift @@ -22,13 +22,13 @@ class RecordEventsReadableSpanTest: XCTestCase { let spanNewName = "NewName" let nanosPerSecond: Int64 = 1000000000 let millisPerSecond: Int64 = 1000 - let idsGenerator: IdsGenerator = RandomIdsGenerator() + let idGenerator: IdGenerator = RandomIdGenerator() var traceId: TraceId! var spanId: SpanId! var parentSpanId: SpanId! let expectedHasRemoteParent = true var spanContext: SpanContext! - let startTime: Date = Date(timeIntervalSinceReferenceDate: 0) + let startTime = Date(timeIntervalSinceReferenceDate: 0) var testClock: TestClock! let resource = Resource() let instrumentationLibraryInfo = InstrumentationLibraryInfo(name: "theName", version: nil) @@ -38,9 +38,9 @@ class RecordEventsReadableSpanTest: XCTestCase { let spanProcessor = SpanProcessorMock() override func setUp() { - traceId = idsGenerator.generateTraceId() - spanId = idsGenerator.generateSpanId() - parentSpanId = idsGenerator.generateSpanId() + traceId = idGenerator.generateTraceId() + spanId = idGenerator.generateSpanId() + parentSpanId = idGenerator.generateSpanId() spanContext = SpanContext.create(traceId: traceId, spanId: spanId, traceFlags: TraceFlags(), traceState: TraceState()) testClock = TestClock(timeInterval: startTime.timeIntervalSince1970) link = SpanData.Link(context: spanContext) @@ -56,7 +56,7 @@ class RecordEventsReadableSpanTest: XCTestCase { span.end() // Check that adding trace events or update fields after Span#end() does not throw any thrown // and are ignored. - spanDoWork(span: span, status: .error) + spanDoWork(span: span, status: .error(description: "GenericError")) let spanData = span.toSpanData() verifySpanData(spanData: spanData, attributes: [String: AttributeValue](), @@ -137,11 +137,11 @@ class RecordEventsReadableSpanTest: XCTestCase { XCTAssertEqual(span.toSpanData().status, Status.unset) span.status = .ok XCTAssertEqual(span.toSpanData().status, Status.ok) - span.status = .error - XCTAssertEqual(span.toSpanData().status, Status.error) + span.status = .error(description: "GenericError") + XCTAssertTrue(span.toSpanData().status.isError) span.end() span.status = .ok - XCTAssertEqual(span.toSpanData().status, Status.error) + XCTAssertTrue(span.toSpanData().status.isError) } func testGetSpanKind() { @@ -248,8 +248,8 @@ class RecordEventsReadableSpanTest: XCTestCase { func testDroppingAttributes() { let maxNumberOfAttributes = 8 - let traceConfig = TraceConfig().settingMaxNumberOfAttributes(maxNumberOfAttributes) - let span = createTestSpan(config: traceConfig) + let spanLimits = SpanLimits().settingAttributeCountLimit(UInt(maxNumberOfAttributes)) + let span = createTestSpan(config: spanLimits) for i in 0 ..< 2 * maxNumberOfAttributes { span.setAttribute(key: "MyStringAttributeKey\(i)", value: AttributeValue.int(i)) } @@ -264,8 +264,8 @@ class RecordEventsReadableSpanTest: XCTestCase { func testDroppingAndAddingAttributes() { let maxNumberOfAttributes = 8 - let traceConfig = TraceConfig().settingMaxNumberOfAttributes(maxNumberOfAttributes) - let span = createTestSpan(config: traceConfig) + let spanLimits = SpanLimits().settingAttributeCountLimit(UInt(maxNumberOfAttributes)) + let span = createTestSpan(config: spanLimits) for i in 0 ..< 2 * maxNumberOfAttributes { span.setAttribute(key: "MyStringAttributeKey\(i)", value: AttributeValue.int(i)) } @@ -278,7 +278,7 @@ class RecordEventsReadableSpanTest: XCTestCase { } spanData = span.toSpanData() XCTAssertEqual(spanData.attributes.count, maxNumberOfAttributes) - // Test that we still have in the attributes map the latest maxNumberOfAttributes / 2 entries. + // Test that we still have in the attributes map the latest attributeCountLimit / 2 entries. for i in 0 ..< maxNumberOfAttributes / 2 { let val = i + maxNumberOfAttributes * 3 / 2 let expectedValue = AttributeValue.int(val) @@ -294,8 +294,8 @@ class RecordEventsReadableSpanTest: XCTestCase { func testDroppingEvents() { let maxNumberOfEvents = 8 - let traceConfig = TraceConfig().settingMaxNumberOfEvents(maxNumberOfEvents) - let span = createTestSpan(config: traceConfig) + let spanLimits = SpanLimits().settingEventCountLimit(UInt(maxNumberOfEvents)) + let span = createTestSpan(config: spanLimits) for _ in 0 ..< 2 * maxNumberOfEvents { span.addEvent(name: "event2", attributes: [String: AttributeValue]()) testClock.advanceMillis(millisPerSecond) @@ -319,10 +319,10 @@ class RecordEventsReadableSpanTest: XCTestCase { func testAsSpanData() { let name = "GreatSpan" let kind = SpanKind.server - let traceId = idsGenerator.generateTraceId() - let spanId = idsGenerator.generateSpanId() - let parentSpanId = idsGenerator.generateSpanId() - let traceConfig = TraceConfig() + let traceId = idGenerator.generateTraceId() + let spanId = idGenerator.generateSpanId() + let parentSpanId = idGenerator.generateSpanId() + let spanLimits = SpanLimits() let spanProcessor = NoopSpanProcessor() let clock = TestClock() var attribute = [String: AttributeValue]() @@ -339,9 +339,9 @@ class RecordEventsReadableSpanTest: XCTestCase { traceFlags: TraceFlags(), traceState: TraceState()) let parentContext = SpanContext.create(traceId: traceId, - spanId: parentSpanId, - traceFlags: TraceFlags(), - traceState: TraceState()) + spanId: parentSpanId, + traceFlags: TraceFlags(), + traceState: TraceState()) let link1 = SpanData.Link(context: context, attributes: TestUtils.generateRandomAttributes()) let links = [link1] @@ -351,7 +351,7 @@ class RecordEventsReadableSpanTest: XCTestCase { kind: kind, parentContext: parentContext, hasRemoteParent: false, - traceConfig: traceConfig, + spanLimits: spanLimits, spanProcessor: spanProcessor, clock: clock, resource: resource, @@ -398,11 +398,11 @@ class RecordEventsReadableSpanTest: XCTestCase { } private func createTestRootSpan() -> RecordEventsReadableSpan { - return createTestSpan(kind: .internal, config: TraceConfig(), parentContext: nil, attributes: [String: AttributeValue]()) + return createTestSpan(kind: .internal, config: SpanLimits(), parentContext: nil, attributes: [String: AttributeValue]()) } private func createTestSpan(attributes: [String: AttributeValue]) -> RecordEventsReadableSpan { - return createTestSpan(kind: .internal, config: TraceConfig(), parentContext: nil, attributes: attributes) + return createTestSpan(kind: .internal, config: SpanLimits(), parentContext: nil, attributes: attributes) } private func createTestSpan(kind: SpanKind) -> RecordEventsReadableSpan { @@ -410,15 +410,15 @@ class RecordEventsReadableSpanTest: XCTestCase { spanId: parentSpanId, traceFlags: TraceFlags(), traceState: TraceState()) - return createTestSpan(kind: kind, config: TraceConfig(), parentContext: parentContext, attributes: [String: AttributeValue]()) + return createTestSpan(kind: kind, config: SpanLimits(), parentContext: parentContext, attributes: [String: AttributeValue]()) } - private func createTestSpan(config: TraceConfig) -> RecordEventsReadableSpan { + private func createTestSpan(config: SpanLimits) -> RecordEventsReadableSpan { return createTestSpan(kind: .internal, config: config, parentContext: nil, attributes: [String: AttributeValue]()) } - private func createTestSpan(kind: SpanKind, config: TraceConfig, parentContext: SpanContext?, attributes: [String: AttributeValue]) -> RecordEventsReadableSpan { - var attributesWithCapacity = AttributesDictionary(capacity: config.maxNumberOfAttributes) + private func createTestSpan(kind: SpanKind, config: SpanLimits, parentContext: SpanContext?, attributes: [String: AttributeValue]) -> RecordEventsReadableSpan { + var attributesWithCapacity = AttributesDictionary(capacity: config.attributeCountLimit) attributesWithCapacity.updateValues(attributes: attributes) let span = RecordEventsReadableSpan.startSpan(context: spanContext, @@ -427,7 +427,7 @@ class RecordEventsReadableSpanTest: XCTestCase { kind: kind, parentContext: parentContext, hasRemoteParent: true, - traceConfig: config, + spanLimits: config, spanProcessor: spanProcessor, clock: testClock, resource: resource, @@ -459,7 +459,8 @@ class RecordEventsReadableSpanTest: XCTestCase { startTime: Date, endTime: Date, status: Status, - hasEnded: Bool) { + hasEnded: Bool) + { XCTAssertEqual(spanData.traceId, traceId) XCTAssertEqual(spanData.spanId, spanId) XCTAssertEqual(spanData.parentSpanId, parentSpanId) @@ -473,7 +474,7 @@ class RecordEventsReadableSpanTest: XCTestCase { XCTAssert(spanData.links == links) XCTAssertEqual(spanData.startTime, startTime) XCTAssertEqual(spanData.endTime, endTime) - XCTAssertEqual(spanData.status.statusCode, status.statusCode) + XCTAssertEqual(spanData.status, status) XCTAssertEqual(spanData.hasEnded, hasEnded) } } diff --git a/Tests/OpenTelemetrySdkTests/Trace/SamplersTests.swift b/Tests/OpenTelemetrySdkTests/Trace/SamplersTests.swift index 22e34438..82b677eb 100644 --- a/Tests/OpenTelemetrySdkTests/Trace/SamplersTests.swift +++ b/Tests/OpenTelemetrySdkTests/Trace/SamplersTests.swift @@ -17,11 +17,11 @@ import OpenTelemetryApi @testable import OpenTelemetrySdk import XCTest -class ProbabilitySamplerTest: XCTestCase { +class SamplerTests: XCTestCase { let spanName = "MySpanName" let spanKind = SpanKind.internal let numSamplesTries = 1000 - let idsGenerator: IdsGenerator = RandomIdsGenerator() + let idGenerator: IdGenerator = RandomIdGenerator() var traceId: TraceId! var spanId: SpanId! var parentSpanId: SpanId! @@ -31,9 +31,9 @@ class ProbabilitySamplerTest: XCTestCase { var sampledParentLink: SpanData.Link! override func setUp() { - traceId = idsGenerator.generateTraceId() - spanId = idsGenerator.generateSpanId() - parentSpanId = idsGenerator.generateSpanId() + traceId = idGenerator.generateTraceId() + spanId = idGenerator.generateSpanId() + parentSpanId = idGenerator.generateSpanId() sampledSpanContext = SpanContext.create(traceId: traceId, spanId: parentSpanId, traceFlags: TraceFlags().settingIsSampled(true), traceState: traceState) notSampledSpanContext = SpanContext.create(traceId: traceId, spanId: parentSpanId, traceFlags: TraceFlags(), traceState: traceState) sampledParentLink = SpanData.Link(context: sampledSpanContext) @@ -59,32 +59,32 @@ class ProbabilitySamplerTest: XCTestCase { .isSampled) } - func testProbabilitySampler_AlwaysSample() { - let sampler = Probability(probability: 1) + func testTraceIdRatioBasedSampler_AlwaysSample() { + let sampler = TraceIdRatioBased(ratio: 1) XCTAssertEqual(sampler.idUpperBound, UInt.max) } - func testProbabilitySampler_NeverSample() { - let sampler = Probability(probability: 0) + func testTraceIdRatioBasedSampler_NeverSample() { + let sampler = TraceIdRatioBased(ratio: 0) XCTAssertEqual(sampler.idUpperBound, UInt.min) } - func testProbabilitySampler_outOfRangeHighProbability() { - let sampler = Probability(probability: 1.01) + func testTraceIdRatioBasedSampler_outOfRangeHighProbability() { + let sampler = TraceIdRatioBased(ratio: 1.01) XCTAssertEqual(sampler.idUpperBound, UInt.max) } - func testProbabilitySampler_outOfRangeLowProbability() { - let sampler = Probability(probability: -0.0001) + func testTraceIdRatioBasedSampler_outOfRangeLowProbability() { + let sampler = TraceIdRatioBased(ratio: -0.0001) XCTAssertEqual(sampler.idUpperBound, UInt.min) } - func testProbabilitySampler_getDescription() { - XCTAssertEqual(Probability(probability: 0.5).description, String(format: "ProbabilitySampler{%.6f}", 0.5)) + func testTraceIdRatioBasedSampler_getDescription() { + XCTAssertEqual(TraceIdRatioBased(ratio: 0.5).description, String(format: "TraceIdRatioBased{%.6f}", 0.5)) } - func testProbabilitySampler_ToString() { - XCTAssertTrue(Probability(probability: 0.5).description.contains("0.5")) + func testTraceIdRatioBasedSampler_ToString() { + XCTAssertTrue(TraceIdRatioBased(ratio: 0.5).description.contains("0.5")) } // Applies the given sampler to NUM_SAMPLE_TRIES random traceId/spanId pairs. @@ -106,34 +106,34 @@ class ProbabilitySamplerTest: XCTestCase { } func testProbabilitySampler_DifferentProbabilities_NotSampledParent() { - let fiftyPercentSample = Probability(probability: 0.5) + let fiftyPercentSample = TraceIdRatioBased(ratio: 0.5) assertSamplerSamplesWithProbability(sampler: fiftyPercentSample, parent: notSampledSpanContext, parentLinks: [SpanData.Link](), probability: 0.5) - let twentyPercentSample = Probability(probability: 0.2) + let twentyPercentSample = TraceIdRatioBased(ratio: 0.2) assertSamplerSamplesWithProbability(sampler: twentyPercentSample, parent: notSampledSpanContext, parentLinks: [SpanData.Link](), probability: 0.2) - let twoThirdsSample = Probability(probability: 2.0 / 3.0) + let twoThirdsSample = TraceIdRatioBased(ratio: 2.0 / 3.0) assertSamplerSamplesWithProbability(sampler: twoThirdsSample, parent: notSampledSpanContext, parentLinks: [SpanData.Link](), probability: 2.0 / 3.0) } func testProbabilitySampler_DifferentProbabilities_SampledParent() { - let fiftyPercentSample = Probability(probability: 0.5) + let fiftyPercentSample = TraceIdRatioBased(ratio: 0.5) assertSamplerSamplesWithProbability(sampler: fiftyPercentSample, parent: sampledSpanContext, parentLinks: [SpanData.Link](), probability: 1.0) - let twentyPercentSample = Probability(probability: 0.2) + let twentyPercentSample = TraceIdRatioBased(ratio: 0.2) assertSamplerSamplesWithProbability(sampler: twentyPercentSample, parent: sampledSpanContext, parentLinks: [SpanData.Link](), probability: 1.0) - let twoThirdsSample = Probability(probability: 2.0 / 3.0) + let twoThirdsSample = TraceIdRatioBased(ratio: 2.0 / 3.0) assertSamplerSamplesWithProbability(sampler: twoThirdsSample, parent: sampledSpanContext, parentLinks: [SpanData.Link](), probability: 1.0) } func testProbabilitySampler_DifferentProbabilities_SampledParentLink() { - let fiftyPercentSample = Probability(probability: 0.5) + let fiftyPercentSample = TraceIdRatioBased(ratio: 0.5) assertSamplerSamplesWithProbability(sampler: fiftyPercentSample, parent: notSampledSpanContext, parentLinks: [sampledParentLink], probability: 1.0) - let twentyPercentSample = Probability(probability: 0.2) + let twentyPercentSample = TraceIdRatioBased(ratio: 0.2) assertSamplerSamplesWithProbability(sampler: twentyPercentSample, parent: notSampledSpanContext, parentLinks: [sampledParentLink], probability: 1.0) - let twoThirdsSample = Probability(probability: 2.0 / 3.0) + let twoThirdsSample = TraceIdRatioBased(ratio: 2.0 / 3.0) assertSamplerSamplesWithProbability(sampler: twoThirdsSample, parent: notSampledSpanContext, parentLinks: [sampledParentLink], probability: 1.0) } func testProbabilitySampler_SampleBasedOnTraceId() { - let defaultProbability = Probability(probability: 0.0001) + let defaultProbability = TraceIdRatioBased(ratio: 0.0001) // This traceId will not be sampled by the ProbabilitySampler because the first 8 bytes as long // is not less than probability * Long.MAX_VALUE; let notSampledtraceId = TraceId(fromBytes: [0, 0, 0, 0, 0, 0, 0, 0, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) diff --git a/Tests/OpenTelemetrySdkTests/Trace/SpanBuilderSdkTests.swift b/Tests/OpenTelemetrySdkTests/Trace/SpanBuilderSdkTests.swift index 751bff67..01eb553a 100644 --- a/Tests/OpenTelemetrySdkTests/Trace/SpanBuilderSdkTests.swift +++ b/Tests/OpenTelemetrySdkTests/Trace/SpanBuilderSdkTests.swift @@ -53,8 +53,8 @@ class SpanBuilderSdkTest: XCTestCase { func testTruncateLink() { let maxNumberOfLinks = 8 - let traceConfig = tracerSdkFactory.getActiveTraceConfig().settingMaxNumberOfLinks(maxNumberOfLinks) - tracerSdkFactory.updateActiveTraceConfig(traceConfig) + let spanLimits = tracerSdkFactory.getActiveSpanLimits().settingLinkCountLimit(UInt(maxNumberOfLinks)) + tracerSdkFactory.updateActiveSpanLimits(spanLimits) // Verify methods do not crash. let spanBuilder = tracerSdk.spanBuilder(spanName: spanName) for _ in 0 ..< 2 * maxNumberOfLinks { @@ -69,7 +69,7 @@ class SpanBuilderSdkTest: XCTestCase { XCTAssertEqual(spanData.totalRecordedLinks, 2 * maxNumberOfLinks) } span.end() - tracerSdkFactory.updateActiveTraceConfig(TraceConfig()) + tracerSdkFactory.updateActiveSpanLimits(SpanLimits()) } func testSetAttribute() { @@ -103,8 +103,8 @@ class SpanBuilderSdkTest: XCTestCase { func testDroppingAttributes() { let maxNumberOfAttrs = 8 - let traceConfig = tracerSdkFactory.getActiveTraceConfig().settingMaxNumberOfAttributes(maxNumberOfAttrs) - tracerSdkFactory.updateActiveTraceConfig(traceConfig) + let spanLimits = tracerSdkFactory.getActiveSpanLimits().settingAttributeCountLimit(UInt(maxNumberOfAttrs)) + tracerSdkFactory.updateActiveSpanLimits(spanLimits) let spanBuilder = tracerSdk.spanBuilder(spanName: spanName) for i in 0 ..< 2 * maxNumberOfAttrs { spanBuilder.setAttribute(key: "key\(i)", value: i) @@ -116,7 +116,7 @@ class SpanBuilderSdkTest: XCTestCase { XCTAssertEqual(attrs["key\(i + maxNumberOfAttrs)"], AttributeValue.int(i + maxNumberOfAttrs)) } span.end() - tracerSdkFactory.updateActiveTraceConfig(TraceConfig()) + tracerSdkFactory.updateActiveSpanLimits(SpanLimits()) } func testRecordEvents_default() { @@ -137,9 +137,11 @@ class SpanBuilderSdkTest: XCTestCase { } func testSampler() { - let span = TestUtils.startSpanWithSampler(tracerSdkFactory: tracerSdkFactory, - tracer: tracerSdk, spanName: spanName, - sampler: Samplers.alwaysOff).startSpan() + let span = TestUtils.createSpanWithSampler(tracerSdkFactory: tracerSdkFactory, + tracer: tracerSdk, spanName: spanName, + sampler: Samplers.alwaysOff) + .startSpan() + XCTAssertFalse(span.context.traceFlags.sampled) span.end() } @@ -154,7 +156,8 @@ class SpanBuilderSdkTest: XCTestCase { name: String, kind: SpanKind, attributes: [String: AttributeValue], - parentLinks: [SpanData.Link]) -> Decision { + parentLinks: [SpanData.Link]) -> Decision + { return decision } @@ -174,11 +177,11 @@ class SpanBuilderSdkTest: XCTestCase { let decision = TestDecision() let sampler = TestSampler(decision: decision) - let span = TestUtils.startSpanWithSampler(tracerSdkFactory: tracerSdkFactory, - tracer: tracerSdk, - spanName: spanName, - sampler: sampler, - attributes: [SpanBuilderSdkTest.samplerAttributeName: AttributeValue.string("none")]) + let span = TestUtils.createSpanWithSampler(tracerSdkFactory: tracerSdkFactory, + tracer: tracerSdk, + spanName: spanName, + sampler: sampler, + attributes: [SpanBuilderSdkTest.samplerAttributeName: AttributeValue.string("none")]) .startSpan() as! RecordEventsReadableSpan XCTAssertTrue(span.context.traceFlags.sampled) XCTAssertTrue(span.toSpanData().attributes.keys.contains(SpanBuilderSdkTest.samplerAttributeName)) @@ -186,9 +189,9 @@ class SpanBuilderSdkTest: XCTestCase { } func testSampledViaParentLinks() { - let span = TestUtils.startSpanWithSampler(tracerSdkFactory: tracerSdkFactory, - tracer: tracerSdk, spanName: spanName, - sampler: Samplers.probability(probability: 0.0)) + let span = TestUtils.createSpanWithSampler(tracerSdkFactory: tracerSdkFactory, + tracer: tracerSdk, spanName: spanName, + sampler: Samplers.traceIdRatio(ratio: 0.0)) .addLink(spanContext: sampledSpanContext) .startSpan() XCTAssertTrue(span.context.traceFlags.sampled) diff --git a/Tests/OpenTelemetrySdkTests/Trace/SpanLimitTests.swift b/Tests/OpenTelemetrySdkTests/Trace/SpanLimitTests.swift new file mode 100644 index 00000000..d3879bb8 --- /dev/null +++ b/Tests/OpenTelemetrySdkTests/Trace/SpanLimitTests.swift @@ -0,0 +1,41 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import OpenTelemetryApi +import OpenTelemetrySdk +import XCTest + +class SpanLimitTests: XCTestCase { + func testDefaultSpanLimits() { + XCTAssertEqual(SpanLimits().attributeCountLimit, 128) + XCTAssertEqual(SpanLimits().eventCountLimit, 128) + XCTAssertEqual(SpanLimits().linkCountLimit, 128) + XCTAssertEqual(SpanLimits().attributePerEventCountLimit, 128) + XCTAssertEqual(SpanLimits().attributePerLinkCountLimit, 128) + } + + func testUpdateSpanLimit_All() { + let spanLimits = SpanLimits().settingAttributeCountLimit(8) + .settingEventCountLimit(10) + .settingLinkCountLimit(11) + .settingAttributePerEventCountLimit(1) + .settingAttributePerLinkCountLimit(2) + XCTAssertEqual(spanLimits.attributeCountLimit, 8) + XCTAssertEqual(spanLimits.eventCountLimit, 10) + XCTAssertEqual(spanLimits.linkCountLimit, 11) + XCTAssertEqual(spanLimits.attributePerEventCountLimit, 1) + XCTAssertEqual(spanLimits.attributePerLinkCountLimit, 2) + } +} diff --git a/Tests/OpenTelemetrySdkTests/Trace/TestUtils.swift b/Tests/OpenTelemetrySdkTests/Trace/TestUtils.swift index a0c43819..93949471 100644 --- a/Tests/OpenTelemetrySdkTests/Trace/TestUtils.swift +++ b/Tests/OpenTelemetrySdkTests/Trace/TestUtils.swift @@ -45,14 +45,12 @@ struct TestUtils { hasEnded: true) } - static func startSpanWithSampler(tracerSdkFactory: TracerSdkProvider, tracer: Tracer, spanName: String, sampler: Sampler) -> SpanBuilder { - return startSpanWithSampler(tracerSdkFactory: tracerSdkFactory, tracer: tracer, spanName: spanName, sampler: sampler, attributes: [String: AttributeValue]()) + static func createSpanWithSampler(tracerSdkFactory: TracerSdkProvider, tracer: Tracer, spanName: String, sampler: Sampler) -> SpanBuilder { + return createSpanWithSampler(tracerSdkFactory: tracerSdkFactory, tracer: tracer, spanName: spanName, sampler: sampler, attributes: [String: AttributeValue]()) } - static func startSpanWithSampler(tracerSdkFactory: TracerSdkProvider, tracer: Tracer, spanName: String, sampler: Sampler, attributes: [String: AttributeValue]) -> SpanBuilder { - let originalConfig = tracerSdkFactory.getActiveTraceConfig() - tracerSdkFactory.updateActiveTraceConfig(originalConfig.settingSampler(sampler)) - defer { tracerSdkFactory.updateActiveTraceConfig(originalConfig) } + static func createSpanWithSampler(tracerSdkFactory: TracerSdkProvider, tracer: Tracer, spanName: String, sampler: Sampler, attributes: [String: AttributeValue]) -> SpanBuilder { + tracerSdkFactory.sharedState.setSampler(sampler) let builder = tracer.spanBuilder(spanName: spanName) for attribute in attributes { builder.setAttribute(key: attribute.key, value: attribute.value)