diff --git a/.github/workflows/BuildAndTest.yml b/.github/workflows/BuildAndTest.yml index d01514b7..8a40743d 100644 --- a/.github/workflows/BuildAndTest.yml +++ b/.github/workflows/BuildAndTest.yml @@ -38,7 +38,7 @@ jobs: run: | curl -Os https://uploader.codecov.io/latest/macos/codecov chmod +x codecov - xcrun llvm-cov export -ignore-filename-regex="pb\.swift|grpc\.swift" -format="lcov" .build/debug/opentelemetry-swiftPackageTests.xctest/Contents/MacOS/opentelemetry-swiftPackageTests -instr-profile .build/debug/codecov/default.profdata > .build/debug/codecov/coverage_report.lcov + xcrun llvm-cov export -ignore-filename-regex="pb\.swift|grpc\.swift" -format="lcov" .build/debug/opentelemetry-swift-corePackageTests.xctest/Contents/MacOS/opentelemetry-swift-corePackageTests -instr-profile .build/debug/codecov/default.profdata > .build/debug/codecov/coverage_report.lcov ./codecov -f .build/debug/codecov/coverage_report.lcov iOS: runs-on: macos-15 diff --git a/.github/workflows/Create-Release-PR.yml b/.github/workflows/Create-Release-PR.yml index 17c636ca..1a1e0fd7 100644 --- a/.github/workflows/Create-Release-PR.yml +++ b/.github/workflows/Create-Release-PR.yml @@ -34,14 +34,7 @@ jobs: run: | sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-Api.podspec sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-Sdk.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-BaggagePropagationProcessor.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-Instrumentation-NetworkStatus.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-Instrumentation-URLSession.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-Protocol-Exporter-Common.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-Protocol-Exporter-Http.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-SdkResourceExtension.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-StdoutExporter.podspec - sed -i -e 's/spec.version = ".*"/spec.version = "${{ inputs.new_version }}"/' OpenTelemetry-Swift-PersistenceExporter.podspec + - name: Create Pull Request uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 diff --git a/.github/workflows/Tag-And-Release.yml b/.github/workflows/Tag-And-Release.yml index e3f84ec7..bc18f8a8 100644 --- a/.github/workflows/Tag-And-Release.yml +++ b/.github/workflows/Tag-And-Release.yml @@ -43,12 +43,4 @@ jobs: run: | pod trunk push OpenTelemetry-Swift-Api.podspec --allow-warnings pod trunk push OpenTelemetry-Swift-Sdk.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-BaggagePropagationProcessor.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-Instrumentation-NetworkStatus.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-Instrumentation-URLSession.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-Protocol-Exporter-Common.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-SdkResourceExtension.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-Protocol-Exporter-Http.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-PersistenceExporter.podspec --allow-warnings --synchronous - pod trunk push OpenTelemetry-Swift-StdoutExporter.podspec --allow-warnings --synchronous diff --git a/CODEOWNERS b/CODEOWNERS index 7ce4f29f..e834176a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,6 +1,6 @@ ##################################################### # -# List of approvers for OpenTelemetry Swift SDK +# List of approvers for OpenTelemetry Swift Core # ##################################################### # diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f957d1e..016b7b0a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -125,60 +125,6 @@ merge. You'll probably get some feedback from these fine folks which helps to make the project that much better. Respond to the feedback and work with your reviewer(s) to resolve any issues. -### Generating OTLP protobuf files -Occasionally, the opentelemetry protocol's protobuf definitions are updated and need to be regenerated for the OTLP exporters. This is documentation on how to accomplish that for this project. Other projects can regenerate their otlp protobuf files using the [Open Telemetry build tools][build-tools]. - -#### Requirements -- [protoc] -- [grpc-swift] -- [opentelemetry-proto] - -##### Install protoc -```asciidoc -$ brew install protobuf -$ protoc --version # Ensure compiler version is 3+ -``` -##### Installing grpc-swift -``` - brew install swift-protobuf grpc-swift - ``` - -##### Generating otlp protobuf files - -Clone [opentelemetry-proto] - -From within opentelemetry-proto: - -```shell -# collect the proto definitions: -PROTO_FILES=($(ls opentelemetry/proto/*/*/*/*.proto opentelemetry/proto/*/*/*.proto)) -# generate swift proto files -for file in "${PROTO_FILES[@]}" -do - protoc --swift_opt=Visibility=Public --swift_out=./out ${file} -done - -# genearate GRPC swift proto files -protoc --swift_opt=Visibility=Public --grpc-swift_opt=Visibility=Public --swift_out=./out --grpc-swift_out=./out opentelemetry/proto/collector/trace/v1/trace_service.proto -protoc --swift_opt=Visibility=Public --grpc-swift_opt=Visibility=Public --swift_out=./out --grpc-swift_out=./out opentelemetry/proto/collector/metrics/v1/metrics_service.proto -protoc --swift_opt=Visibility=Public --grpc-swift_opt=Visibility=Public --swift_out=./out --grpc-swift_out=./out opentelemetry/proto/collector/logs/v1/logs_service.proto -``` - -Replace the generated files in `Sources/Exporters/OpenTelemetryProtocolCommon/proto` & `Sources/Exporters/OpenTelemetryGrpc/proto`: -###### `OpenTelemetryProtocolGrpc/proto` file list -`logs_service.grpc.swift` -`metrics_serivce.grpc.swift` -`trace_service.grpc.swift` - -###### `OpenTelemetryProtocolCommon/proto` -`common.pb.swift` -`logs.pb.swift` -`logs_service.pb.swift` -`metrics.pb.swift` -`metrics_services.pb.swift` -`resource.pb.swift` -`trace.pb.swift` -`trace_service.pb.swift` [cncf-cla]: https://identity.linuxfoundation.org/projects/cncf [github-draft]: https://github.blog/2019-02-14-introducing-draft-pull-requests/ @@ -187,7 +133,4 @@ Replace the generated files in `Sources/Exporters/OpenTelemetryProtocolCommon/pr [otel-github-workflow]: https://github.com/open-telemetry/community/blob/master/CONTRIBUTING.md#github-workflow [otel-lib-guidelines]: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/library-guidelines.md [otel-specification]: https://github.com/open-telemetry/opentelemetry-specification -[grpc-swift]: https://github.com/grpc/grpc-swift -[opentelemetry-proto]: https://github.com/open-telemetry/opentelemetry-proto -[protoc]: https://grpc.io/docs/protoc-installation/ [build-tools]: https://github.com/open-telemetry/build-tools diff --git a/Examples/Custom HTTPClient/README.md b/Examples/Custom HTTPClient/README.md deleted file mode 100644 index 1e6f5856..00000000 --- a/Examples/Custom HTTPClient/README.md +++ /dev/null @@ -1,166 +0,0 @@ -# Custom HTTPClient Example - -This example demonstrates how to use a custom HTTPClient implementation with OpenTelemetry HTTP exporters for authentication and other custom behaviors. - -## Token Refresh HTTPClient - -```swift -import Foundation -import OpenTelemetryProtocolExporterHttp - -class AuthTokenHTTPClient: HTTPClient { - private let session: URLSession - private var authToken: String? - private let tokenRefreshURL: URL - - init(session: URLSession = URLSession.shared, tokenRefreshURL: URL) { - self.session = session - self.tokenRefreshURL = tokenRefreshURL - } - - func send(request: URLRequest, completion: @escaping (Result) -> Void) { - var authorizedRequest = request - - // Add auth token if available - if let token = authToken { - authorizedRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") - } - - let task = session.dataTask(with: authorizedRequest) { [weak self] data, response, error in - if let httpResponse = response as? HTTPURLResponse { - // Check if token expired (401) - if httpResponse.statusCode == 401 { - self?.refreshTokenAndRetry(request: request, completion: completion) - return - } - - // Handle response normally - if let error = error { - completion(.failure(error)) - } else { - completion(.success(httpResponse)) - } - } else if let error = error { - completion(.failure(error)) - } - } - task.resume() - } - - private func refreshTokenAndRetry(request: URLRequest, completion: @escaping (Result) -> Void) { - // Implement your token refresh logic here - var tokenRequest = URLRequest(url: tokenRefreshURL) - tokenRequest.httpMethod = "POST" - - let task = session.dataTask(with: tokenRequest) { [weak self] data, response, error in - if let data = data, - let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], - let newToken = json["access_token"] as? String { - self?.authToken = newToken - // Retry original request with new token - self?.send(request: request, completion: completion) - } else { - completion(.failure(error ?? URLError(.userAuthenticationRequired))) - } - } - task.resume() - } -} - -// Usage -let customHTTPClient = AuthTokenHTTPClient(tokenRefreshURL: URL(string: "https://auth.example.com/token")!) -let exporter = OtlpHttpTraceExporter( - endpoint: URL(string: "https://api.example.com/v1/traces")!, - httpClient: customHTTPClient -) -``` - -## Retry HTTPClient - -```swift -class RetryHTTPClient: HTTPClient { - private let baseClient: HTTPClient - private let maxRetries: Int - - init(baseClient: HTTPClient = BaseHTTPClient(), maxRetries: Int = 3) { - self.baseClient = baseClient - self.maxRetries = maxRetries - } - - func send(request: URLRequest, completion: @escaping (Result) -> Void) { - sendWithRetry(request: request, attempt: 0, completion: completion) - } - - private func sendWithRetry(request: URLRequest, attempt: Int, completion: @escaping (Result) -> Void) { - baseClient.send(request: request) { [weak self] result in - switch result { - case .success(let response): - if response.statusCode >= 500 && attempt < self?.maxRetries ?? 0 { - // Retry on server errors - DispatchQueue.global().asyncAfter(deadline: .now() + pow(2.0, Double(attempt))) { - self?.sendWithRetry(request: request, attempt: attempt + 1, completion: completion) - } - } else { - completion(result) - } - case .failure: - if attempt < self?.maxRetries ?? 0 { - DispatchQueue.global().asyncAfter(deadline: .now() + pow(2.0, Double(attempt))) { - self?.sendWithRetry(request: request, attempt: attempt + 1, completion: completion) - } - } else { - completion(result) - } - } - } - } -} -``` - -## Custom Headers HTTPClient - -```swift -class CustomHeadersHTTPClient: HTTPClient { - private let baseClient: HTTPClient - private let customHeaders: [String: String] - - init(baseClient: HTTPClient = BaseHTTPClient(), customHeaders: [String: String]) { - self.baseClient = baseClient - self.customHeaders = customHeaders - } - - func send(request: URLRequest, completion: @escaping (Result) -> Void) { - var modifiedRequest = request - - // Add custom headers - for (key, value) in customHeaders { - modifiedRequest.setValue(value, forHTTPHeaderField: key) - } - - baseClient.send(request: modifiedRequest, completion: completion) - } -} - -// Usage -let customClient = CustomHeadersHTTPClient( - customHeaders: [ - "X-API-Key": "your-api-key", - "X-Client-Version": "1.0.0" - ] -) -let exporter = OtlpHttpLogExporter( - endpoint: URL(string: "https://api.example.com/v1/logs")!, - httpClient: customClient -) -``` - -## Benefits - -Using custom HTTPClient implementations allows you to: - -- **Authentication**: Implement OAuth2, API key, or other authentication schemes -- **Retries**: Add exponential backoff retry logic for resilient telemetry export -- **Custom Headers**: Add API keys, client versions, or other required headers -- **Request Modification**: Transform requests before sending (e.g., compression, encryption) -- **Response Handling**: Custom error handling and response processing -- **Testing**: Mock HTTP clients for unit testing exporters \ No newline at end of file diff --git a/Examples/Logging Tracer/Logger.swift b/Examples/Logging Tracer/Logger.swift deleted file mode 100644 index 7ad4be3c..00000000 --- a/Examples/Logging Tracer/Logger.swift +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -class Logger { - static let startTime = Date() - - static func printHeader() { - print("TimeSinceStart | ThreadId | API") - } - - static func log(_ s: String) { - let output = String(format: "%.9f | %@ | %@", timeSinceStart(), Thread.current.description, s) - print(output) - } - - private static func timeSinceStart() -> Double { - let start = startTime - return Date().timeIntervalSince(start) - } -} diff --git a/Examples/Logging Tracer/LoggingBinaryFormat.swift b/Examples/Logging Tracer/LoggingBinaryFormat.swift deleted file mode 100644 index 2b6e32f8..00000000 --- a/Examples/Logging Tracer/LoggingBinaryFormat.swift +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -struct LoggingBinaryFormat: BinaryFormattable { - func fromByteArray(bytes: [UInt8]) -> SpanContext? { - Logger.log("LoggingBinaryFormat.FromByteArray(...)") - return nil - } - - func toByteArray(spanContext: SpanContext) -> [UInt8] { - Logger.log("LoggingBinaryFormat.ToByteArray({spanContext})") - return [UInt8]() - } -} diff --git a/Examples/Logging Tracer/LoggingSpan.swift b/Examples/Logging Tracer/LoggingSpan.swift deleted file mode 100644 index 00f480bd..00000000 --- a/Examples/Logging Tracer/LoggingSpan.swift +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -class LoggingSpan: Span { - var name: String - var kind: SpanKind - var context: SpanContext - var isRecording: Bool = true - var status: Status = .unset - - public init(name: String, kind: SpanKind) { - self.name = name - self.kind = kind - context = SpanContext.create(traceId: TraceId.random(), - spanId: SpanId.random(), - traceFlags: TraceFlags(), - traceState: TraceState()) - } - - public var description: String { - return name - } - - public func updateName(name: String) { - Logger.log("Span.updateName(\(name))") - self.name = name - } - - public func setAttribute(key: String, value: String) { - Logger.log("Span.setAttribute(key: \(key), value: \(value))") - } - - public func setAttribute(key: String, value: Int) { - Logger.log("Span.setAttribute(key: \(key), value: \(value))") - } - - public func setAttribute(key: String, value: Double) { - Logger.log("Span.setAttribute(key: \(key), value: \(value))") - } - - public func setAttribute(key: String, value: Bool) { - Logger.log("Span.setAttribute(key: \(key), value: \(value))") - } - - public func setAttribute(key: String, value: AttributeValue?) { - Logger.log("Span.setAttribute(key: \(key), value: \(String(describing: value)))") - } - - public func setAttribute(keyValuePair: (String, AttributeValue)) { - Logger.log("Span.SetAttributes(keyValue: \(keyValuePair))") - setAttribute(key: keyValuePair.0, value: keyValuePair.1) - } - - public func setAttributes( - _ attributes: [String: OpenTelemetryApi.AttributeValue] - ) { - attributes.forEach { key, value in - setAttribute(key: key, value: value) - } - } - - public func addEvent(name: String) { - Logger.log("Span.addEvent(\(name))") - } - - public func addEvent(name: String, timestamp: Date) { - Logger.log("Span.addEvent(\(name) timestamp:\(timestamp))") - } - - public func addEvent(name: String, attributes: [String: AttributeValue]) { - Logger.log("Span.addEvent(\(name), attributes:\(attributes) )") - } - - public func addEvent(name: String, attributes: [String: AttributeValue], timestamp: Date) { - Logger.log("Span.addEvent(\(name), attributes:\(attributes), timestamp:\(timestamp))") - } - - public func recordException(_ exception: SpanException) { - Logger.log("Span.recordException(\(exception)") - } - - public func recordException(_ exception: SpanException, timestamp: Date) { - Logger.log("Span.recordException(\(exception), timestamp:\(timestamp))") - } - - public func recordException(_ exception: SpanException, attributes: [String: AttributeValue]) { - Logger.log("Span.recordException(\(exception), attributes:\(attributes)") - } - - public func recordException(_ exception: SpanException, attributes: [String: AttributeValue], timestamp: Date) { - Logger.log("Span.recordException(\(exception), attributes:\(attributes), timestamp:\(timestamp))") - } - - public func end() { - Logger.log("Span.End, Name: \(name)") - } - - public func end(time: Date) { - Logger.log("Span.End, Name: \(name), time:\(time)) }") - } -} diff --git a/Examples/Logging Tracer/LoggingTextFormat.swift b/Examples/Logging Tracer/LoggingTextFormat.swift deleted file mode 100644 index e81a390a..00000000 --- a/Examples/Logging Tracer/LoggingTextFormat.swift +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -class LoggingTextFormat: TextMapPropagator { - var fields = Set() - - func inject(spanContext: SpanContext, carrier: inout [String: String], setter: some Setter) { - Logger.log("LoggingTextFormat.Inject(\(spanContext), ...)") - } - - func extract(carrier: [String: String], getter: some Getter) -> SpanContext? { - Logger.log("LoggingTextFormat.Extract(...)") - return nil - } -} diff --git a/Examples/Logging Tracer/LoggingTracer.swift b/Examples/Logging Tracer/LoggingTracer.swift deleted file mode 100644 index 198effcc..00000000 --- a/Examples/Logging Tracer/LoggingTracer.swift +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -class LoggingTracer: Tracer { - let tracerName = "LoggingTracer" - - var binaryFormat: BinaryFormattable = LoggingBinaryFormat() - var textFormat: TextMapPropagator = W3CTraceContextPropagator() - - func spanBuilder(spanName: String) -> SpanBuilder { - return LoggingSpanBuilder(tracer: self, spanName: spanName) - } - - class LoggingSpanBuilder: SpanBuilder { - private var tracer: Tracer - private var isRootSpan: Bool = false - private var spanContext: SpanContext? - private var name: String - - init(tracer: Tracer, spanName: String) { - self.tracer = tracer - name = spanName - } - - func startSpan() -> Span { - return LoggingSpan(name: name, kind: .client) - } - - func setParent(_ parent: Span) -> Self { - spanContext = parent.context - return self - } - - func setParent(_ parent: SpanContext) -> Self { - spanContext = parent - return self - } - - func setNoParent() -> Self { - isRootSpan = true - return self - } - - func addLink(spanContext: SpanContext) -> Self { - return self - } - - func addLink(spanContext: SpanContext, attributes: [String: AttributeValue]) -> Self { - return self - } - - func setSpanKind(spanKind: SpanKind) -> Self { - return self - } - - func setStartTime(time: Date) -> Self { - return self - } - - func setAttribute(key: String, value: AttributeValue) -> Self { - return self - } - - func setActive(_ active: Bool) -> Self { - return self - } - - func withActiveSpan(_ operation: (any SpanBase) throws -> T) rethrows -> T { - let span = startSpan() - defer { - span.end() - } - return try operation(span) - } - - #if canImport(_Concurrency) - @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) - func withActiveSpan(_ operation: (any SpanBase) async throws -> T) async rethrows -> T { - let span = startSpan() - defer { - span.end() - } - return try await operation(span) - } - #endif - } -} diff --git a/Examples/Logging Tracer/LoggingTracerProvider.swift b/Examples/Logging Tracer/LoggingTracerProvider.swift deleted file mode 100644 index 5db34ed4..00000000 --- a/Examples/Logging Tracer/LoggingTracerProvider.swift +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -class LoggingTracerProvider: TracerProvider { - func get(instrumentationName: String, instrumentationVersion: String?, - schemaUrl: String? = nil, - attributes: [String: AttributeValue]? = nil) -> any Tracer { - Logger - .log( - "TracerFactory.get(\(instrumentationName), \(instrumentationVersion ?? ""), \(schemaUrl ?? ""), \(attributes ?? [:])" - ) - var labels = [String: String]() - labels["instrumentationName"] = instrumentationName - labels["instrumentationVersion"] = instrumentationVersion - labels["schemaUrl"] = schemaUrl - labels["attributes"] = attributes?.description - return LoggingTracer() - } -} diff --git a/Examples/Logging Tracer/main.swift b/Examples/Logging Tracer/main.swift deleted file mode 100644 index 9b05d8de..00000000 --- a/Examples/Logging Tracer/main.swift +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -Logger.printHeader() - -OpenTelemetry.registerTracerProvider(tracerProvider: LoggingTracerProvider()) - -var tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "ConsoleApp", instrumentationVersion: "semver:1.0.0") - -let span1 = tracer.spanBuilder(spanName: "Main (span1)").startSpan() -OpenTelemetry.instance.contextProvider.setActiveSpan(span1) -let semaphore = DispatchSemaphore(value: 0) -DispatchQueue.global().async { - let span2 = tracer.spanBuilder(spanName: "Main (span2)").startSpan() - OpenTelemetry.instance.contextProvider.setActiveSpan(span2) - OpenTelemetry.instance.contextProvider.activeSpan?.setAttribute(key: "myAttribute", value: "myValue") - sleep(1) - span2.end() - semaphore.signal() -} - -span1.end() - -semaphore.wait() diff --git a/Examples/Logs Sample/main.swift b/Examples/Logs Sample/main.swift deleted file mode 100644 index acf34ed8..00000000 --- a/Examples/Logs Sample/main.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import OpenTelemetryProtocolExporterGrpc -import Logging -import GRPC -import NIO - -func configure() { - let configuration = ClientConnection.Configuration.default(target: .hostAndPort("localhost", 4317), - eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1)) - - OpenTelemetry.registerLoggerProvider(loggerProvider: LoggerProviderBuilder().with(processors: [ - BatchLogRecordProcessor(logRecordExporter: OtlpLogExporter(channel: ClientConnection(configuration: configuration))) - ]).build()) -} - -configure() - -let eventProvider = OpenTelemetry.instance.loggerProvider.loggerBuilder(instrumentationScopeName: "myScope").setEventDomain("device").build() diff --git a/Examples/Metric Sample/main.swift b/Examples/Metric Sample/main.swift deleted file mode 100644 index e9ed8878..00000000 --- a/Examples/Metric Sample/main.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -func configure() { - let configuration = ClientConnection.Configuration.default(target: .hostAndPort("localhost", 4317), - eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1)) - let client = ClientConnection(configuration: configuration) - - let resource = Resource(attributes: ["service.name": "StableMetricExample"]).merge(other: resource()) - - OpenTelemetry.registerMeterProvider(meterProvider: StableMeterProviderSdk.builder(). - registerMetricReader(reader: StablePeriodicMetricReaderBuilder(exporter: StableOtlpMetricExporter(channel: client)) - .setInterval(timeInterval: 60).build()).build()) -} - -configure() diff --git a/Examples/Network Sample/README.md b/Examples/Network Sample/README.md deleted file mode 100644 index 1d6ec129..00000000 --- a/Examples/Network Sample/README.md +++ /dev/null @@ -1,4 +0,0 @@ -### Network sample - -This example shows the `URLSessionInstrumentation` in action. -It only shows the minimum configuration: Just by initializing the class, all network request that happen after it will be captured by Opentelemetry as Spans. Check [`URLSessionInstrumentation` README](Sources/Instrumentation/URLSession/README.md) for more information. diff --git a/Examples/Network Sample/main.swift b/Examples/Network Sample/main.swift deleted file mode 100644 index 4a8e8136..00000000 --- a/Examples/Network Sample/main.swift +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import StdoutExporter -import URLSessionInstrumentation - -func simpleNetworkCall() { - let url = URL(string: "http://httpbin.org/get")! - let request = URLRequest(url: url) - let semaphore = DispatchSemaphore(value: 0) - - let task = URLSession.shared.dataTask(with: request) { data, _, _ in - if let data { - let string = String(bytes: data, encoding: .utf8) - print(string as Any) - } - semaphore.signal() - } - task.resume() - - semaphore.wait() -} - -class SessionDelegate: NSObject, URLSessionDataDelegate, URLSessionTaskDelegate { - let semaphore = DispatchSemaphore(value: 0) - var callCount = 0 - - func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - semaphore.signal() - } - - func urlSession(_ session: URLSession, - task: URLSessionTask, - didFinishCollecting metrics: URLSessionTaskMetrics) { - semaphore.signal() - callCount += 1 - print("delegate called") - } -} - -let delegate = SessionDelegate() - -enum TimeoutError: Error { - case timeout -} - -func waitForSemaphore(withTimeoutSecs: Int) async { - do { - _ = try await withThrowingTaskGroup(of: Bool.self) { group in - group.addTask { - try await Task.sleep(nanoseconds: UInt64(withTimeoutSecs) * NSEC_PER_SEC) - throw TimeoutError.timeout - } - group.addTask { - let semaphoreTask = Task { - DispatchQueue.global().async { - delegate.semaphore.wait() - } - } - await semaphoreTask.value - try Task.checkCancellation() - return true - } - - return try await group.next()! - } - } catch { - print("timed out waiting for semaphore") - } -} - -func simpleNetworkCallWithDelegate() { - let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil) - - let url = URL(string: "http://httpbin.org/get")! - let request = URLRequest(url: url) - - let task = session.dataTask(with: request) - task.resume() - - delegate.semaphore.wait() -} - -@available(macOS 10.15, iOS 15.0, watchOS 8.0, tvOS 15.0, *) -func asyncNetworkCallWithTaskDelegate() async { - let session = URLSession(configuration: .default) - - let url = URL(string: "http://httpbin.org/get")! - let request = URLRequest(url: url) - - do { - _ = try await session.data(for: request, delegate: delegate) - } catch { - return - } - - await waitForSemaphore(withTimeoutSecs: 3) -} - -@available(macOS 10.15, iOS 15.0, tvOS 13.0, *) -func asyncNetworkCallWithSessionDelegate() async { - let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil) - - let url = URL(string: "http://httpbin.org/get")! - let request = URLRequest(url: url) - - do { - _ = try await session.data(for: request) - } catch { - return - } - - await waitForSemaphore(withTimeoutSecs: 3) -} - -let spanProcessor = SimpleSpanProcessor(spanExporter: StdoutSpanExporter(isDebug: true)) -OpenTelemetry.registerTracerProvider(tracerProvider: - TracerProviderBuilder() - .add(spanProcessor: spanProcessor) - .build() -) - -let networkInstrumentation = URLSessionInstrumentation(configuration: URLSessionInstrumentationConfiguration()) - -print("making simple call") -var callCount = delegate.callCount -simpleNetworkCallWithDelegate() -assert(delegate.callCount == callCount + 1) - -if #available(macOS 10.15, iOS 15.0, watchOS 8.0, tvOS 15.0, *) { - print("making simple call with task delegate") - callCount = delegate.callCount - await asyncNetworkCallWithTaskDelegate() - assert(delegate.callCount == callCount + 1, "async task delegate not called") - - print("making simple call with session delegate") - callCount = delegate.callCount - await asyncNetworkCallWithSessionDelegate() - assert(delegate.callCount == callCount + 1, "async session delegate not called") -} - -sleep(1) diff --git a/Examples/OTLP Exporter/README.md b/Examples/OTLP Exporter/README.md deleted file mode 100644 index d019f1f9..00000000 --- a/Examples/OTLP Exporter/README.md +++ /dev/null @@ -1,57 +0,0 @@ -### OTLP Exporter Example - -This example shows how to use [OTLP Exporter](https://github.com/open-telemetry/opentelemetry-swift/tree/main/Sources/Exporters/OpenTelemetryProtocol) to instrument a simple Swift application. - -This example will export spans data simultaneously using [OTLP Exporter ](https://github.com/open-telemetry/opentelemetry-swift/tree/main/Sources/Exporters/OpenTelemetryProtocol) and grpc. It will use [proto format](https://github.com/open-telemetry/opentelemetry-proto). - - -## Run the Application - -1. Run docker: This will start otel-collector, Zipkin and Prometheus - - ```shell script - # from this directory - docker-compose up - ``` - -2. Run app - - ```shell script - # from this directory - swift run OTLPExporter - ``` - -3. Teardown the docker images - - ```shell script - # from this directory - docker-compose down - ``` - -4. Open page at - you should be able to see the spans in zipkin -![Screenshot of the running example](images/zipkin-spans.png) - -### Prometheus UI - -The prometheus client will be available at . - -Note: It may take some time for the application metrics to appear on the Prometheus dashboard. -![Screenshot of the running example](images/prometheus-metrics.png) - -5. If you don't set service.name as per https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md the default name of the service and spans generate by the OTLP Exporter is `unknown_service:otlpexporter` You can either set the service.name by editing the schema in Xcode and the set the environment variable for OTEL_RESOURCE_ATTRIBUTES, or set it via command line: - - ```shell script - # from this directory - OTEL_RESOURCE_ATTRIBUTES="service.name=my-swift-app,service.version=v1.2.3" swift run OTLPExporter - ``` -This will create a service and spans with the name `my-swift-app` - -## Useful links - -- For more information on OpenTelemetry, visit: -- For more information on trace, visit: -- For more information on metrics, visit: - -## LICENSE - -Apache License 2.0 diff --git a/Examples/OTLP Exporter/collector-config.yaml b/Examples/OTLP Exporter/collector-config.yaml deleted file mode 100644 index 1a965a12..00000000 --- a/Examples/OTLP Exporter/collector-config.yaml +++ /dev/null @@ -1,37 +0,0 @@ -receivers: - otlp: - protocols: - grpc: - http: - cors: - allowed_origins: - - http://* - - https://* - -exporters: - zipkin: - endpoint: "http://zipkin-all-in-one:9411/api/v2/spans" - prometheus: - endpoint: "0.0.0.0:9464" - -processors: - resource: - attributes: - - key: service.name - value: OTLP Exporter - action: insert - batch: - -service: - telemetry: - logs: - level: "debug" - pipelines: - traces: - receivers: [otlp] - exporters: [zipkin] - processors: [resource, batch] - metrics: - receivers: [otlp] - exporters: [prometheus] - processors: [resource, batch] diff --git a/Examples/OTLP Exporter/docker-compose.yaml b/Examples/OTLP Exporter/docker-compose.yaml deleted file mode 100644 index 870cc26c..00000000 --- a/Examples/OTLP Exporter/docker-compose.yaml +++ /dev/null @@ -1,32 +0,0 @@ -version: "3" -services: - # Collector - collector: - image: otel/opentelemetry-collector:0.131.1@sha256:e601f0d6d77e6d61491db0d79d45534ac7d9c8c655a8d69085a0000257895059 -# The latest image of the otel-collector may not work, so specifying the version that works with this release -# image: otel/opentelemetry-collector:latest - command: ["--config=/conf/collector-config.yaml"] - volumes: - - ./collector-config.yaml:/conf/collector-config.yaml - ports: - - "9464:9464" - - "4317:4317" - - "55681:55681" - depends_on: - - zipkin-all-in-one - - # Zipkin - zipkin-all-in-one: - image: openzipkin/zipkin:latest@sha256:bb570eb45c2994eaf32da783cc098b3d51d1095b73ec92919863d73d0a9eaafb - ports: - - "9411:9411" - - # Prometheus - prometheus: - container_name: prometheus - image: prom/prometheus:latest@sha256:63805ebb8d2b3920190daf1cb14a60871b16fd38bed42b857a3182bc621f4996 - volumes: - - ./prometheus.yaml:/etc/prometheus/prometheus.yml - ports: - - "9090:9090" -# - "9184:9184" diff --git a/Examples/OTLP Exporter/images/prometheus-metrics.png b/Examples/OTLP Exporter/images/prometheus-metrics.png deleted file mode 100644 index e4e42afd..00000000 Binary files a/Examples/OTLP Exporter/images/prometheus-metrics.png and /dev/null differ diff --git a/Examples/OTLP Exporter/images/zipkin-spans.png b/Examples/OTLP Exporter/images/zipkin-spans.png deleted file mode 100644 index 120c24a6..00000000 Binary files a/Examples/OTLP Exporter/images/zipkin-spans.png and /dev/null differ diff --git a/Examples/OTLP Exporter/main.swift b/Examples/OTLP Exporter/main.swift deleted file mode 100644 index c6a9f4d5..00000000 --- a/Examples/OTLP Exporter/main.swift +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(macOS) - - import Foundation - import GRPC - import NIO - import NIOSSL - import OpenTelemetryApi - import OpenTelemetryProtocolExporterGrpc - import OpenTelemetrySdk - import ResourceExtension - import SignPostIntegration - import StdoutExporter - import ZipkinExporter - - let sampleKey = "sampleKey" - let sampleValue = "sampleValue" - - var resources = DefaultResources().get() - - let instrumentationScopeName = "OTLPExporter" - let instrumentationScopeVersion = "semver:0.1.0" - - let configuration = ClientConnection.Configuration.default(target: .hostAndPort("localhost", 4317), - eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1)) - let client = ClientConnection(configuration: configuration) - - let otlpTraceExporter = OtlpTraceExporter(channel: client) - let stdoutExporter = StdoutSpanExporter() - let spanExporter = MultiSpanExporter(spanExporters: [otlpTraceExporter, stdoutExporter]) - - let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporter) - OpenTelemetry.registerTracerProvider(tracerProvider: - TracerProviderBuilder() - .add(spanProcessor: spanProcessor) - .build() - ) - - let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: instrumentationScopeName, instrumentationVersion: instrumentationScopeVersion) - - if #available(iOS 15.0, macOS 12, tvOS 15.0, watchOS 8.0, *) { - let tracerProviderSDK = OpenTelemetry.instance.tracerProvider as? TracerProviderSdk - tracerProviderSDK?.addSpanProcessor(OSSignposterIntegration()) - } else { - let tracerProviderSDK = OpenTelemetry.instance.tracerProvider as? TracerProviderSdk - tracerProviderSDK?.addSpanProcessor(SignPostIntegration()) - } - - func createSpans() { - let parentSpan1 = tracer.spanBuilder(spanName: "Main").setSpanKind(spanKind: .client).startSpan() - parentSpan1.setAttribute(key: sampleKey, value: sampleValue) - OpenTelemetry.instance.contextProvider.setActiveSpan(parentSpan1) - for _ in 1 ... 3 { - doWork() - } - Thread.sleep(forTimeInterval: 0.5) - - let parentSpan2 = tracer.spanBuilder(spanName: "Another").setSpanKind(spanKind: .client).setActive(true).startSpan() - parentSpan2.setAttribute(key: sampleKey, value: sampleValue) - // do more Work - for _ in 1 ... 3 { - doWork() - } - Thread.sleep(forTimeInterval: 0.5) - - parentSpan2.end() - parentSpan1.end() - } - - func doWork() { - let childSpan = tracer.spanBuilder(spanName: "doWork").setSpanKind(spanKind: .client).startSpan() - childSpan.setAttribute(key: sampleKey, value: sampleValue) - Thread.sleep(forTimeInterval: Double.random(in: 0 ..< 10) / 100) - childSpan.end() - } - - // Create a Parent span (Main) and do some Work (child Spans). Repeat for another Span. - createSpans() - - // Metrics -let otlpMetricExporter = OtlpMetricExporter(channel: client) -let meterProvider = MeterProviderSdk.builder() - .registerMetricReader( - reader: PeriodicMetricReaderBuilder( - exporter: otlpMetricExporter).setInterval(timeInterval: 60) - .build() - ) - .registerView( - selector: InstrumentSelector.builder().setInstrument(name: ".*").build(), - view: View.builder().build() - ) - .build() - -OpenTelemetry.registerMeterProvider(meterProvider: meterProvider) - -let labels1 = ["dim1": AttributeValue.string("value1")] - - var meter = meterProvider.get(name: "otlp_example_meter'") - -var exampleCounter = meter.counterBuilder(name: "otlp_example_counter").build() -var exampleObserver = meter.gaugeBuilder( - name: "otlp_example_observation" -).buildWithCallback { observer in - var taskInfo = mach_task_basic_info() - var count = mach_msg_type_number_t(MemoryLayout.size) / 4 - let _: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { - $0.withMemoryRebound(to: integer_t.self, capacity: 1) { - task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count) - } - } - observer.record(value: Int(taskInfo.resident_size), attributes: labels1) - } - - for _ in 1 ... 3000 { - exampleCounter.add(value: 1, attributes: labels1) - sleep(1) - } - -#endif diff --git a/Examples/OTLP Exporter/prometheus.yaml b/Examples/OTLP Exporter/prometheus.yaml deleted file mode 100644 index b027daf9..00000000 --- a/Examples/OTLP Exporter/prometheus.yaml +++ /dev/null @@ -1,9 +0,0 @@ -global: - scrape_interval: 15s # Default is every 1 minute. - -scrape_configs: - - job_name: 'collector' - # metrics_path defaults to '/metrics' - # scheme defaults to 'http'. - static_configs: - - targets: ['collector:9464'] diff --git a/Examples/OTLP HTTP Exporter/README.md b/Examples/OTLP HTTP Exporter/README.md deleted file mode 100644 index a6de42a2..00000000 --- a/Examples/OTLP HTTP Exporter/README.md +++ /dev/null @@ -1,57 +0,0 @@ -### OTLP Exporter Example - -This example shows how to use [OTLP HTTP Exporter](https://github.com/open-telemetry/opentelemetry-swift/tree/main/Sources/Exporters/OpenTelemetryProtocol) to instrument a simple Swift application. - -This example will export spans data using [OTLP HTTP Exporter ](https://github.com/open-telemetry/opentelemetry-swift/tree/main/Sources/Exporters/OpenTelemetryProtocol). It will use [proto format](https://github.com/open-telemetry/opentelemetry-proto). - - -## Run the Application - -1. Run docker: This will start otel-collector, Zipkin and Prometheus - - ```shell script - # from this directory - docker-compose up - ``` - -2. Run app - - ```shell script - # from this directory - swift run OTLPHTTPExporter - ``` - -3. Teardown the docker images - - ```shell script - # from this directory - docker-compose down - ``` - -4. Open page at - you should be able to see the spans in zipkin -![Screenshot of the running example](images/zipkin-spans.png) - -### Prometheus UI - -The prometheus client will be available at . - -Note: It may take some time for the application metrics to appear on the Prometheus dashboard. -![Screenshot of the running example](images/prometheus-metrics.png) - -5. If you don't set service.name as per https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md the default name of the service and spans generate by the OTLP Exporter is `unknown_service:otlpexporter` You can either set the service.name by editing the schema in Xcode and the set the environment variable for OTEL_RESOURCE_ATTRIBUTES, or set it via command line: - - ```shell script - # from this directory - OTEL_RESOURCE_ATTRIBUTES="service.name=my-swift-app,service.version=v1.2.3" swift run OTLPExporter - ``` -This will create a service and spans with the name `my-swift-app` - -## Useful links - -- For more information on OpenTelemetry, visit: -- For more information on trace, visit: -- For more information on metrics, visit: - -## LICENSE - -Apache License 2.0 diff --git a/Examples/OTLP HTTP Exporter/collector-config.yaml b/Examples/OTLP HTTP Exporter/collector-config.yaml deleted file mode 100644 index 1a965a12..00000000 --- a/Examples/OTLP HTTP Exporter/collector-config.yaml +++ /dev/null @@ -1,37 +0,0 @@ -receivers: - otlp: - protocols: - grpc: - http: - cors: - allowed_origins: - - http://* - - https://* - -exporters: - zipkin: - endpoint: "http://zipkin-all-in-one:9411/api/v2/spans" - prometheus: - endpoint: "0.0.0.0:9464" - -processors: - resource: - attributes: - - key: service.name - value: OTLP Exporter - action: insert - batch: - -service: - telemetry: - logs: - level: "debug" - pipelines: - traces: - receivers: [otlp] - exporters: [zipkin] - processors: [resource, batch] - metrics: - receivers: [otlp] - exporters: [prometheus] - processors: [resource, batch] diff --git a/Examples/OTLP HTTP Exporter/docker-compose.yaml b/Examples/OTLP HTTP Exporter/docker-compose.yaml deleted file mode 100644 index 75b0ab1d..00000000 --- a/Examples/OTLP HTTP Exporter/docker-compose.yaml +++ /dev/null @@ -1,33 +0,0 @@ -version: "3" -services: - # Collector - collector: - image: otel/opentelemetry-collector:latest@sha256:0c066d4388070dad8dc9961d9f23649e85a226620e6b359334e4a6c7f9d73b23 -# The latest image of the otel-collector may not work, so specifying the version that works with this release -# image: otel/opentelemetry-collector:latest - command: ["--config=/conf/collector-config.yaml"] - volumes: - - ./collector-config.yaml:/conf/collector-config.yaml - ports: - - "9464:9464" - - "4317:4317" - - "4318:4318" - - "55681:55681" - depends_on: - - zipkin-all-in-one - - # Zipkin - zipkin-all-in-one: - image: openzipkin/zipkin:latest@sha256:bb570eb45c2994eaf32da783cc098b3d51d1095b73ec92919863d73d0a9eaafb - ports: - - "9411:9411" - - # Prometheus - prometheus: - container_name: prometheus - image: prom/prometheus:latest@sha256:63805ebb8d2b3920190daf1cb14a60871b16fd38bed42b857a3182bc621f4996 - volumes: - - ./prometheus.yaml:/etc/prometheus/prometheus.yml - ports: - - "9090:9090" -# - "9184:9184" diff --git a/Examples/OTLP HTTP Exporter/images/prometheus-metrics.png b/Examples/OTLP HTTP Exporter/images/prometheus-metrics.png deleted file mode 100644 index e4e42afd..00000000 Binary files a/Examples/OTLP HTTP Exporter/images/prometheus-metrics.png and /dev/null differ diff --git a/Examples/OTLP HTTP Exporter/images/zipkin-spans.png b/Examples/OTLP HTTP Exporter/images/zipkin-spans.png deleted file mode 100644 index 120c24a6..00000000 Binary files a/Examples/OTLP HTTP Exporter/images/zipkin-spans.png and /dev/null differ diff --git a/Examples/OTLP HTTP Exporter/main.swift b/Examples/OTLP HTTP Exporter/main.swift deleted file mode 100644 index a71963c1..00000000 --- a/Examples/OTLP HTTP Exporter/main.swift +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(macOS) - - import Foundation - import OpenTelemetryApi - import OpenTelemetryProtocolExporterHttp - import OpenTelemetrySdk - import ResourceExtension - import SignPostIntegration - import StdoutExporter - import ZipkinExporter - - let sampleKey = "sampleKey" - let sampleValue = "sampleValue" - - var resources = DefaultResources().get() - - let instrumentationScopeName = "OTLPHTTPExporter" - let instrumentationScopeVersion = "semver:0.1.0" - - let otlpHttpTraceExporter = OtlpHttpTraceExporter() - let stdoutExporter = StdoutSpanExporter() - let spanExporter = MultiSpanExporter(spanExporters: [otlpHttpTraceExporter, stdoutExporter]) - - let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporter) - OpenTelemetry.registerTracerProvider(tracerProvider: - TracerProviderBuilder() - .add(spanProcessor: spanProcessor) - .build() - ) - - let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: instrumentationScopeName, instrumentationVersion: instrumentationScopeVersion) - - if #available(iOS 15.0, macOS 12, tvOS 15.0, watchOS 8.0, *) { - let tracerProviderSDK = OpenTelemetry.instance.tracerProvider as? TracerProviderSdk - tracerProviderSDK?.addSpanProcessor(OSSignposterIntegration()) - } else { - let tracerProviderSDK = OpenTelemetry.instance.tracerProvider as? TracerProviderSdk - tracerProviderSDK?.addSpanProcessor(SignPostIntegration()) - } - - func createSpans() { - let parentSpan1 = tracer.spanBuilder(spanName: "Main").setSpanKind(spanKind: .client).startSpan() - parentSpan1.setAttribute(key: sampleKey, value: sampleValue) - OpenTelemetry.instance.contextProvider.setActiveSpan(parentSpan1) - for _ in 1 ... 3 { - doWork() - } - Thread.sleep(forTimeInterval: 0.5) - - let parentSpan2 = tracer.spanBuilder(spanName: "Another").setSpanKind(spanKind: .client).setActive(true).startSpan() - parentSpan2.setAttribute(key: sampleKey, value: sampleValue) - // do more Work - for _ in 1 ... 3 { - doWork() - } - Thread.sleep(forTimeInterval: 0.5) - - parentSpan2.end() - parentSpan1.end() - } - - func doWork() { - let childSpan = tracer.spanBuilder(spanName: "doWork").setSpanKind(spanKind: .client).startSpan() - childSpan.setAttribute(key: sampleKey, value: sampleValue) - Thread.sleep(forTimeInterval: Double.random(in: 0 ..< 10) / 100) - childSpan.end() - } - - // Create a Parent span (Main) and do some Work (child Spans). Repeat for another Span. - createSpans() - -// Metrics -let otlpMetricExporter = OtlpHttpMetricExporter(endpoint: defaultOtlpHttpMetricsEndpoint()) -let meterProvider = MeterProviderSdk.builder() - .registerMetricReader( - reader: PeriodicMetricReaderBuilder( - exporter: otlpMetricExporter).setInterval(timeInterval: 60) - .build() - ) - .registerView( - selector: InstrumentSelector.builder().setInstrument(name: ".*").build(), - view: View.builder().build() - ) - .build() - -OpenTelemetry.registerMeterProvider(meterProvider: meterProvider) - -let labels1 = ["dim1": AttributeValue.string("value1")] - -var meter = meterProvider.get(name: "otlp_example_meter'") - -var exampleCounter = meter.counterBuilder(name: "otlp_example_counter").build() -var exampleObserver = meter.gaugeBuilder( - name: "otlp_example_observation" -).buildWithCallback { observer in - var taskInfo = mach_task_basic_info() - var count = mach_msg_type_number_t(MemoryLayout.size) / 4 - let _: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { - $0.withMemoryRebound(to: integer_t.self, capacity: 1) { - task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count) - } - } - observer.record(value: Int(taskInfo.resident_size), attributes: labels1) -} - -for _ in 1 ... 3000 { - exampleCounter.add(value: 1, attributes: labels1) - sleep(1) -} -#endif diff --git a/Examples/OTLP HTTP Exporter/prometheus.yaml b/Examples/OTLP HTTP Exporter/prometheus.yaml deleted file mode 100644 index b027daf9..00000000 --- a/Examples/OTLP HTTP Exporter/prometheus.yaml +++ /dev/null @@ -1,9 +0,0 @@ -global: - scrape_interval: 15s # Default is every 1 minute. - -scrape_configs: - - job_name: 'collector' - # metrics_path defaults to '/metrics' - # scheme defaults to 'http'. - static_configs: - - targets: ['collector:9464'] diff --git a/Examples/Prometheus Sample/README.md b/Examples/Prometheus Sample/README.md deleted file mode 100644 index 0a6ad41a..00000000 --- a/Examples/Prometheus Sample/README.md +++ /dev/null @@ -1,41 +0,0 @@ -### Prometheus Sample - -This example shows the Prometheus exporter returning data in a web server. -Modify your local ip address in the main file an the prometheus.yml file - -The sample expects a Prometheus instance scraping data from a specific local port ,you can run it like: - -``` -docker run -p 9090:9090 -p 9184:9184 -v $HOME/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -with a prometheus.yml with the content (use your local ip address at the bottom): - -``` ---- -alerting: - alertmanagers: - - - api_version: v1 - scheme: http - static_configs: - - - targets: [] - timeout: 10s -global: - evaluation_interval: 15s - scrape_interval: 15s - scrape_timeout: 10s -scrape_configs: - - - honor_timestamps: true - job_name: Example code - metrics_path: /metrics - scheme: http - scrape_interval: 15s - scrape_timeout: 10s - static_configs: - - - targets: - - "192.168.1.28:9184" -``` diff --git a/Examples/Prometheus Sample/main.swift b/Examples/Prometheus Sample/main.swift deleted file mode 100644 index 9517919b..00000000 --- a/Examples/Prometheus Sample/main.swift +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import PrometheusExporter - -print("Hello Prometheus") - -// -// You should use here your real local address, change it also in the prometheus.yml file -let localAddress = "192.168.1.28" -// - -let promOptions = PrometheusExporterOptions(url: "http://\(localAddress):9184/metrics") -let promExporter = PrometheusExporter(options: promOptions) -let metricsHttpServer = PrometheusExporterHttpServer(exporter: promExporter) - -DispatchQueue.global(qos: .default).async { - do { - try metricsHttpServer.start() - } catch { - print("Failed staring http server") - return - } -} - -let meterProvider = MeterProviderSdk.builder() - .registerView( - selector: InstrumentSelector - .builder() - .setInstrument(type: .histogram).build(), - view: View.builder() - .withAggregation( - aggregation: ExplicitBucketHistogramAggregation(bucketBoundaries: [5, 10, 25]) - ).build() - ) - .registerMetricReader( - reader: PeriodicMetricReaderBuilder(exporter: promExporter).build( - )).build() - -OpenTelemetry.registerMeterProvider(meterProvider: meterProvider) - -var meter = meterProvider.get(name: "MyMeter") - -var testCounter = meter.counterBuilder(name: "MyCounter").build() -var testMeasure = meter.gaugeBuilder(name: "MyMeasure").build() - -var testHistogram = meter.histogramBuilder(name: "MyHistogram").build() - -var testObserver = meter.gaugeBuilder(name: "MyObservation").buildWithCallback { observer in - var taskInfo = mach_task_basic_info() - var count = mach_msg_type_number_t(MemoryLayout.size) / 4 - let _: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { - $0.withMemoryRebound(to: integer_t.self, capacity: 1) { - task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count) - } - } - let labels1 = ["dim1": AttributeValue.string("value1")] - observer - .record(value: Int(taskInfo.resident_size), attributes: labels1) -} - -var labels1 = ["dim1": AttributeValue.string("value1")] -var labels2 = ["dim1": AttributeValue.string("value2")] - -var counter = 0 -while counter < 3000 { - testCounter.add(value: 100, attributes: labels1) - - testMeasure.record(value: 100, attributes: labels1) - testMeasure.record(value: 500, attributes: labels1) - testMeasure.record(value: 5, attributes: labels1) - testMeasure.record(value: 750, attributes: labels1) - - testHistogram.record(value: 8, attributes: labels1) - testHistogram.record(value: 20, attributes: labels1) - testHistogram.record(value: 30, attributes: labels1) - - counter += 1 - sleep(1) -} - -metricsHttpServer.stop() - -print("Metrics server shutdown.") -print("Press Enter key to exit.") diff --git a/Examples/Simple Exporter/README.md b/Examples/Simple Exporter/README.md deleted file mode 100644 index c2a12a7b..00000000 --- a/Examples/Simple Exporter/README.md +++ /dev/null @@ -1,23 +0,0 @@ -### Simple Exporter - -This example shows the Jaeger and Stdout exporters in action using a MultiSpanExporter. It also adds support for SignPostIntegration, so running this app in `Instruments` will show the span creation and duration - -The sample expects a local Jaeger installation as explained in [Jaeger docs](https://www.jaegertracing.io/docs/1.41/getting-started/#all-in-one): - -``` -docker run -d --name jaeger \ - -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ - -e COLLECTOR_OTLP_ENABLED=true \ - -p 6831:6831/udp \ - -p 6832:6832/udp \ - -p 5778:5778 \ - -p 16686:16686 \ - -p 4317:4317 \ - -p 4318:4318 \ - -p 14250:14250 \ - -p 14268:14268 \ - -p 14269:14269 \ - -p 9411:9411 \ - jaegertracing/all-in-one:1.41 -``` - diff --git a/Examples/Simple Exporter/main.swift b/Examples/Simple Exporter/main.swift deleted file mode 100644 index 3dc22791..00000000 --- a/Examples/Simple Exporter/main.swift +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(macOS) - - import Foundation - import JaegerExporter - import OpenTelemetryApi - import OpenTelemetrySdk - import ResourceExtension - import SignPostIntegration - import StdoutExporter - import ZipkinExporter - - let sampleKey = "sampleKey" - let sampleValue = "sampleValue" - - let instrumentationScopeName = "SimpleExporter" - let instrumentationScopeVersion = "semver:0.1.0" - - var tracer: TracerSdk - let jaegerCollectorAddress = "localhost" - let jaegerExporter = JaegerSpanExporter(serviceName: "SimpleExporter", collectorAddress: jaegerCollectorAddress) - let stdoutExporter = StdoutSpanExporter() - - // let zipkinExporterOptions = ZipkinTraceExporterOptions() - // let zipkinExporter = ZipkinTraceExporter(options: zipkinExporterOptions) - - let spanExporter = MultiSpanExporter(spanExporters: [jaegerExporter, stdoutExporter /* , zipkinExporter */ ]) - let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporter) - let resources = DefaultResources().get() - - OpenTelemetry.registerTracerProvider(tracerProvider: - TracerProviderBuilder() - .add(spanProcessor: spanProcessor) - .with(resource: resources) - .build() - ) - - tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: instrumentationScopeName, instrumentationVersion: instrumentationScopeVersion) as! TracerSdk - - if #available(iOS 15.0, macOS 12, tvOS 15.0, watchOS 8.0, *) { - let tracerProviderSDK = OpenTelemetry.instance.tracerProvider as? TracerProviderSdk - tracerProviderSDK?.addSpanProcessor(OSSignposterIntegration()) - } else { - let tracerProviderSDK = OpenTelemetry.instance.tracerProvider as? TracerProviderSdk - tracerProviderSDK?.addSpanProcessor(SignPostIntegration()) - } - - func simpleSpan() { - let span = tracer.spanBuilder(spanName: "SimpleSpan").setSpanKind(spanKind: .client).startSpan() - span.setAttribute(key: sampleKey, value: sampleValue) - Thread.sleep(forTimeInterval: 0.5) - span.end() - } - - func childSpan() { - let span = tracer.spanBuilder(spanName: "parentSpan").setSpanKind(spanKind: .client).setActive(true).startSpan() - span.setAttribute(key: sampleKey, value: sampleValue) - Thread.sleep(forTimeInterval: 0.2) - let childSpan = tracer.spanBuilder(spanName: "childSpan").setSpanKind(spanKind: .client).startSpan() - childSpan.setAttribute(key: sampleKey, value: sampleValue) - Thread.sleep(forTimeInterval: 0.5) - childSpan.end() - span.end() - } - - simpleSpan() - sleep(1) - childSpan() - sleep(1) - -#endif diff --git a/Examples/Stable Metric Sample/README.md b/Examples/Stable Metric Sample/README.md deleted file mode 100644 index 0619394d..00000000 --- a/Examples/Stable Metric Sample/README.md +++ /dev/null @@ -1,12 +0,0 @@ -### Stable metrics - - Stable metrics is the working name for the otel-swift implementation of the current OpenTelemetry metrics specification. - The existing otel-swift metric implementation is old and out-of-spec. While Stable Metrics is in an experimental phase it will maintaion - the "stable" prefix, and can be expected to be present on overlapping constructs in the implementation. - Expected time line will be as follows: - Phase 1: - Provide access to Stable Metrics along side existing Metrics. Once Stable Metrics are considered stable we will move onto phase 2. - Phase 2: - Mark all existing Metric APIs as deprecated. This will maintained for a period TBD - Phase 3: - Remove deprecated metrics api and remove Stable prefix from Stable metrics. diff --git a/Examples/Stable Metric Sample/main.swift b/Examples/Stable Metric Sample/main.swift deleted file mode 100644 index 76475293..00000000 --- a/Examples/Stable Metric Sample/main.swift +++ /dev/null @@ -1,106 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import OpenTelemetryProtocolExporterCommon -import OpenTelemetryProtocolExporterGrpc -import StdoutExporter -import GRPC -import NIO -import NIOHPACK - -/* - Stable metrics is the working name for the otel-swift implementation of the current OpenTelemetry metrics specification. - The existing otel-swift metric implementation is old and out-of-spec. While Stable Metrics is in an experimental phase it will maintaion - the "stable" prefix, and can be expected to be present on overlapping constructs in the implementation. - Expected time line will be as follows: - Phase 1: - Provide access to Stable Metrics along side existing Metrics. Once Stable Metrics are considered stable we will move onto phase 2. - Phase 2: - Mark all existing Metric APIs as deprecated. This will maintained for a period TBD - Phase 3: - Remove deprecated metrics api and remove Stable prefix from Stable metrics. - - Below is an example used the Stable Metrics API - - */ - -/* - Basic configuration for metrics - */ -func basicConfiguration() { - let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - let exporterChannel = ClientConnection.insecure(group: group) - .connect(host: "localhost", port: 8200) - - // register view will process all instruments using `.*` regex - - OpenTelemetry.registerMeterProvider( -meterProvider: MeterProviderSdk.builder() - .registerView( - selector: InstrumentSelector.builder().setInstrument(name: ".*").build(), - view: View.builder().build() - ) - .registerMetricReader( - reader: PeriodicMetricReaderBuilder( - exporter: OtlpMetricExporter(channel: exporterChannel) - ) - .build() - ) - .build() - ) -} - -func complexViewConfiguration() { - let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - _ = ClientConnection.insecure(group: group) - .connect(host: "localhost", port: 8200) - - // The example registers a View that re-configures the Gauge instrument into a sum instrument named "GaugeSum" - - OpenTelemetry.registerMeterProvider( - meterProvider: MeterProviderSdk.builder() - .registerView( - selector: InstrumentSelector.builder() - .setInstrument(name: "Gauge") - .build(), - view: View.builder() - .withName(name: "GaugeSum") - .withAggregation( - aggregation: Aggregations - .sum() - ) - .build() - ) - .setExemplarFilter(exemplarFilter: AlwaysOnFilter()) - .registerMetricReader( - reader: PeriodicMetricReaderBuilder( - exporter: StdoutMetricExporter(isDebug: true) - ) - .build() - ) - .build() - ) -} - -basicConfiguration() - -// creating a new meter & instrument -let meter = OpenTelemetry.instance.meterProvider.meterBuilder(name: "MyMeter").build() -var gaugeBuilder = meter.gaugeBuilder(name: "Gauge") - -// observable gauge -var observableGauge = gaugeBuilder.buildWithCallback { ObservableDoubleMeasurement in - ObservableDoubleMeasurement.record(value: 1.0, attributes: ["test": AttributeValue.bool(true)]) -} - -var gauge = meter.gaugeBuilder(name: "Gauge").buildWithCallback { _ in - // noop -} - -// gauge -// gauge.record(value: 1.0, attributes: ["test": AttributeValue.bool(true)]) diff --git a/Makefile b/Makefile index c4ce6add..b84e08da 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PROJECT_NAME="opentelemetry-swift-Package" +PROJECT_NAME="opentelemetry-swift-core-Package" XCODEBUILD_OPTIONS_IOS=\ -configuration Debug \ diff --git a/OpenTelemetry-Swift-BaggagePropagationProcessor.podspec b/OpenTelemetry-Swift-BaggagePropagationProcessor.podspec deleted file mode 100644 index 5ec0fdde..00000000 --- a/OpenTelemetry-Swift-BaggagePropagationProcessor.podspec +++ /dev/null @@ -1,25 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-BaggagePropagationProcessor" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Baggage Propagation Processor" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Contrib/Processors/BaggagePropagationProcessor/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "BaggagePropagationProcessor" - - spec.dependency 'OpenTelemetry-Swift-Api', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name BaggagePropagationProcessor -package-name opentelemetry_swift_baggage_propagation_processor" } - -end diff --git a/OpenTelemetry-Swift-Instrumentation-NetworkStatus.podspec b/OpenTelemetry-Swift-Instrumentation-NetworkStatus.podspec deleted file mode 100644 index bea12ee7..00000000 --- a/OpenTelemetry-Swift-Instrumentation-NetworkStatus.podspec +++ /dev/null @@ -1,26 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-Instrumentation-NetworkStatus" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Network Status Instrumentation" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Instrumentation/NetworkStatus/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "NetworkStatus" - - spec.ios.frameworks = 'CoreTelephony' - - spec.dependency 'OpenTelemetry-Swift-Api', spec.version.to_s - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name NetworkStatus -package-name opentelemetry_swift_network_status" } - -end diff --git a/OpenTelemetry-Swift-Instrumentation-URLSession.podspec b/OpenTelemetry-Swift-Instrumentation-URLSession.podspec deleted file mode 100644 index 694f3141..00000000 --- a/OpenTelemetry-Swift-Instrumentation-URLSession.podspec +++ /dev/null @@ -1,25 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-Instrumentation-URLSession" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry URLSession Instrumentation" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Instrumentation/URLSession/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "URLSession" - - spec.dependency 'OpenTelemetry-Swift-Instrumentation-NetworkStatus', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name URLSession -package-name opentelemetry_swift_urlsession" } - -end diff --git a/OpenTelemetry-Swift-PersistenceExporter.podspec b/OpenTelemetry-Swift-PersistenceExporter.podspec deleted file mode 100644 index d655907b..00000000 --- a/OpenTelemetry-Swift-PersistenceExporter.podspec +++ /dev/null @@ -1,24 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-PersistenceExporter" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Persistence Exporter" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Exporters/Persistence/**/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "PersistenceExporter" - - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name PersistenceExporter -package-name opentelemetry_swift_persistence_exporter" } - -end diff --git a/OpenTelemetry-Swift-Protocol-Exporter-Common.podspec b/OpenTelemetry-Swift-Protocol-Exporter-Common.podspec deleted file mode 100644 index 9560dc97..00000000 --- a/OpenTelemetry-Swift-Protocol-Exporter-Common.podspec +++ /dev/null @@ -1,26 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-Protocol-Exporter-Common" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Protocol Exporter Common" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Exporters/OpenTelemetryProtocolCommon/**/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "OpenTelemetryProtocolExporterCommon" - - spec.dependency 'OpenTelemetry-Swift-Api', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.dependency 'SwiftProtobuf', '~> 1.28' - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name OpenTelemetryProtocolExporterCommon -package-name opentelemetry_swift_exporter_common" } - -end diff --git a/OpenTelemetry-Swift-Protocol-Exporter-Http.podspec b/OpenTelemetry-Swift-Protocol-Exporter-Http.podspec deleted file mode 100644 index 5a8542a0..00000000 --- a/OpenTelemetry-Swift-Protocol-Exporter-Http.podspec +++ /dev/null @@ -1,28 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-Protocol-Exporter-Http" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Protocol Exporter Common" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Exporters/OpenTelemetryProtocolHttp/**/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "OpenTelemetryProtocolExporterHttp" - - spec.dependency 'OpenTelemetry-Swift-Api', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Protocol-Exporter-Common', spec.version.to_s - spec.dependency 'DataCompression', '3.8.0' - spec.dependency 'SwiftProtobuf', '~> 1.28' - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name OpenTelemetryProtocolExporterHttp -package-name opentelemetry_swift_exporter_http" } - -end diff --git a/OpenTelemetry-Swift-SdkResourceExtension.podspec b/OpenTelemetry-Swift-SdkResourceExtension.podspec deleted file mode 100644 index 99bba74e..00000000 --- a/OpenTelemetry-Swift-SdkResourceExtension.podspec +++ /dev/null @@ -1,25 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-SdkResourceExtension" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Resource Extension" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Instrumentation/SDKResourceExtension/**/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "ResourceExtension" - - spec.dependency 'OpenTelemetry-Swift-Api', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name ResourceExtension -package-name opentelemetry_swift_resource_extension" } - -end diff --git a/OpenTelemetry-Swift-StdoutExporter.podspec b/OpenTelemetry-Swift-StdoutExporter.podspec deleted file mode 100644 index b27b236a..00000000 --- a/OpenTelemetry-Swift-StdoutExporter.podspec +++ /dev/null @@ -1,25 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = "OpenTelemetry-Swift-StdoutExporter" - spec.version = "2.0.2" - spec.summary = "Swift OpenTelemetry Standard output Exporter" - - spec.homepage = "https://github.com/open-telemetry/opentelemetry-swift" - spec.documentation_url = "https://opentelemetry.io/docs/languages/swift" - spec.license = { :type => "Apache 2.0", :file => "LICENSE" } - spec.authors = "OpenTelemetry Authors" - - spec.source = { :git => "https://github.com/open-telemetry/opentelemetry-swift.git", :tag => spec.version.to_s } - spec.source_files = "Sources/Exporters/Stdout/*.swift" - - spec.swift_version = "5.10" - spec.ios.deployment_target = "13.0" - spec.tvos.deployment_target = "13.0" - spec.watchos.deployment_target = "6.0" - spec.visionos.deployment_target = "1.0" - spec.module_name = "StdoutExporter" - - spec.dependency 'OpenTelemetry-Swift-Api', spec.version.to_s - spec.dependency 'OpenTelemetry-Swift-Sdk', spec.version.to_s - spec.pod_target_xcconfig = { "OTHER_SWIFT_FLAGS" => "-module-name StdoutExporter -package-name opentelemetry_swift_stdout_exporter" } - -end diff --git a/Package.resolved b/Package.resolved index ff698e52..f0305524 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,32 +1,5 @@ { "pins" : [ - { - "identity" : "datacompression", - "kind" : "remoteSourceControl", - "location" : "https://github.com/mw99/DataCompression", - "state" : { - "revision" : "5ab15951321b08b74511601cbd0497667649d70b", - "version" : "3.8.0" - } - }, - { - "identity" : "grpc-swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/grpc/grpc-swift.git", - "state" : { - "revision" : "a56a157218877ef3e9625f7e1f7b2cb7e46ead1b", - "version" : "1.26.1" - } - }, - { - "identity" : "opentracing-objc", - "kind" : "remoteSourceControl", - "location" : "https://github.com/undefinedlabs/opentracing-objc", - "state" : { - "revision" : "18c1a35ca966236cee0c5a714a51a73ff33384c1", - "version" : "0.5.2" - } - }, { "identity" : "swift-atomics", "kind" : "remoteSourceControl", @@ -35,114 +8,6 @@ "revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7", "version" : "1.3.0" } - }, - { - "identity" : "swift-collections", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-collections.git", - "state" : { - "revision" : "ee97538f5b81ae89698fd95938896dec5217b148", - "version" : "1.1.1" - } - }, - { - "identity" : "swift-http-types", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-http-types", - "state" : { - "revision" : "9bee2fdb79cc740081abd8ebd80738063d632286", - "version" : "1.1.0" - } - }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log.git", - "state" : { - "revision" : "3d8596ed08bd13520157f0355e35caed215ffbfa", - "version" : "1.6.3" - } - }, - { - "identity" : "swift-metrics", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-metrics.git", - "state" : { - "revision" : "4c83e1cdf4ba538ef6e43a9bbd0bcc33a0ca46e3", - "version" : "2.7.0" - } - }, - { - "identity" : "swift-nio", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio.git", - "state" : { - "revision" : "34d486b01cd891297ac615e40d5999536a1e138d", - "version" : "2.83.0" - } - }, - { - "identity" : "swift-nio-extras", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-extras.git", - "state" : { - "revision" : "2e9746cfc57554f70b650b021b6ae4738abef3e6", - "version" : "1.24.1" - } - }, - { - "identity" : "swift-nio-http2", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-http2.git", - "state" : { - "revision" : "4281466512f63d1bd530e33f4aa6993ee7864be0", - "version" : "1.36.0" - } - }, - { - "identity" : "swift-nio-ssl", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-ssl.git", - "state" : { - "revision" : "2b09805797f21c380f7dc9bedaab3157c5508efb", - "version" : "2.27.0" - } - }, - { - "identity" : "swift-nio-transport-services", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-transport-services.git", - "state" : { - "revision" : "cd1e89816d345d2523b11c55654570acd5cd4c56", - "version" : "1.24.0" - } - }, - { - "identity" : "swift-protobuf", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-protobuf.git", - "state" : { - "revision" : "102a647b573f60f73afdce5613a51d71349fe507", - "version" : "1.30.0" - } - }, - { - "identity" : "swift-system", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-system.git", - "state" : { - "revision" : "c8a44d836fe7913603e246acab7c528c2e780168", - "version" : "1.4.0" - } - }, - { - "identity" : "thrift-swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/undefinedlabs/Thrift-Swift", - "state" : { - "revision" : "18ff09e6b30e589ed38f90a1af23e193b8ecef8e", - "version" : "1.1.2" - } } ], "version" : 2 diff --git a/Package.swift b/Package.swift index bd0cf59b..5a24ff95 100644 --- a/Package.swift +++ b/Package.swift @@ -5,7 +5,7 @@ import Foundation import PackageDescription let package = Package( - name: "opentelemetry-swift", + name: "opentelemetry-swift-core", platforms: [ .macOS(.v12), .iOS(.v13), @@ -17,29 +17,11 @@ let package = Package( .library(name: "OpenTelemetryApi", targets: ["OpenTelemetryApi"]), .library(name: "OpenTelemetryConcurrency", targets: ["OpenTelemetryConcurrency"]), .library(name: "OpenTelemetrySdk", targets: ["OpenTelemetrySdk"]), - .library(name: "SwiftMetricsShim", targets: ["SwiftMetricsShim"]), .library(name: "StdoutExporter", targets: ["StdoutExporter"]), - .library(name: "PrometheusExporter", targets: ["PrometheusExporter"]), - .library(name: "OpenTelemetryProtocolExporter", targets: ["OpenTelemetryProtocolExporterGrpc"]), - .library( - name: "OpenTelemetryProtocolExporterHTTP", targets: ["OpenTelemetryProtocolExporterHttp"] - ), - .library(name: "PersistenceExporter", targets: ["PersistenceExporter"]), - .library(name: "InMemoryExporter", targets: ["InMemoryExporter"]), - .library(name: "OTelSwiftLog", targets: ["OTelSwiftLog"]), - .library(name: "BaggagePropagationProcessor", targets: ["BaggagePropagationProcessor"]), .executable(name: "ConcurrencyContext", targets: ["ConcurrencyContext"]), - .executable(name: "loggingTracer", targets: ["LoggingTracer"]), - .executable(name: "StableMetricSample", targets: ["StableMetricSample"]), ], dependencies: [ - .package(url: "https://github.com/apple/swift-nio.git", from: "2.83.0"), - .package(url: "https://github.com/grpc/grpc-swift.git", exact: "1.26.1"), - .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.30.0"), - .package(url: "https://github.com/apple/swift-log.git", from: "1.6.3"), - .package(url: "https://github.com/apple/swift-metrics.git", from: "2.7.0"), .package(url: "https://github.com/apple/swift-atomics.git", from: "1.3.0"), - .package(url: "https://github.com/mw99/DataCompression", from: "3.9.0"), ], targets: [ .target( @@ -57,96 +39,14 @@ let package = Package( name: "OpenTelemetryConcurrency", dependencies: ["OpenTelemetryApi"] ), - .target( - name: "OpenTelemetryTestUtils", - dependencies: ["OpenTelemetryApi", "OpenTelemetrySdk"] - ), - .target( - name: "OTelSwiftLog", - dependencies: [ - "OpenTelemetryApi", - .product(name: "Logging", package: "swift-log"), - ], - path: "Sources/Bridges/OTelSwiftLog", - exclude: ["README.md"] - ), - .target( - name: "SwiftMetricsShim", - dependencies: [ - "OpenTelemetrySdk", - .product(name: "CoreMetrics", package: "swift-metrics"), - ], - path: "Sources/Importers/SwiftMetricsShim", - exclude: ["README.md"] - ), - .target( - name: "PrometheusExporter", - dependencies: [ - "OpenTelemetrySdk", - .product(name: "NIO", package: "swift-nio"), - .product(name: "NIOHTTP1", package: "swift-nio"), - ], - path: "Sources/Exporters/Prometheus" - ), - .target( - name: "OpenTelemetryProtocolExporterCommon", - dependencies: [ - "OpenTelemetrySdk", - .product(name: "Logging", package: "swift-log"), - .product(name: "SwiftProtobuf", package: "swift-protobuf"), - ], - path: "Sources/Exporters/OpenTelemetryProtocolCommon" - ), - .target( - name: "OpenTelemetryProtocolExporterHttp", - dependencies: [ - "OpenTelemetrySdk", - "OpenTelemetryProtocolExporterCommon", - .product( - name: "DataCompression", - package: "DataCompression", - condition: .when(platforms: [.macOS, .iOS, .watchOS, .tvOS, .visionOS]) - ), - ], - path: "Sources/Exporters/OpenTelemetryProtocolHttp" - ), - .target( - name: "OpenTelemetryProtocolExporterGrpc", - dependencies: [ - "OpenTelemetrySdk", - "OpenTelemetryProtocolExporterCommon", - .product(name: "GRPC", package: "grpc-swift"), - ], - path: "Sources/Exporters/OpenTelemetryProtocolGrpc" - ), .target( name: "StdoutExporter", dependencies: ["OpenTelemetrySdk"], path: "Sources/Exporters/Stdout" ), .target( - name: "InMemoryExporter", - dependencies: ["OpenTelemetrySdk"], - path: "Sources/Exporters/InMemory" - ), - .target( - name: "PersistenceExporter", - dependencies: ["OpenTelemetrySdk"], - path: "Sources/Exporters/Persistence", - exclude: ["README.md"] - ), - .target( - name: "BaggagePropagationProcessor", - dependencies: [ - "OpenTelemetryApi", - "OpenTelemetrySdk", - ], - path: "Sources/Contrib/Processors/BaggagePropagationProcessor" - ), - .testTarget( - name: "OTelSwiftLogTests", - dependencies: ["OTelSwiftLog"], - path: "Tests/BridgesTests/OTelSwiftLog" + name: "OpenTelemetryTestUtils", + dependencies: ["OpenTelemetryApi", "OpenTelemetrySdk"] ), .testTarget( name: "OpenTelemetryApiTests", @@ -162,248 +62,13 @@ let package = Package( ], path: "Tests/OpenTelemetrySdkTests" ), - .testTarget( - name: "SwiftMetricsShimTests", - dependencies: [ - "SwiftMetricsShim", - "OpenTelemetrySdk", - ], - path: "Tests/ImportersTests/SwiftMetricsShim" - ), - .testTarget( - name: "PrometheusExporterTests", - dependencies: ["PrometheusExporter"], - path: "Tests/ExportersTests/Prometheus" - ), - .testTarget( - name: "OpenTelemetryProtocolExporterTests", - dependencies: [ - "OpenTelemetryProtocolExporterGrpc", - "OpenTelemetryProtocolExporterHttp", - .product( - name: "DataCompression", - package: "DataCompression", - condition: .when(platforms: [.macOS, .iOS, .watchOS, .tvOS, .visionOS]) - ), - .product(name: "NIO", package: "swift-nio"), - .product(name: "NIOHTTP1", package: "swift-nio"), - .product(name: "NIOTestUtils", package: "swift-nio"), - ], - path: "Tests/ExportersTests/OpenTelemetryProtocol" - ), - .testTarget( - name: "InMemoryExporterTests", - dependencies: ["InMemoryExporter"], - path: "Tests/ExportersTests/InMemory" - ), - .testTarget( - name: "PersistenceExporterTests", - dependencies: ["PersistenceExporter"], - path: "Tests/ExportersTests/PersistenceExporter" - ), - .testTarget( - name: "ContribTests", - dependencies: [ - "BaggagePropagationProcessor", - "InMemoryExporter", - ] - ), - .executableTarget( - name: "LoggingTracer", - dependencies: ["OpenTelemetryApi"], - path: "Examples/Logging Tracer" - ), - .executableTarget( - name: "LogsSample", - dependencies: [ - "OpenTelemetrySdk", "OpenTelemetryProtocolExporterGrpc", - .product(name: "GRPC", package: "grpc-swift"), - ], - path: "Examples/Logs Sample" - ), .executableTarget( name: "ConcurrencyContext", dependencies: ["OpenTelemetrySdk", "OpenTelemetryConcurrency", "StdoutExporter"], path: "Examples/ConcurrencyContext" ), - .executableTarget( - name: "StableMetricSample", - dependencies: ["OpenTelemetrySdk", "OpenTelemetryProtocolExporterGrpc", "StdoutExporter"], - path: "Examples/Stable Metric Sample", - exclude: ["README.md"] - ), ] -).addPlatformSpecific() - -extension Package { - func addPlatformSpecific() -> Self { - #if canImport(ObjectiveC) - dependencies.append( - .package(url: "https://github.com/undefinedlabs/opentracing-objc", from: "0.5.2") - ) - products.append( - .library(name: "OpenTracingShim-experimental", targets: ["OpenTracingShim"]) - ) - targets.append(contentsOf: [ - .target( - name: "OpenTracingShim", - dependencies: [ - "OpenTelemetrySdk", - .product(name: "Opentracing", package: "opentracing-objc"), - ], - path: "Sources/Importers/OpenTracingShim", - exclude: ["README.md"] - ), - .testTarget( - name: "OpenTracingShimTests", - dependencies: [ - "OpenTracingShim", - "OpenTelemetrySdk", - ], - path: "Tests/ImportersTests/OpenTracingShim" - ), - ]) - #endif - - #if canImport(Darwin) - dependencies.append( - .package(url: "https://github.com/undefinedlabs/Thrift-Swift", from: "1.1.1") - ) - products.append(contentsOf: [ - .library(name: "JaegerExporter", targets: ["JaegerExporter"]), - .executable(name: "simpleExporter", targets: ["SimpleExporter"]), - .library(name: "NetworkStatus", targets: ["NetworkStatus"]), - .library(name: "URLSessionInstrumentation", targets: ["URLSessionInstrumentation"]), - .library(name: "ZipkinExporter", targets: ["ZipkinExporter"]), - .executable(name: "OTLPExporter", targets: ["OTLPExporter"]), - .executable(name: "OTLPHTTPExporter", targets: ["OTLPHTTPExporter"]), - .library(name: "SignPostIntegration", targets: ["SignPostIntegration"]), - .library(name: "ResourceExtension", targets: ["ResourceExtension"]), - ]) - targets.append(contentsOf: [ - .target( - name: "JaegerExporter", - dependencies: [ - "OpenTelemetrySdk", - .product( - name: "Thrift", package: "Thrift-Swift", - condition: .when(platforms: [.iOS, .macOS, .tvOS, .macCatalyst, .linux]) - ), - ], - path: "Sources/Exporters/Jaeger" - ), - .testTarget( - name: "JaegerExporterTests", - dependencies: ["JaegerExporter"], - path: "Tests/ExportersTests/Jaeger" - ), - .executableTarget( - name: "SimpleExporter", - dependencies: [ - "OpenTelemetrySdk", "JaegerExporter", "StdoutExporter", "ZipkinExporter", - "ResourceExtension", "SignPostIntegration", - ], - path: "Examples/Simple Exporter", - exclude: ["README.md"] - ), - .target( - name: "NetworkStatus", - dependencies: [ - "OpenTelemetryApi" - ], - path: "Sources/Instrumentation/NetworkStatus", - linkerSettings: [.linkedFramework("CoreTelephony", .when(platforms: [.iOS]))] - ), - .testTarget( - name: "NetworkStatusTests", - dependencies: [ - "NetworkStatus" - ], - path: "Tests/InstrumentationTests/NetworkStatusTests" - ), - .target( - name: "URLSessionInstrumentation", - dependencies: ["OpenTelemetrySdk", "NetworkStatus"], - path: "Sources/Instrumentation/URLSession", - exclude: ["README.md"] - ), - .testTarget( - name: "URLSessionInstrumentationTests", - dependencies: [ - "URLSessionInstrumentation", - .product(name: "NIO", package: "swift-nio"), - .product(name: "NIOHTTP1", package: "swift-nio"), - ], - path: "Tests/InstrumentationTests/URLSessionTests" - ), - .executableTarget( - name: "NetworkSample", - dependencies: ["URLSessionInstrumentation", "StdoutExporter"], - path: "Examples/Network Sample", - exclude: ["README.md"] - ), - .target( - name: "ZipkinExporter", - dependencies: ["OpenTelemetrySdk"], - path: "Sources/Exporters/Zipkin" - ), - .testTarget( - name: "ZipkinExporterTests", - dependencies: ["ZipkinExporter"], - path: "Tests/ExportersTests/Zipkin" - ), - .executableTarget( - name: "OTLPExporter", - dependencies: [ - "OpenTelemetrySdk", "OpenTelemetryProtocolExporterGrpc", "StdoutExporter", - "ZipkinExporter", "ResourceExtension", "SignPostIntegration", - ], - path: "Examples/OTLP Exporter", - exclude: ["README.md", "prometheus.yaml", "collector-config.yaml", "docker-compose.yaml", "images"] - ), - .executableTarget( - name: "OTLPHTTPExporter", - dependencies: [ - "OpenTelemetrySdk", "OpenTelemetryProtocolExporterHttp", "StdoutExporter", - "ZipkinExporter", "ResourceExtension", "SignPostIntegration", - .product( - name: "DataCompression", - package: "DataCompression", - condition: .when(platforms: [.macOS, .iOS, .watchOS, .tvOS, .visionOS]) - ), - ], - path: "Examples/OTLP HTTP Exporter", - exclude: ["README.md", "collector-config.yaml", "docker-compose.yaml", "prometheus.yaml", "images"] - ), - .target( - name: "SignPostIntegration", - dependencies: ["OpenTelemetrySdk"], - path: "Sources/Instrumentation/SignPostIntegration", - exclude: ["README.md"] - ), - .target( - name: "ResourceExtension", - dependencies: ["OpenTelemetrySdk"], - path: "Sources/Instrumentation/SDKResourceExtension", - exclude: ["README.md"] - ), - .testTarget( - name: "ResourceExtensionTests", - dependencies: ["ResourceExtension", "OpenTelemetrySdk"], - path: "Tests/InstrumentationTests/SDKResourceExtensionTests" - ), - .executableTarget( - name: "PrometheusSample", - dependencies: ["OpenTelemetrySdk", "PrometheusExporter"], - path: "Examples/Prometheus Sample", - exclude: ["README.md"] - ), - ]) - #endif - - return self - } -} +) if ProcessInfo.processInfo.environment["OTEL_ENABLE_SWIFTLINT"] != nil { package.dependencies.append(contentsOf: [ diff --git a/README.md b/README.md index d049c44c..12a4e269 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ For more information about the maintainer role, see the [community repository](h For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver). -### Triager ([@open-telemetry/swift-triagers](https://github.com/orgs/open-telemetry/teams/swift-triagers)) +### Triager ([@open-telemetry/swift-core-triagers](https://github.com/orgs/open-telemetry/teams/swift-core-triagers)) - [Alolita Sharma](https://github.com/alolita), Apple diff --git a/Sources/Bridges/OTelSwiftLog/LogHandler.swift b/Sources/Bridges/OTelSwiftLog/LogHandler.swift deleted file mode 100644 index 28575a0e..00000000 --- a/Sources/Bridges/OTelSwiftLog/LogHandler.swift +++ /dev/null @@ -1,141 +0,0 @@ -import Foundation -import OpenTelemetryApi -import Logging - -// let the bridgename be the url of the package? -let bridgeName: String = "OTelSwiftLog" -let version: String = "1.0.0" - -/// A custom log handler to translate swift logs into otel logs -public struct OTelLogHandler: LogHandler { - /// Get or set the configured log level. - /// - /// - note: `LogHandler`s must treat the log level as a value type. This means that the change in metadata must - /// only affect this very `LogHandler`. It is acceptable to provide some form of global log level override - /// that means a change in log level on a particular `LogHandler` might not be reflected in any - /// `LogHandler`. - public var logLevel: Logging.Logger.Level = .info - - /// loggerProvider to use for the bridge. - private var loggerProvider: LoggerProvider - private var logger: OpenTelemetryApi.Logger - - // Define metadata for this handler - public var metadata: Logging.Logger.Metadata = [:] - public subscript(metadataKey key: String) -> Logging.Logger.Metadata.Value? { - get { - return metadata[key] - } - set { - metadata[key] = newValue - } - } - - /// create a new OtelLogHandler - /// - Parameter loggerProvider: The logger provider to use in the bridge. Defaults to the global logger provider. - /// - Parameter includeTraceContext : boolean flag used for the logger builder - /// - Parameter attributes: attributes to apply to the logger builder - public init(loggerProvider: LoggerProvider = OpenTelemetryApi.DefaultLoggerProvider.instance, - includeTraceContext: Bool = true, - attributes: [String: AttributeValue] = [String: AttributeValue]()) { - self.loggerProvider = loggerProvider - logger = self.loggerProvider.loggerBuilder(instrumentationScopeName: bridgeName) - .setInstrumentationVersion(version) - .setEventDomain("device") - .setIncludeTraceContext(true) - .setAttributes(attributes) - .setIncludeTraceContext(includeTraceContext) - .build() - } - - public func log(level: Logging.Logger.Level, - message: Logging.Logger.Message, - metadata: Logging.Logger.Metadata?, - source: String, - file: String, - function: String, - line: UInt) { - // This converts log atrributes to otel attributes - var otelattributes: [String: AttributeValue] = [ - "source": AttributeValue.string(source), - "file": AttributeValue.string(file), - "function": AttributeValue.string(function), - "line": AttributeValue.int(Int(line)) - ] - - // Convert metadata from the method parameter to AttributeValue and assign it to otelattributes - if let metadata { - let methodMetadata = convertMetadata(metadata) - otelattributes.merge(methodMetadata) { _, new in new } - } - - // Convert metadata from the struct property to AttributeValue and merge it with otelattributes - let structMetadata = convertMetadata(self.metadata) - otelattributes.merge(structMetadata) { _, new in new } - - // Build the log record and emit it - let event = logger.logRecordBuilder().setSeverity(convertSeverity(level: level)) - .setBody(AttributeValue.string(message.description)) - .setAttributes(otelattributes) - - if let context = OpenTelemetry.instance.contextProvider.activeSpan?.context { - _ = event.setSpanContext(context) - } - event.emit() - } -} - -func convertMetadata(_ metadata: Logging.Logger.Metadata) -> [String: AttributeValue] { - var convertedAttributes: [String: AttributeValue] = [:] - - // Iterate over each key-value pair in the metadata dictionary - for (key, value) in metadata { - // Convert each value to AttributeValue - let attributeValue = convertToAttributeValue(value) - - // Store the converted value with its corresponding key in the attributes dictionary - convertedAttributes[key] = attributeValue - } - - return convertedAttributes -} - -// Function to recursively convert nested dictionaries to AttributeValue -func convertToAttributeValue(_ value: Logging.Logger.Metadata.Value) -> AttributeValue { - switch value { - case let .dictionary(nestedDictionary): - // If value is a nested dictionary, recursively convert it - var nestedAttributes: [String: AttributeValue] = [:] - for (nestedKey, nestedValue) in nestedDictionary { - nestedAttributes[nestedKey] = convertToAttributeValue(nestedValue) - } - return AttributeValue.set(AttributeSet(labels: nestedAttributes)) - case let .array(nestedArray): - // If value is a nested array, recursively convert it - let nestedValues = nestedArray.map { convertToAttributeValue($0) } - return AttributeValue.array(AttributeArray(values: nestedValues)) - case let .string(str): - return AttributeValue(str) - case let .stringConvertible(strConvertable): - return AttributeValue(strConvertable.description) - } -} - -func convertSeverity(level: Logging.Logger.Level) -> OpenTelemetryApi.Severity { - switch level { - case .trace: - return OpenTelemetryApi.Severity.trace - case .debug: - return OpenTelemetryApi.Severity.debug - case .info: - return OpenTelemetryApi.Severity.info - case .notice: - return OpenTelemetryApi.Severity.info2 - case .warning: - return OpenTelemetryApi.Severity.warn - case .error: - return OpenTelemetryApi.Severity.error - case .critical: - return OpenTelemetryApi.Severity.error2 // should this be fatal instead? - } -} diff --git a/Sources/Bridges/OTelSwiftLog/README.md b/Sources/Bridges/OTelSwiftLog/README.md deleted file mode 100644 index b90d7ccf..00000000 --- a/Sources/Bridges/OTelSwiftLog/README.md +++ /dev/null @@ -1,70 +0,0 @@ -### How to use OTelLogHandler - -1. Using Default Scope: - -```swift -import Foundation -import Logging - -// Initialize the OTelLogHandler without a custom scope (using default scope) -let otelLogHandler = OTelLogHandler() - -// Create a Logger instance with the default log handler -var logger = Logger(label: "com.example.myapp") -logger.logLevel = .debug -logger.handler = otelLogHandler - -// Log messages with various log levels -logger.debug("This is a debug message") - -// Log with additional metadata -logger[metadataKey: "customKey"] = "customValue" -logger.info("Logging with additional metadata") -``` - -2. Using Custom Scope: -```swift -import Foundation -import Logging - -// Initialize a custom instrumentation scope -let customScope = InstrumentationScope( - name: "MyCustomInstrumentationScope", - version: "1.0.0", - eventDomain: "MyEventDomain", - schemaUrl: "https://example.com/schema", - includeTraceContext: true, - attributes: ["customAttribute": AttributeValue.string("customValue")] -) - -// Initialize the OTelLogHandler with custom scope -let otelLogHandler = OTelLogHandler(scope: customScope) - -// Create a Logger instance with the custom log handler -var logger = Logger(label: "com.example.myapp") -logger.logLevel = .debug -logger.handler = otelLogHandler - -// Log messages with various log levels -logger.debug("This is a debug message") -``` - -3. Using Custom Logger Provider: -```swift -import Foundation -import Logging - -// Initialize a custom LoggerProvider -let customLoggerProvider = MyCustomLoggerProvider() - -// Initialize the OTelLogHandler with custom LoggerProvider and default scope -let otelLogHandler = OTelLogHandler(loggerProvider: customLoggerProvider) - -// Create a Logger instance with the custom log handler -var logger = Logger(label: "com.example.myapp") -logger.logLevel = .debug -logger.handler = otelLogHandler - -// Log messages with various log levels -logger.debug("This is a debug message") -``` diff --git a/Sources/Contrib/Processors/BaggagePropagationProcessor/BaggagePropagationProcessor.swift b/Sources/Contrib/Processors/BaggagePropagationProcessor/BaggagePropagationProcessor.swift deleted file mode 100644 index f59fad0a..00000000 --- a/Sources/Contrib/Processors/BaggagePropagationProcessor/BaggagePropagationProcessor.swift +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public struct BaggagePropagationProcessor: SpanProcessor { - public let isStartRequired = true - public let isEndRequired = false - public let filter: (Entry) -> Bool - public var activeBaggage: () -> Baggage? = { - return OpenTelemetry.instance.contextProvider.activeBaggage - } - - public init(filter: @escaping (Entry) -> Bool) { - self.filter = filter - } - - public func onStart(parentContext: SpanContext?, - span: any ReadableSpan) { - if let baggage = activeBaggage() { - let filteredEntries = baggage.getEntries().filter(filter) - for entry in filteredEntries { - span.setAttribute(key: entry.key.name, value: entry.value.string) - } - } - } - - public func onEnd(span: any ReadableSpan) {} - - public func shutdown(explicitTimeout: TimeInterval? = nil) {} - - public func forceFlush(timeout: TimeInterval? = nil) {} -} diff --git a/Sources/Exporters/InMemory/InMemoryExporter.swift b/Sources/Exporters/InMemory/InMemoryExporter.swift deleted file mode 100644 index 4bc1ac91..00000000 --- a/Sources/Exporters/InMemory/InMemoryExporter.swift +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -public class InMemoryExporter: SpanExporter { - private var finishedSpanItems: [SpanData] = [] - private var isRunning: Bool = true - - public init() {} - - public func getFinishedSpanItems() -> [SpanData] { - return finishedSpanItems - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - guard isRunning else { - return .failure - } - - finishedSpanItems.append(contentsOf: spans) - return .success - } - - public func flush(explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - guard isRunning else { - return .failure - } - - return .success - } - - public func reset() { - finishedSpanItems.removeAll() - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) { - finishedSpanItems.removeAll() - isRunning = false - } -} diff --git a/Sources/Exporters/Jaeger/Adapter.swift b/Sources/Exporters/Jaeger/Adapter.swift deleted file mode 100644 index fce12d8a..00000000 --- a/Sources/Exporters/Jaeger/Adapter.swift +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - import OpenTelemetryApi - import OpenTelemetrySdk - import Thrift - - enum Adapter { - static let keyError = "error" - static let keyLogMessage = "message" - static let keySpanKind = "span.kind" - static let keySpanStatusMessage = "span.status.message" - static let keySpanStatusCode = "span.status.code" - - /// Converts a list of SpanData into a collection of Jaeger's Span. - /// - Parameter spans: the list of spans to be converted - static func toJaeger(spans: [SpanData]) -> [Span] { - var converted = [Span]() - converted.reserveCapacity(spans.count) - spans.forEach { - converted.append(toJaeger(span: $0)) - } - return converted - } - - /// Converts a single SpanData into a Jaeger's Span. - /// - Parameter span: the span to be converted - static func toJaeger(span: SpanData) -> Span { - var tags = TList() - var logs = TList() - var references = TList() - - let traceHex = span.traceId.hexString - let secondIndex = traceHex.index(traceHex.startIndex, offsetBy: 16) - let traceIdHigh = Int64(traceHex[traceHex.startIndex ..< secondIndex], radix: 16) ?? 0 - let traceIdLow = Int64(traceHex[secondIndex ..< traceHex.endIndex], radix: 16) ?? 0 - - let spanHex = span.spanId.hexString - let spanId = Int64(spanHex, radix: 16) ?? 0 - let operationName = span.name - let startTime = Int64(span.startTime.timeIntervalSince1970.toMicroseconds) - let duration = Int64(span.endTime.timeIntervalSince(span.startTime).toMicroseconds) - - var parentSpanId: Int64 = 0 - - tags.append(contentsOf: toJaegerTags(attributes: span.attributes)) - logs.append(contentsOf: toJaegerLogs(events: span.events)) - references.append(contentsOf: toSpanRefs(links: span.links)) - - if let parentId = span.parentSpanId, parentId.isValid { - let parentTraceIdHigh = traceIdHigh - let parentTraceIdLow = traceIdLow - - let spanHex = parentId.hexString - parentSpanId = Int64(spanHex, radix: 16) ?? 0 - - let refType = SpanRefType.child_of - let spanRef = SpanRef(refType: refType, traceIdLow: parentTraceIdLow, traceIdHigh: parentTraceIdHigh, - spanId: parentSpanId) - - references.append(spanRef) - } - - tags.append( - Tag(key: Adapter.keySpanKind, vType: .string, vStr: span.kind.rawValue.uppercased(), - vDouble: nil, vBool: nil, vLong: nil, 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)) - tags.append( - Tag(key: keyError, vType: .bool, vStr: nil, vDouble: nil, vBool: true, 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)) - - return Span(traceIdLow: traceIdLow, traceIdHigh: traceIdHigh, spanId: spanId, - parentSpanId: parentSpanId, operationName: operationName, references: references, flags: 0, - startTime: startTime, duration: duration, tags: tags, logs: logs) - } - - static func toJaegerTags(attributes: [String: AttributeValue]) -> [Tag] { - var tags = [Tag]() - tags.reserveCapacity(attributes.count) - attributes.forEach { - tags.append(toJaegerTag(key: $0.key, attrib: $0.value)) - } - return tags - } - - static func processAttributeArray(data: AttributeArray) -> [String] { - var processedValues = [String]() - data.values.forEach { item in - switch item { - case let .string(value): - processedValues.append("\"\(value)\"") - case let .bool(value): - processedValues.append(value.description) - case let .int(value): - processedValues.append(Int64(value).description) - case let .double(value): - processedValues.append(value.description) - case let .array(value): - let array = processAttributeArray(data: value) - if let json = try? String(data: JSONEncoder().encode(array), encoding: .utf8) { - processedValues.append(json) - } - case let .set(value): - if let json = try? String(data: JSONEncoder().encode(value), encoding: .utf8) { - processedValues.append(json) - } - case let .stringArray(value): - if let json = try? String(data: JSONEncoder().encode(value), encoding: .utf8) { - processedValues.append(json) - } - case let .boolArray(value): - if let json = try? String(data: JSONEncoder().encode(value), encoding: .utf8) { - processedValues.append(json) - } - case let .intArray(value): - if let json = try? String(data: JSONEncoder().encode(value), encoding: .utf8) { - processedValues.append(json) - } - case let .doubleArray(value): - if let json = try? String(data: JSONEncoder().encode(value), encoding: .utf8) { - processedValues.append(json) - } - } - } - return processedValues - } - - static func toJaegerTag(key: String, attrib: AttributeValue) -> Tag { - let key = key - var vType: TagType - var vStr: String? - var vDouble: Double? - var vBool: Bool? - var vLong: Int64? - - switch attrib { - case let .string(value): - vType = .string - vStr = value - case let .bool(value): - vType = .bool - vBool = value - case let .int(value): - vType = .long - vLong = Int64(value) - case let .double(value): - vType = .double - vDouble = value - case let .stringArray(value): - vType = .string - vStr = try? String(data: JSONEncoder().encode(value), encoding: .utf8) - case let .boolArray(value): - vType = .string - vStr = try? String(data: JSONEncoder().encode(value), encoding: .utf8) - case let .intArray(value): - vType = .string - vStr = try? String(data: JSONEncoder().encode(value), encoding: .utf8) - case let .doubleArray(value): - vType = .string - vStr = try? String(data: JSONEncoder().encode(value), encoding: .utf8) - case let .array(value): - vType = .string - vStr = "[\(processAttributeArray(data: value).joined(separator: ", "))]" - case let .set(value): - vType = .string - vStr = try? String(data: JSONEncoder().encode(value), encoding: .utf8) - } - return Tag(key: key, vType: vType, vStr: vStr, vDouble: vDouble, vBool: vBool, vLong: vLong, - vBinary: nil) - } - - static func toJaegerLogs(events: [SpanData.Event]) -> [Log] { - var logs = [Log]() - logs.reserveCapacity(events.count) - - events.forEach { - logs.append(toJaegerLog(event: $0)) - } - return logs - } - - static func toJaegerLog(event: SpanData.Event) -> Log { - let timestamp = Int64(event.timestamp.timeIntervalSince1970.toMicroseconds) - - var tags = TList() - tags.append( - Tag(key: Adapter.keyLogMessage, vType: .string, vStr: event.name, vDouble: nil, vBool: nil, - vLong: nil, vBinary: nil)) - tags.append(contentsOf: toJaegerTags(attributes: event.attributes)) - return Log(timestamp: timestamp, fields: tags) - } - - static func toSpanRefs(links: [SpanData.Link]) -> [SpanRef] { - var spanRefs = [SpanRef]() - spanRefs.reserveCapacity(links.count) - links.forEach { - spanRefs.append(toSpanRef(link: $0)) - } - return spanRefs - } - - static func toSpanRef(link: SpanData.Link) -> SpanRef { - let traceHex = link.context.traceId.hexString - let secondIndex = traceHex.index(traceHex.startIndex, offsetBy: 16) - let traceIdHigh = Int64(traceHex[traceHex.startIndex ..< secondIndex], radix: 16) ?? 0 - let traceIdLow = Int64(traceHex[secondIndex ..< traceHex.endIndex], radix: 16) ?? 0 - - let spanHex = link.context.spanId.hexString - let spanId = Int64(spanHex, radix: 16) ?? 0 - let refType = SpanRefType.follows_from - - return SpanRef(refType: refType, traceIdLow: traceIdLow, traceIdHigh: traceIdHigh, spanId: spanId) - } - } - -#endif diff --git a/Sources/Exporters/Jaeger/Jaeger Thrift/agent+Exts.swift b/Sources/Exporters/Jaeger/Jaeger Thrift/agent+Exts.swift deleted file mode 100644 index 550df1e9..00000000 --- a/Sources/Exporters/Jaeger/Jaeger Thrift/agent+Exts.swift +++ /dev/null @@ -1,233 +0,0 @@ -/** - * Autogenerated by Thrift Compiler (0.13.0) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - - import Thrift - - private final class Agent_emitZipkinBatch_args { - fileprivate var spans: TList - - fileprivate init(spans: TList) { - self.spans = spans - } - } - - private func == (lhs: Agent_emitZipkinBatch_args, rhs: Agent_emitZipkinBatch_args) -> Bool { - return - lhs.spans == rhs.spans - } - - extension Agent_emitZipkinBatch_args: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(spans) - } - } - - extension Agent_emitZipkinBatch_args: TStruct { - fileprivate static var fieldIds: [String: Int32] { - return ["spans": 1] - } - - fileprivate static var structName: String { - return "Agent_emitZipkinBatch_args" - } - - fileprivate static func read(from proto: TProtocol) throws - -> Agent_emitZipkinBatch_args { - _ = try proto.readStructBegin() - var spans: TList! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .list): spans = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(spans, named: "spans") - - return Agent_emitZipkinBatch_args(spans: spans) - } - } - - private final class Agent_emitBatch_args { - fileprivate var batch: Batch - - fileprivate init(batch: Batch) { - self.batch = batch - } - } - - private func == (lhs: Agent_emitBatch_args, rhs: Agent_emitBatch_args) -> Bool { - return lhs.batch == rhs.batch - } - - extension Agent_emitBatch_args: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(batch) - } - } - - extension Agent_emitBatch_args: TStruct { - fileprivate static var fieldIds: [String: Int32] { - return ["batch": 1] - } - - fileprivate static var structName: String { return "Agent_emitBatch_args" } - - fileprivate static func read(from proto: TProtocol) throws - -> Agent_emitBatch_args { - _ = try proto.readStructBegin() - var batch: Batch! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .struct): batch = try Batch.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(batch, named: "batch") - - return Agent_emitBatch_args(batch: batch) - } - } - - extension AgentClient: Agent { - private func send_emitZipkinBatch(spans: TList) throws { - try outProtocol.writeMessageBegin(name: "emitZipkinBatch", type: .oneway, sequenceID: 0) - let args = Agent_emitZipkinBatch_args(spans: spans) - try args.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - - public func emitZipkinBatch(spans: TList) throws { - try send_emitZipkinBatch(spans: spans) - try outProtocol.transport.flush() - } - - private func send_emitBatch(batch: Batch) throws { - try outProtocol.writeMessageBegin(name: "emitBatch", type: .oneway, sequenceID: 0) - let args = Agent_emitBatch_args(batch: batch) - try args.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - - public func emitBatch(batch: Batch) throws { - try send_emitBatch(batch: batch) - try outProtocol.transport.flush() - } - } - - extension AgentAsyncClient: AgentAsync { - private func send_emitZipkinBatch(on outProtocol: TProtocol, spans: TList) throws { - try outProtocol.writeMessageBegin(name: "emitZipkinBatch", type: .oneway, sequenceID: 0) - let args = Agent_emitZipkinBatch_args(spans: spans) - try args.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - - public func emitZipkinBatch(spans: TList, completion: @escaping (TAsyncResult) -> Void) { - let transport = factory.newTransport() - let proto = Protocol(on: transport) - - do { - try send_emitZipkinBatch(on: proto, spans: spans) - } catch { - completion(.error(error)) - } - - transport.flush { _, error in - if let error { - completion(.error(error)) - } - completion(.success(())) - } - } - - private func send_emitBatch(on outProtocol: TProtocol, batch: Batch) throws { - try outProtocol.writeMessageBegin(name: "emitBatch", type: .oneway, sequenceID: 0) - let args = Agent_emitBatch_args(batch: batch) - try args.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - - public func emitBatch(batch: Batch, completion: @escaping (TAsyncResult) -> Void) { - let transport = factory.newTransport() - let proto = Protocol(on: transport) - - do { - try send_emitBatch(on: proto, batch: batch) - } catch { - completion(.error(error)) - } - - transport.flush { _, error in - - if let error { - completion(.error(error)) - } - completion(.success(())) - } - } - } - - extension AgentProcessor: TProcessor { - static let processorHandlers: ProcessorHandlerDictionary = { - var processorHandlers = ProcessorHandlerDictionary() - - processorHandlers["emitZipkinBatch"] = { _, inProtocol, _, _ in - - let args = try Agent_emitZipkinBatch_args.read(from: inProtocol) - - try inProtocol.readMessageEnd() - } - processorHandlers["emitBatch"] = { _, inProtocol, _, _ in - - let args = try Agent_emitBatch_args.read(from: inProtocol) - - try inProtocol.readMessageEnd() - } - return processorHandlers - }() - - public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { - let (messageName, _, sequenceID) = try inProtocol.readMessageBegin() - if let processorHandler = AgentProcessor.processorHandlers[messageName] { - do { - try processorHandler(sequenceID, inProtocol, outProtocol, service) - } catch let error as TApplicationError { - try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error) - } - } else { - try inProtocol.skip(type: .struct) - try inProtocol.readMessageEnd() - let ex = TApplicationError( - error: .unknownMethod(methodName: messageName)) - try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex) - } - } - } - -#endif diff --git a/Sources/Exporters/Jaeger/Jaeger Thrift/agent.swift b/Sources/Exporters/Jaeger/Jaeger Thrift/agent.swift deleted file mode 100644 index 523f7a62..00000000 --- a/Sources/Exporters/Jaeger/Jaeger Thrift/agent.swift +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Autogenerated by Thrift Compiler (0.13.0) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - - import Thrift - - public protocol Agent { - /// - /// - Parameters: - /// - spans: - /// - Throws: - func emitZipkinBatch(spans: TList) throws - - /// - /// - Parameters: - /// - batch: - /// - Throws: - func emitBatch(batch: Batch) throws - } - - open class AgentClient: TClient /* , Agent */ {} - - public protocol AgentAsync { - /// - /// - Parameters: - /// - spans: - /// - completion: TAsyncResult wrapping return and following Exceptions: - func emitZipkinBatch(spans: TList, completion: @escaping (TAsyncResult) -> Void) - - /// - /// - Parameters: - /// - batch: - /// - completion: TAsyncResult wrapping return and following Exceptions: - func emitBatch(batch: Batch, completion: @escaping (TAsyncResult) -> Void) - } - - open class AgentAsyncClient: TAsyncClient /* , Agent */ {} - - open class AgentProcessor /* Agent */ { - typealias ProcessorHandlerDictionary = [String: (Int32, TProtocol, TProtocol, Agent) throws -> Void] - - public var service: Agent - - public required init(service: Agent) { - self.service = service - } - } - -#endif diff --git a/Sources/Exporters/Jaeger/Jaeger Thrift/jaeger+Exts.swift b/Sources/Exporters/Jaeger/Jaeger Thrift/jaeger+Exts.swift deleted file mode 100644 index b2ea1ad7..00000000 --- a/Sources/Exporters/Jaeger/Jaeger Thrift/jaeger+Exts.swift +++ /dev/null @@ -1,706 +0,0 @@ -/** - * Autogenerated by Thrift Compiler (0.13.0) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - - import Thrift - - public func == (lhs: Tag, rhs: Tag) -> Bool { - return - (lhs.key == rhs.key) && (lhs.vType == rhs.vType) && (lhs.vStr == rhs.vStr) - && (lhs.vDouble == rhs.vDouble) && (lhs.vBool == rhs.vBool) - && (lhs.vLong == rhs.vLong) && (lhs.vBinary == rhs.vBinary) - } - - extension Tag: CustomStringConvertible { - public var description: String { - var desc = "Tag(" - desc += "key=\(String(describing: key)), " - desc += "vType=\(String(describing: vType)), " - desc += "vStr=\(String(describing: vStr)), " - desc += "vDouble=\(String(describing: vDouble)), " - desc += "vBool=\(String(describing: vBool)), " - desc += "vLong=\(String(describing: vLong)), " - desc += "vBinary=\(String(describing: vBinary))" - return desc - } - } - - extension Tag: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(key) - hasher.combine(vType) - hasher.combine(vStr) - hasher.combine(vDouble) - hasher.combine(vBool) - hasher.combine(vLong) - hasher.combine(vBinary) - } - } - - extension Tag: TStruct { - public static var fieldIds: [String: Int32] { - return [ - "key": 1, "vType": 2, "vStr": 3, "vDouble": 4, "vBool": 5, "vLong": 6, - "vBinary": 7 - ] - } - - public static var structName: String { return "Tag" } - - public static func read(from proto: TProtocol) throws -> Tag { - _ = try proto.readStructBegin() - var key: String! - var vType: TagType! - var vStr: String? - var vDouble: Double? - var vBool: Bool? - var vLong: Int64? - var vBinary: Data? - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .string): key = try String.read(from: proto) - case (2, .i32): vType = try TagType.read(from: proto) - case (3, .string): vStr = try String.read(from: proto) - case (4, .double): vDouble = try Double.read(from: proto) - case (5, .bool): vBool = try Bool.read(from: proto) - case (6, .i64): vLong = try Int64.read(from: proto) - case (7, .string): vBinary = try Data.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(key, named: "key") - try proto.validateValue(vType, named: "vType") - - return Tag(key: key, vType: vType, vStr: vStr, vDouble: vDouble, vBool: vBool, - vLong: vLong, vBinary: vBinary) - } - } - - public func == (lhs: Log, rhs: Log) -> Bool { - return - (lhs.timestamp == rhs.timestamp) && (lhs.fields == rhs.fields) - } - - extension Log: CustomStringConvertible { - public var description: String { - var desc = "Log(" - desc += "timestamp=\(String(describing: timestamp)), " - desc += "fields=\(String(describing: fields))" - return desc - } - } - - extension Log: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(timestamp) - hasher.combine(fields) - } - } - - extension Log: TStruct { - public static var fieldIds: [String: Int32] { - return ["timestamp": 1, "fields": 2] - } - - public static var structName: String { return "Log" } - - public static func read(from proto: TProtocol) throws -> Log { - _ = try proto.readStructBegin() - var timestamp: Int64! - var fields: TList! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .i64): timestamp = try Int64.read(from: proto) - case (2, .list): fields = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(timestamp, named: "timestamp") - try proto.validateValue(fields, named: "fields") - - return Log(timestamp: timestamp, fields: fields) - } - } - - public func == (lhs: SpanRef, rhs: SpanRef) -> Bool { - return - (lhs.refType == rhs.refType) && (lhs.traceIdLow == rhs.traceIdLow) - && (lhs.traceIdHigh == rhs.traceIdHigh) && (lhs.spanId == rhs.spanId) - } - - extension SpanRef: CustomStringConvertible { - public var description: String { - var desc = "SpanRef(" - desc += "refType=\(String(describing: refType)), " - desc += "traceIdLow=\(String(describing: traceIdLow)), " - desc += "traceIdHigh=\(String(describing: traceIdHigh)), " - desc += "spanId=\(String(describing: spanId))" - return desc - } - } - - extension SpanRef: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(refType) - hasher.combine(traceIdLow) - hasher.combine(traceIdHigh) - hasher.combine(spanId) - } - } - - extension SpanRef: TStruct { - public static var fieldIds: [String: Int32] { - return ["refType": 1, "traceIdLow": 2, "traceIdHigh": 3, "spanId": 4] - } - - public static var structName: String { return "SpanRef" } - - public static func read(from proto: TProtocol) throws -> SpanRef { - _ = try proto.readStructBegin() - var refType: SpanRefType! - var traceIdLow: Int64! - var traceIdHigh: Int64! - var spanId: Int64! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .i32): refType = try SpanRefType.read(from: proto) - case (2, .i64): traceIdLow = try Int64.read(from: proto) - case (3, .i64): traceIdHigh = try Int64.read(from: proto) - case (4, .i64): spanId = try Int64.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(refType, named: "refType") - try proto.validateValue(traceIdLow, named: "traceIdLow") - try proto.validateValue(traceIdHigh, named: "traceIdHigh") - try proto.validateValue(spanId, named: "spanId") - - return SpanRef(refType: refType, traceIdLow: traceIdLow, traceIdHigh: traceIdHigh, - spanId: spanId) - } - } - - public func == (lhs: Span, rhs: Span) -> Bool { - return - (lhs.traceIdLow == rhs.traceIdLow) && (lhs.traceIdHigh == rhs.traceIdHigh) - && (lhs.spanId == rhs.spanId) && (lhs.parentSpanId == rhs.parentSpanId) - && (lhs.operationName == rhs.operationName) - && (lhs.references == rhs.references) && (lhs.flags == rhs.flags) - && (lhs.startTime == rhs.startTime) && (lhs.duration == rhs.duration) - && (lhs.tags == rhs.tags) && (lhs.logs == rhs.logs) - } - - extension Span: CustomStringConvertible { - public var description: String { - var desc = "Span(" - desc += "traceIdLow=\(String(describing: traceIdLow)), " - desc += "traceIdHigh=\(String(describing: traceIdHigh)), " - desc += "spanId=\(String(describing: spanId)), " - desc += "parentSpanId=\(String(describing: parentSpanId)), " - desc += "operationName=\(String(describing: operationName)), " - desc += "references=\(String(describing: references)), " - desc += "flags=\(String(describing: flags)), " - desc += "startTime=\(String(describing: startTime)), " - desc += "duration=\(String(describing: duration)), " - desc += "tags=\(String(describing: tags)), " - desc += "logs=\(String(describing: logs))" - return desc - } - } - - extension Span: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(traceIdLow) - hasher.combine(traceIdHigh) - hasher.combine(spanId) - hasher.combine(parentSpanId) - hasher.combine(operationName) - hasher.combine(references) - hasher.combine(flags) - hasher.combine(startTime) - hasher.combine(duration) - hasher.combine(tags) - hasher.combine(logs) - } - } - - extension Span: TStruct { - public static var fieldIds: [String: Int32] { - return [ - "traceIdLow": 1, "traceIdHigh": 2, "spanId": 3, "parentSpanId": 4, - "operationName": 5, "references": 6, "flags": 7, "startTime": 8, - "duration": 9, "tags": 10, "logs": 11 - ] - } - - public static var structName: String { return "Span" } - - public static func read(from proto: TProtocol) throws -> Span { - _ = try proto.readStructBegin() - var traceIdLow: Int64! - var traceIdHigh: Int64! - var spanId: Int64! - var parentSpanId: Int64! - var operationName: String! - var references: TList? - var flags: Int32! - var startTime: Int64! - var duration: Int64! - var tags: TList? - var logs: TList? - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .i64): traceIdLow = try Int64.read(from: proto) - case (2, .i64): traceIdHigh = try Int64.read(from: proto) - case (3, .i64): spanId = try Int64.read(from: proto) - case (4, .i64): parentSpanId = try Int64.read(from: proto) - case (5, .string): operationName = try String.read(from: proto) - case (6, .list): references = try TList.read(from: proto) - case (7, .i32): flags = try Int32.read(from: proto) - case (8, .i64): startTime = try Int64.read(from: proto) - case (9, .i64): duration = try Int64.read(from: proto) - case (10, .list): tags = try TList.read(from: proto) - case (11, .list): logs = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(traceIdLow, named: "traceIdLow") - try proto.validateValue(traceIdHigh, named: "traceIdHigh") - try proto.validateValue(spanId, named: "spanId") - try proto.validateValue(parentSpanId, named: "parentSpanId") - try proto.validateValue(operationName, named: "operationName") - try proto.validateValue(flags, named: "flags") - try proto.validateValue(startTime, named: "startTime") - try proto.validateValue(duration, named: "duration") - - return Span(traceIdLow: traceIdLow, traceIdHigh: traceIdHigh, spanId: spanId, - parentSpanId: parentSpanId, operationName: operationName, - references: references, flags: flags, startTime: startTime, - duration: duration, tags: tags, logs: logs) - } - } - - public func == (lhs: Process, rhs: Process) -> Bool { - return - (lhs.serviceName == rhs.serviceName) && (lhs.tags == rhs.tags) - } - - extension Process: CustomStringConvertible { - public var description: String { - var desc = "Process(" - desc += "serviceName=\(String(describing: serviceName)), " - desc += "tags=\(String(describing: tags))" - return desc - } - } - - extension Process: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(serviceName) - hasher.combine(tags) - } - } - - extension Process: TStruct { - public static var fieldIds: [String: Int32] { - return ["serviceName": 1, "tags": 2] - } - - public static var structName: String { return "Process" } - - public static func read(from proto: TProtocol) throws -> Process { - _ = try proto.readStructBegin() - var serviceName: String! - var tags: TList? - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .string): serviceName = try String.read(from: proto) - case (2, .list): tags = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(serviceName, named: "serviceName") - - return Process(serviceName: serviceName, tags: tags) - } - } - - public func == (lhs: Batch, rhs: Batch) -> Bool { - return - (lhs.process == rhs.process) && (lhs.spans == rhs.spans) - } - - extension Batch: CustomStringConvertible { - public var description: String { - var desc = "Batch(" - desc += "process=\(String(describing: process)), " - desc += "spans=\(String(describing: spans))" - return desc - } - } - - extension Batch: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(process) - hasher.combine(spans) - } - } - - extension Batch: TStruct { - public static var fieldIds: [String: Int32] { - return ["process": 1, "spans": 2] - } - - public static var structName: String { return "Batch" } - - public static func read(from proto: TProtocol) throws -> Batch { - _ = try proto.readStructBegin() - var process: Process! - var spans: TList! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .struct): process = try Process.read(from: proto) - case (2, .list): spans = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(process, named: "process") - try proto.validateValue(spans, named: "spans") - - return Batch(process: process, spans: spans) - } - } - - public func == (lhs: BatchSubmitResponse, rhs: BatchSubmitResponse) -> Bool { - return - lhs.ok == rhs.ok - } - - extension BatchSubmitResponse: CustomStringConvertible { - public var description: String { - var desc = "BatchSubmitResponse(" - desc += "ok=\(String(describing: ok))" - return desc - } - } - - extension BatchSubmitResponse: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(ok) - } - } - - extension BatchSubmitResponse: TStruct { - public static var fieldIds: [String: Int32] { - return ["ok": 1] - } - - public static var structName: String { return "BatchSubmitResponse" } - - public static func read(from proto: TProtocol) throws -> BatchSubmitResponse { - _ = try proto.readStructBegin() - var ok: Bool! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .bool): ok = try Bool.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(ok, named: "ok") - - return BatchSubmitResponse(ok: ok) - } - } - - private final class Collector_submitBatches_args { - fileprivate var batches: TList - - fileprivate init(batches: TList) { - self.batches = batches - } - } - - private func == (lhs: Collector_submitBatches_args, rhs: Collector_submitBatches_args) -> Bool { - return - lhs.batches == rhs.batches - } - - extension Collector_submitBatches_args: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(batches) - } - } - - extension Collector_submitBatches_args: TStruct { - fileprivate static var fieldIds: [String: Int32] { - return ["batches": 1] - } - - fileprivate static var structName: String { - return "Collector_submitBatches_args" - } - - fileprivate static func read(from proto: TProtocol) throws - -> Collector_submitBatches_args { - _ = try proto.readStructBegin() - var batches: TList! - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (1, .list): batches = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - // Required fields - try proto.validateValue(batches, named: "batches") - - return Collector_submitBatches_args(batches: batches) - } - } - - private final class Collector_submitBatches_result { - fileprivate var success: TList? - - fileprivate init() {} - fileprivate init(success: TList?) { - self.success = success - } - } - - private func == (lhs: Collector_submitBatches_result, rhs: Collector_submitBatches_result) -> Bool { - return - lhs.success == rhs.success - } - - extension Collector_submitBatches_result: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(success) - } - } - - extension Collector_submitBatches_result: TStruct { - fileprivate static var fieldIds: [String: Int32] { - return ["success": 0] - } - - fileprivate static var structName: String { - return "Collector_submitBatches_result" - } - - fileprivate static func read(from proto: TProtocol) throws - -> Collector_submitBatches_result { - _ = try proto.readStructBegin() - var success: TList? - - fields: while true { - let (_, fieldType, fieldID) = try proto.readFieldBegin() - - switch (fieldID, fieldType) { - case (_, .stop): break fields - case (0, .list): - success = try TList.read(from: proto) - case let (_, unknownType): try proto.skip(type: unknownType) - } - - try proto.readFieldEnd() - } - - try proto.readStructEnd() - - return Collector_submitBatches_result(success: success) - } - } - - extension CollectorClient: Collector { - private func send_submitBatches(batches: TList) throws { - try outProtocol.writeMessageBegin(name: "submitBatches", type: .call, sequenceID: 0) - let args = Collector_submitBatches_args(batches: batches) - try args.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - - private func recv_submitBatches() throws -> TList { - try inProtocol.readResultMessageBegin() - let result = try Collector_submitBatches_result.read(from: inProtocol) - try inProtocol.readMessageEnd() - - if let success = result.success { - return success - } - throw TApplicationError( - error: .missingResult(methodName: "submitBatches")) - } - - public func submitBatches(batches: TList) throws -> TList { - try send_submitBatches(batches: batches) - try outProtocol.transport.flush() - return try recv_submitBatches() - } - } - - extension CollectorAsyncClient: CollectorAsync { - private func send_submitBatches(on outProtocol: TProtocol, batches: TList) throws { - try outProtocol.writeMessageBegin(name: "submitBatches", type: .call, sequenceID: 0) - let args = Collector_submitBatches_args(batches: batches) - try args.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - - private func recv_submitBatches(on inProtocol: TProtocol) throws -> TList { - try inProtocol.readResultMessageBegin() - let result = try Collector_submitBatches_result.read(from: inProtocol) - try inProtocol.readMessageEnd() - - if let success = result.success { - return success - } - throw TApplicationError( - error: .missingResult(methodName: "submitBatches")) - } - - public func submitBatches(batches: TList, - completion: @escaping (TAsyncResult>) -> Void) { - let transport = factory.newTransport() - let proto = Protocol(on: transport) - - do { - try send_submitBatches(on: proto, batches: batches) - } catch { - completion(.error(error)) - } - - transport.flush { _, error in - if let error { - completion(.error(error)) - } - do { - let result = try self.recv_submitBatches(on: proto) - completion(.success(result)) - } catch { - completion(.error(error)) - } - } - } - } - - extension CollectorProcessor: TProcessor { - static let processorHandlers: ProcessorHandlerDictionary = { - var processorHandlers = ProcessorHandlerDictionary() - - processorHandlers["submitBatches"] = { sequenceID, inProtocol, outProtocol, handler in - - let args = try Collector_submitBatches_args.read(from: inProtocol) - - try inProtocol.readMessageEnd() - - var result = Collector_submitBatches_result() - do { - result.success = try handler.submitBatches(batches: args.batches) - } catch { throw error } - - try outProtocol.writeMessageBegin(name: "submitBatches", type: .reply, sequenceID: sequenceID) - try result.write(to: outProtocol) - try outProtocol.writeMessageEnd() - } - return processorHandlers - }() - - public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { - let (messageName, _, sequenceID) = try inProtocol.readMessageBegin() - - if let processorHandler = CollectorProcessor.processorHandlers[ - messageName - ] { - do { - try processorHandler(sequenceID, inProtocol, outProtocol, service) - } catch let error as TApplicationError { - try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error) - } - } else { - try inProtocol.skip(type: .struct) - try inProtocol.readMessageEnd() - let ex = TApplicationError( - error: .unknownMethod(methodName: messageName)) - try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex) - } - } - } - -#endif diff --git a/Sources/Exporters/Jaeger/Jaeger Thrift/jaeger.swift b/Sources/Exporters/Jaeger/Jaeger Thrift/jaeger.swift deleted file mode 100644 index 679c441f..00000000 --- a/Sources/Exporters/Jaeger/Jaeger Thrift/jaeger.swift +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Autogenerated by Thrift Compiler (0.13.0) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - - import Thrift - - public enum TagType: TEnum { - case string - case double - case bool - case long - case binary - case unknown(Int32) - - public static func read(from proto: TProtocol) throws -> TagType { - let raw: Int32 = try proto.read() - let new = TagType(rawValue: raw) - if let unwrapped = new { - return unwrapped - } else { - throw TProtocolError(error: .invalidData, - message: "Invalid enum value (\(raw)) for \(TagType.self)") - } - } - - public init() { - self = .string - } - - public var rawValue: Int32 { - switch self { - case .string: return 0 - case .double: return 1 - case .bool: return 2 - case .long: return 3 - case .binary: return 4 - case let .unknown(value): return value - } - } - - public init?(rawValue: Int32) { - switch rawValue { - case 0: self = .string - case 1: self = .double - case 2: self = .bool - case 3: self = .long - case 4: self = .binary - default: self = .unknown(rawValue) - } - } - } - - public enum SpanRefType: TEnum { - case child_of - case follows_from - case unknown(Int32) - - public static func read(from proto: TProtocol) throws -> SpanRefType { - let raw: Int32 = try proto.read() - let new = SpanRefType(rawValue: raw) - if let unwrapped = new { - return unwrapped - } else { - throw TProtocolError(error: .invalidData, - message: "Invalid enum value (\(raw)) for \(SpanRefType.self)") - } - } - - public init() { - self = .child_of - } - - public var rawValue: Int32 { - switch self { - case .child_of: return 0 - case .follows_from: return 1 - case let .unknown(value): return value - } - } - - public init?(rawValue: Int32) { - switch rawValue { - case 0: self = .child_of - case 1: self = .follows_from - default: self = .unknown(rawValue) - } - } - } - - public final class Tag { - public var key: String - - public var vType: TagType - - public var vStr: String? - - public var vDouble: Double? - - public var vBool: Bool? - - public var vLong: Int64? - - public var vBinary: Data? - - public init(key: String, vType: TagType) { - self.key = key - self.vType = vType - } - - public init(key: String, vType: TagType, vStr: String?, vDouble: Double?, vBool: Bool?, vLong: Int64?, vBinary: Data?) { - self.key = key - self.vType = vType - self.vStr = vStr - self.vDouble = vDouble - self.vBool = vBool - self.vLong = vLong - self.vBinary = vBinary - } - } - - public final class Log { - public var timestamp: Int64 - - public var fields: TList - - public init(timestamp: Int64, fields: TList) { - self.timestamp = timestamp - self.fields = fields - } - } - - public final class SpanRef { - public var refType: SpanRefType - - public var traceIdLow: Int64 - - public var traceIdHigh: Int64 - - public var spanId: Int64 - - public init(refType: SpanRefType, traceIdLow: Int64, traceIdHigh: Int64, spanId: Int64) { - self.refType = refType - self.traceIdLow = traceIdLow - self.traceIdHigh = traceIdHigh - self.spanId = spanId - } - } - - public final class Span { - public var traceIdLow: Int64 - - public var traceIdHigh: Int64 - - public var spanId: Int64 - - public var parentSpanId: Int64 - - public var operationName: String - - public var references: TList? - - public var flags: Int32 - - public var startTime: Int64 - - public var duration: Int64 - - public var tags: TList? - - public var logs: TList? - - public init(traceIdLow: Int64, traceIdHigh: Int64, spanId: Int64, parentSpanId: Int64, operationName: String, flags: Int32, startTime: Int64, duration: Int64) { - self.traceIdLow = traceIdLow - self.traceIdHigh = traceIdHigh - self.spanId = spanId - self.parentSpanId = parentSpanId - self.operationName = operationName - self.flags = flags - self.startTime = startTime - self.duration = duration - } - - public init(traceIdLow: Int64, traceIdHigh: Int64, spanId: Int64, parentSpanId: Int64, operationName: String, references: TList?, flags: Int32, startTime: Int64, duration: Int64, tags: TList?, logs: TList?) { - self.traceIdLow = traceIdLow - self.traceIdHigh = traceIdHigh - self.spanId = spanId - self.parentSpanId = parentSpanId - self.operationName = operationName - self.references = references - self.flags = flags - self.startTime = startTime - self.duration = duration - self.tags = tags - self.logs = logs - } - } - - public final class Process { - public var serviceName: String - - public var tags: TList? - - public init(serviceName: String) { - self.serviceName = serviceName - } - - public init(serviceName: String, tags: TList?) { - self.serviceName = serviceName - self.tags = tags - } - } - - public final class Batch { - public var process: Process - - public var spans: TList - - public init(process: Process, spans: TList) { - self.process = process - self.spans = spans - } - } - - public final class BatchSubmitResponse { - public var ok: Bool - - public init(ok: Bool) { - self.ok = ok - } - } - - public protocol Collector { - /// - /// - Parameters: - /// - batches: - /// - Returns: TList - /// - Throws: - func submitBatches(batches: TList) throws -> TList - } - - open class CollectorClient: TClient /* , Collector */ {} - - public protocol CollectorAsync { - /// - /// - Parameters: - /// - batches: - /// - completion: TAsyncResult> wrapping return and following Exceptions: - func submitBatches(batches: TList, completion: @escaping (TAsyncResult>) -> Void) - } - - open class CollectorAsyncClient: TAsyncClient /* , Collector */ {} - - open class CollectorProcessor /* Collector */ { - typealias ProcessorHandlerDictionary = [String: (Int32, TProtocol, TProtocol, Collector) throws -> Void] - - public var service: Collector - - public required init(service: Collector) { - self.service = service - } - } - -#endif diff --git a/Sources/Exporters/Jaeger/JaegerSpanExporter.swift b/Sources/Exporters/Jaeger/JaegerSpanExporter.swift deleted file mode 100644 index 6c6a6699..00000000 --- a/Sources/Exporters/Jaeger/JaegerSpanExporter.swift +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - import OpenTelemetrySdk - import Thrift - - public class JaegerSpanExporter: SpanExporter { - let collectorAddress: String - let process: Process - - public init(serviceName: String, collectorAddress: String) { - process = Process(serviceName: serviceName, tags: TList()) - self.collectorAddress = collectorAddress - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - var spanList = TList() - spanList.append(contentsOf: Adapter.toJaeger(spans: spans)) - let batch = Batch(process: process, spans: spanList) - let sender = Sender(host: collectorAddress) - let success = sender.sendBatch(batch: batch) - return success ? SpanExporterResultCode.success : SpanExporterResultCode.failure - } - - public func flush(explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - return .success - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) {} - } - -#endif diff --git a/Sources/Exporters/Jaeger/Sender.swift b/Sources/Exporters/Jaeger/Sender.swift deleted file mode 100644 index c430b518..00000000 --- a/Sources/Exporters/Jaeger/Sender.swift +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - import Network - import Thrift - - public class Sender { - private let host: String - private let port = 6832 - - lazy var address: sockaddr_storage? = { - guard let addresses = try? addressesFor(host: host, port: port) else { - return nil - } - return addresses[0] - }() - - public init(host: String) { - self.host = host - } - - final func sendBatch(batch: Batch) -> Bool { - let transport = TMemoryBufferTransport() - let proto = TBinaryProtocol(on: transport) - let agent = AgentClient(inoutProtocol: proto) - var batches = TList() - batches.append(batch) - do { - try agent.emitBatch(batch: batch) - } catch { - return false - } - - guard let address else { - return false - } - - let fd = socket(Int32(address.ss_family), SOCK_DGRAM, 0) - guard fd >= 0 else { - return false - } - defer { - close(fd) - } - - let sendResult = transport.writeBuffer.withUnsafeBytes { (rawBufferPointer: UnsafeRawBufferPointer) -> Int in - address.withSockAddr { sa, saLen -> Int in - sendto(fd, rawBufferPointer.baseAddress, transport.writeBuffer.count, 0, sa, saLen) - } - } - - return sendResult >= 0 - } - } - -#endif diff --git a/Sources/Exporters/Jaeger/Utils/UDPUtils.swift b/Sources/Exporters/Jaeger/Utils/UDPUtils.swift deleted file mode 100644 index 9f8ccaf4..00000000 --- a/Sources/Exporters/Jaeger/Utils/UDPUtils.swift +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -/// This code was adapted from Quinn “The Eskimo!” sample code at https://forums.developer.apple.com/thread/99494 -/// It uses BSD socket to send UDP Packages -/// Using Network framework would be easier and clearer but only supported from 10.14+. - -func addressesFor(host: String, port: Int) throws -> [sockaddr_storage] { - var hints = addrinfo() - hints.ai_socktype = SOCK_DGRAM - var addrList: UnsafeMutablePointer? - let err = getaddrinfo(host, "\(port)", &hints, &addrList) - guard err == 0, let start = addrList else { - throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotFindHost, userInfo: nil) - } - defer { - free(start) - } - return sequence(first: start, next: { $0.pointee.ai_next }).map { addr -> sockaddr_storage in - sockaddr_storage(sa: addr.pointee.ai_addr, saLen: addr.pointee.ai_addrlen) - } -} - -extension sockaddr_storage { - // not actually in Socket API Helper, but an 'obvious' extension - - init(sa: UnsafeMutablePointer, saLen: socklen_t) { - var ss = sockaddr_storage() - withUnsafeMutableBytes(of: &ss) { ssPtr in - let addrBuf = UnsafeRawBufferPointer(start: sa, count: Int(saLen)) - assert(addrBuf.count <= MemoryLayout.size) - ssPtr.copyMemory(from: addrBuf) - } - self = ss - } - - // from Socket API Helper - - static func fromSockAddr(_ body: (_ sa: UnsafeMutablePointer, _ saLen: inout socklen_t) throws -> ReturnType) rethrows -> (ReturnType, sockaddr_storage) { - // We need a mutable `sockaddr_storage` so that we can pass it to `withUnsafePointer(to:_:)`. - var ss = sockaddr_storage() - // Similarly, we need a mutable copy of our length for the benefit of `saLen`. - var saLen = socklen_t(MemoryLayout.size) - let result = try withUnsafeMutablePointer(to: &ss) { - try $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { - try body($0, &saLen) - } - } - return (result, ss) - } - - // from Socket API Helper - - func withSockAddr(_ body: (_ sa: UnsafePointer, _ saLen: socklen_t) throws -> ReturnType) rethrows -> ReturnType { - // We need to create a mutable copy of `self` so that we can pass it to `withUnsafePointer(to:_:)`. - var ss = self - return try withUnsafePointer(to: &ss) { - try $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { - try body($0, socklen_t(self.ss_len)) - } - } - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/CommonAdapter.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/CommonAdapter.swift deleted file mode 100644 index 4af2c6f3..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/CommonAdapter.swift +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public enum CommonAdapter { - public static func toProtoAttribute(key: String, attributeValue: AttributeValue) - -> Opentelemetry_Proto_Common_V1_KeyValue { - var keyValue = Opentelemetry_Proto_Common_V1_KeyValue() - keyValue.key = key - switch attributeValue { - case let .string(value): - keyValue.value.stringValue = value - case let .bool(value): - keyValue.value.boolValue = value - case let .int(value): - keyValue.value.intValue = Int64(value) - case let .double(value): - keyValue.value.doubleValue = value - case let .set(value): - keyValue.value.kvlistValue.values = value.labels.map { - return toProtoAttribute(key: $0, attributeValue: $1) - } - case let .array(value): - keyValue.value.arrayValue.values = value.values.map { - return toProtoAnyValue(attributeValue: $0) - } - case let .stringArray(value): - keyValue.value.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .string($0)) - } - case let .boolArray(value): - keyValue.value.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .bool($0)) - } - case let .intArray(value): - keyValue.value.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .int($0)) - } - case let .doubleArray(value): - keyValue.value.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .double($0)) - } - } - return keyValue - } - - public static func toProtoAnyValue(attributeValue: AttributeValue) -> Opentelemetry_Proto_Common_V1_AnyValue { - var anyValue = Opentelemetry_Proto_Common_V1_AnyValue() - switch attributeValue { - case let .string(value): - anyValue.stringValue = value - case let .bool(value): - anyValue.boolValue = value - case let .int(value): - anyValue.intValue = Int64(value) - case let .double(value): - anyValue.doubleValue = value - case let .set(value): - anyValue.kvlistValue.values = value.labels.map { - return toProtoAttribute(key: $0, attributeValue: $1) - } - case let .array(value): - anyValue.arrayValue.values = value.values.map { - return toProtoAnyValue(attributeValue: $0) - } - case let .stringArray(value): - anyValue.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .string($0)) - } - case let .boolArray(value): - anyValue.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .bool($0)) - } - case let .intArray(value): - anyValue.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .int($0)) - } - case let .doubleArray(value): - anyValue.arrayValue.values = value.map { - return toProtoAnyValue(attributeValue: .double($0)) - } - } - return anyValue - } - - public static func toProtoInstrumentationScope(instrumentationScopeInfo: InstrumentationScopeInfo) - -> Opentelemetry_Proto_Common_V1_InstrumentationScope { - var instrumentationScope = Opentelemetry_Proto_Common_V1_InstrumentationScope() - instrumentationScope.name = instrumentationScopeInfo.name - if let version = instrumentationScopeInfo.version { - instrumentationScope.version = version - } - - if let attributes = instrumentationScopeInfo.attributes { - attributes.forEach { - instrumentationScope.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - } - return instrumentationScope - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/Constants.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/Constants.swift deleted file mode 100644 index 9c76e7d0..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/Constants.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation - -public enum Constants { - public enum OTLP { - public static let version = "0.20.0" - } - - public enum HTTP { - public static let userAgent = "User-Agent" - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/EnvVarHeaders.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/EnvVarHeaders.swift deleted file mode 100644 index a3ee72aa..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/EnvVarHeaders.swift +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -/// Provides a framework for detection of resource information from the environment variable -public struct EnvVarHeaders { - private static let labelListSplitter = Character(",") - private static let labelKeyValueSplitter = Character("=") - - /// This resource information is loaded from the - /// environment variable. - public static let attributes: [(String, String)]? = EnvVarHeaders.attributes() - - public static func attributes(for rawEnvAttributes: String? = ProcessInfo.processInfo.environment["OTEL_EXPORTER_OTLP_HEADERS"]) -> [(String, String)]? { - parseAttributes(rawEnvAttributes: rawEnvAttributes) - } - - private init() {} - - private static func isKey(token: String) -> Bool { - let alpha = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - let digit = CharacterSet(charactersIn: "0123456789") - let special = CharacterSet(charactersIn: "!#$%&'*+-.^_`|~") - let tchar = special.union(alpha).union(digit) - return tchar.isSuperset(of: CharacterSet(charactersIn: token)) - } - - private static func isValue(baggage: String) -> Bool { - let asciiSet = CharacterSet(charactersIn: UnicodeScalar(0) ..< UnicodeScalar(0x80)) - let special = CharacterSet(charactersIn: "^\"|\"$") - let baggageOctet = asciiSet.subtracting(.controlCharacters).subtracting(.whitespaces).union(special) - return baggageOctet.isSuperset(of: CharacterSet(charactersIn: baggage)) - } - - /// Creates a label map from the environment variable string. - /// - Parameter rawEnvLabels: the comma-separated list of labels - /// NOTE: Parsing does not fully match W3C Correlation-Context - private static func parseAttributes(rawEnvAttributes: String?) -> [(String, String)]? { - guard let rawEnvLabels = rawEnvAttributes else { return nil } - - var labels = [(String, String)]() - - rawEnvLabels.split(separator: labelListSplitter).forEach { - let split = $0.split(separator: labelKeyValueSplitter) - if split.count != 2 { - return - } - - let key = split[0].trimmingCharacters(in: .whitespaces) - guard isKey(token: key) else { return } - - let value = split[1].trimmingCharacters(in: .whitespaces) - guard isValue(baggage: value) else { return } - - labels.append((key, value)) - } - return labels.count > 0 ? labels : nil - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/ExporterMetrics.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/ExporterMetrics.swift deleted file mode 100644 index 6f59bacd..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/ExporterMetrics.swift +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// -import Foundation -import OpenTelemetryApi - -/// `ExporterMetrics` will provide a way to track how many data have been seen or successfully exported, -/// as well as how many failed. The exporter will adopt an instance of this and inject the provider as a dependency. -/// The host application can then track different types of exporters, such as `http, grpc, and log` -public class ExporterMetrics { - public enum TransporterType: String { - case grpc - case protoBuf = "http" - case httpJson = "http-json" - } - - public static let ATTRIBUTE_KEY_TYPE: String = "type" - public static let ATTRIBUTE_KEY_SUCCESS: String = "success" - - private let meterProvider: any MeterProvider - private let exporterName: String - private let transportName: String - private var seenAttrs: [String: AttributeValue] = [:] - private var successAttrs: [String: AttributeValue] = [:] - private var failedAttrs: [String: AttributeValue] = [:] - - private var seen: LongCounter? - private var exported: LongCounter? - - /// - Parameters: - /// - type: That represent what type of exporter it is. `otlp` - /// - meterProvider: Injected `StableMeterProvider` for metric - /// - exporterName: Could be `span`, `log` etc - /// - transportName: Kind of exporter defined by type `TransporterType` - public init(type: String, - meterProvider: any MeterProvider, - exporterName: String, - transportName: TransporterType) { - self.meterProvider = meterProvider - self.exporterName = exporterName - self.transportName = transportName.rawValue - seenAttrs = [ - ExporterMetrics.ATTRIBUTE_KEY_TYPE: .string(type) - ] - successAttrs = [ - ExporterMetrics.ATTRIBUTE_KEY_SUCCESS: .bool(true) - ] - failedAttrs = [ - ExporterMetrics.ATTRIBUTE_KEY_SUCCESS: .bool(false) - ] - - seen = meter.counterBuilder(name: "\(exporterName).exporter.seen").build() - exported = meter.counterBuilder(name: "\(exporterName).exporter.exported").build() - } - - public func addSeen(value: Int) { - seen?.add(value: value, attributes: seenAttrs) - } - - public func addSuccess(value: Int) { - exported?.add(value: value, attributes: successAttrs) - } - - public func addFailed(value: Int) { - exported?.add(value: value, attributes: failedAttrs) - } - - // MARK: - Private functions - - /*** - * Create an instance for recording exporter metrics under the meter - * "io.opentelemetry.exporters." + exporterName + "-transporterType". - **/ - private var meter: any Meter { - meterProvider.get(name: "io.opentelemetry.exporters.\(exporterName)-\(transportName)") - } - - // MARK: - Static function - - public static func makeExporterMetric(type: String, - meterProvider: any MeterProvider, - exporterName: String, - transportName: TransporterType) -> ExporterMetrics { - ExporterMetrics(type: type, - meterProvider: meterProvider, - exporterName: exporterName, - transportName: transportName) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/Headers.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/Headers.swift deleted file mode 100644 index ce85c7b8..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/Headers.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi - -public enum Headers { - // GetUserAgentHeader returns an OTLP header value of the form "OTel OTLP Exporter Swift/{{ .Version }}" - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#user-agent - public static func getUserAgentHeader() -> String { - var version = Constants.OTLP.version - if !version.isEmpty, version.hasPrefix("v") { - version = String(version.dropFirst(1)) - } - let userAgent = "OTel-OTLP-Exporter-Swift/\(version)" - - return userAgent - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/OtlpConfiguration.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/OtlpConfiguration.swift deleted file mode 100644 index c2c0d4d6..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/OtlpConfiguration.swift +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public enum CompressionType { - case gzip - case deflate - case none -} - -public struct OtlpConfiguration { - public static let DefaultTimeoutInterval: TimeInterval = .init(10) - - /* - * This is a first pass addition to satisfy the OTLP Configuration specification: - * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md - * It's possible to satisfy a few of these configuration options through the configuration of the GRPC channel - * It's worth considering re-factoring the initialization of the OTLP exporters to collect all the configuration - * in one locations. - * - * I've left several of the configuration options stubbed in comments, so that may be implemented in the future. - */ - // let endpoint : URL? = URL(string: "https://localhost:4317") - // let certificateFile - // let compression - public let headers: [(String, String)]? - public let timeout: TimeInterval - public let compression: CompressionType - public let exportAsJson: Bool - public init(timeout: TimeInterval = OtlpConfiguration.DefaultTimeoutInterval, - compression: CompressionType = .gzip, - headers: [(String, String)]? = nil, - exportAsJson: Bool = true) { - self.headers = headers - self.timeout = timeout - self.compression = compression - self.exportAsJson = exportAsJson - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/common/ResourceAdapter.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/common/ResourceAdapter.swift deleted file mode 100644 index 501d385f..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/common/ResourceAdapter.swift +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -public enum ResourceAdapter { - public static func toProtoResource(resource: Resource) -> Opentelemetry_Proto_Resource_V1_Resource { - var outputResource = Opentelemetry_Proto_Resource_V1_Resource() - resource.attributes.forEach { - let protoAttribute = CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value) - outputResource.attributes.append(protoAttribute) - } - return outputResource - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift deleted file mode 100644 index c8989582..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public class LogRecordAdapter { - public static func toProtoResourceRecordLog(logRecordList: [ReadableLogRecord]) -> [Opentelemetry_Proto_Logs_V1_ResourceLogs] { - let resourceAndScopeMap = groupByResourceAndScope(logRecordList: logRecordList) - var resourceLogs = [Opentelemetry_Proto_Logs_V1_ResourceLogs]() - resourceAndScopeMap.forEach { resMap in - var scopeLogs = [Opentelemetry_Proto_Logs_V1_ScopeLogs]() - resMap.value.forEach { scopeInfo, logRecords in - var protoScopeLogs = Opentelemetry_Proto_Logs_V1_ScopeLogs() - protoScopeLogs.scope = CommonAdapter.toProtoInstrumentationScope(instrumentationScopeInfo: scopeInfo) - logRecords.forEach { record in - protoScopeLogs.logRecords.append(record) - } - scopeLogs.append(protoScopeLogs) - } - var resourceLog = Opentelemetry_Proto_Logs_V1_ResourceLogs() - resourceLog.resource = ResourceAdapter.toProtoResource(resource: resMap.key) - resourceLog.scopeLogs.append(contentsOf: scopeLogs) - resourceLogs.append(resourceLog) - } - return resourceLogs - } - - static func groupByResourceAndScope(logRecordList: [ReadableLogRecord]) -> [Resource: [InstrumentationScopeInfo: [Opentelemetry_Proto_Logs_V1_LogRecord]]] { - var result = [Resource: [InstrumentationScopeInfo: [Opentelemetry_Proto_Logs_V1_LogRecord]]]() - logRecordList.forEach { logRecord in - result[logRecord.resource, default: [InstrumentationScopeInfo: [Opentelemetry_Proto_Logs_V1_LogRecord]]()][logRecord.instrumentationScopeInfo, default: [Opentelemetry_Proto_Logs_V1_LogRecord]()].append(toProtoLogRecord(logRecord: logRecord)) - } - return result - } - - static func toProtoLogRecord(logRecord: ReadableLogRecord) -> Opentelemetry_Proto_Logs_V1_LogRecord { - var protoLogRecord = Opentelemetry_Proto_Logs_V1_LogRecord() - - if let observedTimestamp = logRecord.observedTimestamp { - protoLogRecord.observedTimeUnixNano = observedTimestamp.timeIntervalSince1970.toNanoseconds - } - - protoLogRecord.timeUnixNano = logRecord.timestamp.timeIntervalSince1970.toNanoseconds - - if let body = logRecord.body { - protoLogRecord.body = CommonAdapter.toProtoAnyValue(attributeValue: body) - } - - if let severity = logRecord.severity { - protoLogRecord.severityText = severity.description - if let protoSeverity = Opentelemetry_Proto_Logs_V1_SeverityNumber(rawValue: severity.rawValue) { - protoLogRecord.severityNumber = protoSeverity - } - } - - if let context = logRecord.spanContext { - protoLogRecord.spanID = TraceProtoUtils.toProtoSpanId(spanId: context.spanId) - protoLogRecord.traceID = TraceProtoUtils.toProtoTraceId(traceId: context.traceId) - protoLogRecord.flags = UInt32(context.traceFlags.byte) - } - - var protoAttributes = [Opentelemetry_Proto_Common_V1_KeyValue]() - logRecord.attributes.forEach { key, value in - protoAttributes.append(CommonAdapter.toProtoAttribute(key: key, attributeValue: value)) - } - protoLogRecord.attributes = protoAttributes - return protoLogRecord - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/metric/MetricsAdapter.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/metric/MetricsAdapter.swift deleted file mode 100644 index 5d9c00b7..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/metric/MetricsAdapter.swift +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public enum MetricsAdapter { - public static func toProtoResourceMetrics(metricData: [MetricData]) -> [Opentelemetry_Proto_Metrics_V1_ResourceMetrics] { - let resourceAndScopeMap = groupByResourceAndScope(metricData: metricData) - - var resourceMetrics = [Opentelemetry_Proto_Metrics_V1_ResourceMetrics]() - resourceAndScopeMap.forEach { resMap in - var instrumentationScopeMetrics = [Opentelemetry_Proto_Metrics_V1_ScopeMetrics]() - resMap.value.forEach { instScope in - var protoInst = Opentelemetry_Proto_Metrics_V1_ScopeMetrics() - protoInst.scope = - CommonAdapter.toProtoInstrumentationScope(instrumentationScopeInfo: instScope.key) - instScope.value.forEach { - protoInst.metrics.append($0) - } - instrumentationScopeMetrics.append(protoInst) - } - var resourceMetric = Opentelemetry_Proto_Metrics_V1_ResourceMetrics() - resourceMetric.resource = ResourceAdapter.toProtoResource(resource: resMap.key) - resourceMetric.scopeMetrics.append(contentsOf: instrumentationScopeMetrics) - resourceMetrics.append(resourceMetric) - } - return resourceMetrics - } - - private static func groupByResourceAndScope(metricData: [MetricData]) -> [Resource: [InstrumentationScopeInfo: [Opentelemetry_Proto_Metrics_V1_Metric]]] { - var results = [Resource: [InstrumentationScopeInfo: [Opentelemetry_Proto_Metrics_V1_Metric]]]() - - metricData.forEach { - if let metric = toProtoMetric(metricData: $0) { - results[$0.resource, default: [InstrumentationScopeInfo: [Opentelemetry_Proto_Metrics_V1_Metric]]()][$0.instrumentationScopeInfo, default: [Opentelemetry_Proto_Metrics_V1_Metric]()].append(metric) - } - } - return results - } - - public static func toProtoMetric(metricData: MetricData) -> Opentelemetry_Proto_Metrics_V1_Metric? { - var protoMetric = Opentelemetry_Proto_Metrics_V1_Metric() - protoMetric.name = metricData.name - protoMetric.unit = metricData.unit - protoMetric.description_p = metricData.description - if metricData.data.points.isEmpty { return nil } - - metricData.data.points.forEach { - switch metricData.type { - case .LongGauge: - guard let gaugeData = $0 as? LongPointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_NumberDataPoint() - injectPointData(protoNumberPoint: &protoDataPoint, pointData: gaugeData) - protoDataPoint.value = .asInt(Int64(gaugeData.value)) - protoMetric.gauge.dataPoints.append(protoDataPoint) - case .LongSum: - guard let gaugeData = $0 as? LongPointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_NumberDataPoint() - injectPointData(protoNumberPoint: &protoDataPoint, pointData: gaugeData) - protoDataPoint.value = .asInt(Int64(gaugeData.value)) - protoMetric.sum.aggregationTemporality = metricData.data.aggregationTemporality.convertToProtoEnum() - protoMetric.sum.dataPoints.append(protoDataPoint) - protoMetric.sum.isMonotonic = metricData.isMonotonic - case .DoubleGauge: - guard let gaugeData = $0 as? DoublePointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_NumberDataPoint() - injectPointData(protoNumberPoint: &protoDataPoint, pointData: gaugeData) - protoDataPoint.value = .asDouble(gaugeData.value) - protoMetric.gauge.dataPoints.append(protoDataPoint) - case .DoubleSum: - guard let gaugeData = $0 as? DoublePointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_NumberDataPoint() - injectPointData(protoNumberPoint: &protoDataPoint, pointData: gaugeData) - protoDataPoint.value = .asDouble(gaugeData.value) - protoMetric.sum.aggregationTemporality = metricData.data.aggregationTemporality.convertToProtoEnum() - protoMetric.sum.dataPoints.append(protoDataPoint) - protoMetric.sum.isMonotonic = metricData.isMonotonic - case .Summary: - guard let summaryData = $0 as? SummaryPointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_SummaryDataPoint() - injectPointData(protoSummaryPoint: &protoDataPoint, pointData: summaryData) - protoDataPoint.sum = summaryData.sum - protoDataPoint.count = summaryData.count - summaryData.values.forEach { - var quantile = Opentelemetry_Proto_Metrics_V1_SummaryDataPoint.ValueAtQuantile() - quantile.quantile = $0.quantile - quantile.value = $0.value - protoDataPoint.quantileValues.append(quantile) - } - protoMetric.summary.dataPoints.append(protoDataPoint) - case .Histogram: - guard let histogramData = $0 as? HistogramPointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_HistogramDataPoint() - injectPointData(protoHistogramPoint: &protoDataPoint, pointData: histogramData) - protoDataPoint.sum = Double(histogramData.sum) - protoDataPoint.count = UInt64(histogramData.count) - protoDataPoint.max = Double(histogramData.max) - protoDataPoint.min = Double(histogramData.min) - protoDataPoint.explicitBounds = histogramData.boundaries.map { Double($0) } - protoDataPoint.bucketCounts = histogramData.counts.map { UInt64($0) } - protoMetric.histogram.aggregationTemporality = metricData.data.aggregationTemporality.convertToProtoEnum() - protoMetric.histogram.dataPoints.append(protoDataPoint) - case .ExponentialHistogram: - guard let exponentialHistogramData = $0 as? ExponentialHistogramPointData else { - break - } - var protoDataPoint = Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint() - injectPointData(protoExponentialHistogramPoint: &protoDataPoint, pointData: exponentialHistogramData) - protoDataPoint.scale = Int32(exponentialHistogramData.scale) - protoDataPoint.sum = Double(exponentialHistogramData.sum) - protoDataPoint.count = UInt64(exponentialHistogramData.count) - protoDataPoint.zeroCount = UInt64(exponentialHistogramData.zeroCount) - protoDataPoint.max = exponentialHistogramData.max - protoDataPoint.min = exponentialHistogramData.min - - var positiveBuckets = Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets() - positiveBuckets.offset = Int32(exponentialHistogramData.positiveBuckets.offset) - positiveBuckets.bucketCounts = exponentialHistogramData.positiveBuckets.bucketCounts.map { UInt64($0) } - - var negativeBuckets = Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets() - negativeBuckets.offset = Int32(exponentialHistogramData.negativeBuckets.offset) - negativeBuckets.bucketCounts = exponentialHistogramData.negativeBuckets.bucketCounts.map { UInt64($0) } - - protoDataPoint.positive = positiveBuckets - protoDataPoint.negative = negativeBuckets - - protoMetric.exponentialHistogram.aggregationTemporality = metricData.data.aggregationTemporality.convertToProtoEnum() - protoMetric.exponentialHistogram.dataPoints.append(protoDataPoint) - } - } - return protoMetric - } - - static func injectPointData(protoExponentialHistogramPoint protoPoint: inout Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint, pointData: PointData) { - protoPoint.timeUnixNano = pointData.endEpochNanos - protoPoint.startTimeUnixNano = pointData.startEpochNanos - - pointData.attributes.forEach { - protoPoint.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - - pointData.exemplars.forEach { - var protoExemplar = Opentelemetry_Proto_Metrics_V1_Exemplar() - protoExemplar.timeUnixNano = $0.epochNanos - - if let doubleExemplar = $0 as? DoubleExemplarData { - protoExemplar.value = .asDouble(doubleExemplar.value) - } - - if let longExemplar = $0 as? LongExemplarData { - protoExemplar.value = .asInt(Int64(longExemplar.value)) - } - - $0.filteredAttributes.forEach { - protoExemplar.filteredAttributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - if let spanContext = $0.spanContext { - protoExemplar.spanID = TraceProtoUtils.toProtoSpanId(spanId: spanContext.spanId) - protoExemplar.traceID = TraceProtoUtils.toProtoTraceId(traceId: spanContext.traceId) - } - protoPoint.exemplars.append(protoExemplar) - } - } - - static func injectPointData(protoHistogramPoint protoPoint: inout Opentelemetry_Proto_Metrics_V1_HistogramDataPoint, pointData: PointData) { - protoPoint.timeUnixNano = pointData.endEpochNanos - protoPoint.startTimeUnixNano = pointData.startEpochNanos - - pointData.attributes.forEach { - protoPoint.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - - pointData.exemplars.forEach { - var protoExemplar = Opentelemetry_Proto_Metrics_V1_Exemplar() - protoExemplar.timeUnixNano = $0.epochNanos - - if let doubleExemplar = $0 as? DoubleExemplarData { - protoExemplar.value = .asDouble(doubleExemplar.value) - } - - if let longExemplar = $0 as? LongExemplarData { - protoExemplar.value = .asInt(Int64(longExemplar.value)) - } - - $0.filteredAttributes.forEach { - protoExemplar.filteredAttributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - if let spanContext = $0.spanContext { - protoExemplar.spanID = TraceProtoUtils.toProtoSpanId(spanId: spanContext.spanId) - protoExemplar.traceID = TraceProtoUtils.toProtoTraceId(traceId: spanContext.traceId) - } - protoPoint.exemplars.append(protoExemplar) - } - } - - static func injectPointData(protoSummaryPoint protoPoint: inout Opentelemetry_Proto_Metrics_V1_SummaryDataPoint, pointData: PointData) { - protoPoint.timeUnixNano = pointData.endEpochNanos - protoPoint.startTimeUnixNano = pointData.startEpochNanos - - pointData.attributes.forEach { - protoPoint.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - } - - static func injectPointData(protoNumberPoint protoPoint: inout Opentelemetry_Proto_Metrics_V1_NumberDataPoint, pointData: PointData) { - protoPoint.timeUnixNano = pointData.endEpochNanos - protoPoint.startTimeUnixNano = pointData.startEpochNanos - - pointData.attributes.forEach { - protoPoint.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - - pointData.exemplars.forEach { - var protoExemplar = Opentelemetry_Proto_Metrics_V1_Exemplar() - protoExemplar.timeUnixNano = $0.epochNanos - - $0.filteredAttributes.forEach { - protoExemplar.filteredAttributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - if let spanContext = $0.spanContext { - protoExemplar.spanID = TraceProtoUtils.toProtoSpanId(spanId: spanContext.spanId) - protoExemplar.traceID = TraceProtoUtils.toProtoTraceId(traceId: spanContext.traceId) - } - protoPoint.exemplars.append(protoExemplar) - } - } -} - -extension AggregationTemporality { - func convertToProtoEnum() -> Opentelemetry_Proto_Metrics_V1_AggregationTemporality { - switch self { - case .cumulative: - return .cumulative - case .delta: - return .delta - } - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/common.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/common.pb.swift deleted file mode 100644 index 3aaa0113..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/common.pb.swift +++ /dev/null @@ -1,502 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/common/v1/common.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2019, 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 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 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 {} - typealias Version = _2 -} - -/// AnyValue is used to represent any type of attribute value. AnyValue may contain a -/// primitive value such as a string or integer or it may contain an arbitrary nested -/// object containing arrays, key-value lists and primitives. -public struct Opentelemetry_Proto_Common_V1_AnyValue: @unchecked Sendable { - // 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 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 "empty". - public var value: Opentelemetry_Proto_Common_V1_AnyValue.OneOf_Value? = nil - - public var stringValue: String { - get { - if case .stringValue(let v)? = value {return v} - return String() - } - set {value = .stringValue(newValue)} - } - - public var boolValue: Bool { - get { - if case .boolValue(let v)? = value {return v} - return false - } - set {value = .boolValue(newValue)} - } - - public var intValue: Int64 { - get { - if case .intValue(let v)? = value {return v} - return 0 - } - set {value = .intValue(newValue)} - } - - public var doubleValue: Double { - get { - if case .doubleValue(let v)? = value {return v} - return 0 - } - set {value = .doubleValue(newValue)} - } - - public var arrayValue: Opentelemetry_Proto_Common_V1_ArrayValue { - get { - if case .arrayValue(let v)? = value {return v} - return Opentelemetry_Proto_Common_V1_ArrayValue() - } - set {value = .arrayValue(newValue)} - } - - public var kvlistValue: Opentelemetry_Proto_Common_V1_KeyValueList { - get { - if case .kvlistValue(let v)? = value {return v} - return Opentelemetry_Proto_Common_V1_KeyValueList() - } - set {value = .kvlistValue(newValue)} - } - - public var bytesValue: Data { - get { - if case .bytesValue(let v)? = value {return v} - return Data() - } - set {value = .bytesValue(newValue)} - } - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// 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 "empty". - public enum OneOf_Value: Equatable, @unchecked Sendable { - case stringValue(String) - case boolValue(Bool) - case intValue(Int64) - case doubleValue(Double) - case arrayValue(Opentelemetry_Proto_Common_V1_ArrayValue) - case kvlistValue(Opentelemetry_Proto_Common_V1_KeyValueList) - case bytesValue(Data) - - } - - public init() {} -} - -/// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message -/// since oneof in AnyValue does not allow repeated fields. -public struct Opentelemetry_Proto_Common_V1_ArrayValue: Sendable { - // 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. - - /// Array of values. The array may be empty (contain 0 elements). - public var values: [Opentelemetry_Proto_Common_V1_AnyValue] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// KeyValueList is a list of KeyValue messages. We need KeyValueList as a message -/// since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need -/// a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to -/// avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches -/// are semantically equivalent. -public struct Opentelemetry_Proto_Common_V1_KeyValueList: Sendable { - // 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. - - /// A collection of key/value pairs of key-value pairs. The list may be empty (may - /// contain 0 elements). - /// The keys MUST be unique (it is not allowed to have more than one - /// value with the same key). - public var values: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// KeyValue is a key-value pair that is used to store Span attributes, Link -/// attributes, etc. -public struct Opentelemetry_Proto_Common_V1_KeyValue: Sendable { - // 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 key: String = String() - - public var value: Opentelemetry_Proto_Common_V1_AnyValue { - get {return _value ?? Opentelemetry_Proto_Common_V1_AnyValue()} - set {_value = newValue} - } - /// Returns true if `value` has been explicitly set. - 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() {self._value = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _value: Opentelemetry_Proto_Common_V1_AnyValue? = nil -} - -/// InstrumentationScope is a message representing the instrumentation scope information -/// such as the fully qualified name and version. -public struct Opentelemetry_Proto_Common_V1_InstrumentationScope: Sendable { - // 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. - - /// An empty instrumentation scope name means the name is unknown. - public var name: String = String() - - public var version: String = String() - - /// Additional attributes that describe the scope. [Optional]. - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - public var droppedAttributesCount: UInt32 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.common.v1" - -extension Opentelemetry_Proto_Common_V1_AnyValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".AnyValue" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "string_value"), - 2: .standard(proto: "bool_value"), - 3: .standard(proto: "int_value"), - 4: .standard(proto: "double_value"), - 5: .standard(proto: "array_value"), - 6: .standard(proto: "kvlist_value"), - 7: .standard(proto: "bytes_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 { - var v: String? - try decoder.decodeSingularStringField(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .stringValue(v) - } - }() - case 2: try { - var v: Bool? - try decoder.decodeSingularBoolField(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .boolValue(v) - } - }() - case 3: try { - var v: Int64? - try decoder.decodeSingularInt64Field(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .intValue(v) - } - }() - case 4: try { - var v: Double? - try decoder.decodeSingularDoubleField(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .doubleValue(v) - } - }() - case 5: try { - var v: Opentelemetry_Proto_Common_V1_ArrayValue? - var hadOneofValue = false - if let current = self.value { - hadOneofValue = true - if case .arrayValue(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.value = .arrayValue(v) - } - }() - case 6: try { - var v: Opentelemetry_Proto_Common_V1_KeyValueList? - var hadOneofValue = false - if let current = self.value { - hadOneofValue = true - if case .kvlistValue(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.value = .kvlistValue(v) - } - }() - case 7: try { - var v: Data? - try decoder.decodeSingularBytesField(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .bytesValue(v) - } - }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - 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 .bytesValue?: try { - guard case .bytesValue(let v)? = self.value else { preconditionFailure() } - try visitor.visitSingularBytesField(value: v, fieldNumber: 7) - }() - 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.value != rhs.value {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Common_V1_ArrayValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ArrayValue" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "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.values) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.values.isEmpty { - try visitor.visitRepeatedMessageField(value: self.values, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Common_V1_ArrayValue, rhs: Opentelemetry_Proto_Common_V1_ArrayValue) -> Bool { - if lhs.values != rhs.values {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Common_V1_KeyValueList: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".KeyValueList" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "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.values) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.values.isEmpty { - try visitor.visitRepeatedMessageField(value: self.values, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Common_V1_KeyValueList, rhs: Opentelemetry_Proto_Common_V1_KeyValueList) -> Bool { - if lhs.values != rhs.values {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Common_V1_KeyValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".KeyValue" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "key"), - 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.decodeSingularStringField(value: &self.key) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._value) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.key.isEmpty { - try visitor.visitSingularStringField(value: self.key, fieldNumber: 1) - } - try { 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.key != rhs.key {return false} - if lhs._value != rhs._value {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Common_V1_InstrumentationScope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".InstrumentationScope" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "name"), - 2: .same(proto: "version"), - 3: .same(proto: "attributes"), - 4: .standard(proto: "dropped_attributes_count"), - ] - - 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.decodeSingularStringField(value: &self.name) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.version) }() - case 3: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() - case 4: try { try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.name.isEmpty { - try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) - } - if !self.version.isEmpty { - try visitor.visitSingularStringField(value: self.version, fieldNumber: 2) - } - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 3) - } - if self.droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: self.droppedAttributesCount, fieldNumber: 4) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Common_V1_InstrumentationScope, rhs: Opentelemetry_Proto_Common_V1_InstrumentationScope) -> Bool { - if lhs.name != rhs.name {return false} - if lhs.version != rhs.version {return false} - if lhs.attributes != rhs.attributes {return false} - if lhs.droppedAttributesCount != rhs.droppedAttributesCount {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/logs.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/logs.pb.swift deleted file mode 100644 index c34dffe3..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/logs.pb.swift +++ /dev/null @@ -1,684 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/logs/v1/logs.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// 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 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 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 {} - typealias Version = _2 -} - -/// Possible values for LogRecord.SeverityNumber. -public enum Opentelemetry_Proto_Logs_V1_SeverityNumber: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// UNSPECIFIED is the default SeverityNumber, it MUST NOT be used. - case unspecified // = 0 - case trace // = 1 - case trace2 // = 2 - case trace3 // = 3 - case trace4 // = 4 - case debug // = 5 - case debug2 // = 6 - case debug3 // = 7 - case debug4 // = 8 - case info // = 9 - case info2 // = 10 - case info3 // = 11 - case info4 // = 12 - case warn // = 13 - case warn2 // = 14 - case warn3 // = 15 - case warn4 // = 16 - case error // = 17 - case error2 // = 18 - case error3 // = 19 - case error4 // = 20 - case fatal // = 21 - case fatal2 // = 22 - case fatal3 // = 23 - case fatal4 // = 24 - case UNRECOGNIZED(Int) - - public init() { - self = .unspecified - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .unspecified - case 1: self = .trace - case 2: self = .trace2 - case 3: self = .trace3 - case 4: self = .trace4 - case 5: self = .debug - case 6: self = .debug2 - case 7: self = .debug3 - case 8: self = .debug4 - case 9: self = .info - case 10: self = .info2 - case 11: self = .info3 - case 12: self = .info4 - case 13: self = .warn - case 14: self = .warn2 - case 15: self = .warn3 - case 16: self = .warn4 - case 17: self = .error - case 18: self = .error2 - case 19: self = .error3 - case 20: self = .error4 - case 21: self = .fatal - case 22: self = .fatal2 - case 23: self = .fatal3 - case 24: self = .fatal4 - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .unspecified: return 0 - case .trace: return 1 - case .trace2: return 2 - case .trace3: return 3 - case .trace4: return 4 - case .debug: return 5 - case .debug2: return 6 - case .debug3: return 7 - case .debug4: return 8 - case .info: return 9 - case .info2: return 10 - case .info3: return 11 - case .info4: return 12 - case .warn: return 13 - case .warn2: return 14 - case .warn3: return 15 - case .warn4: return 16 - case .error: return 17 - case .error2: return 18 - case .error3: return 19 - case .error4: return 20 - case .fatal: return 21 - case .fatal2: return 22 - case .fatal3: return 23 - case .fatal4: return 24 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Logs_V1_SeverityNumber] = [ - .unspecified, - .trace, - .trace2, - .trace3, - .trace4, - .debug, - .debug2, - .debug3, - .debug4, - .info, - .info2, - .info3, - .info4, - .warn, - .warn2, - .warn3, - .warn4, - .error, - .error2, - .error3, - .error4, - .fatal, - .fatal2, - .fatal3, - .fatal4, - ] - -} - -/// LogRecordFlags represents constants used to interpret the -/// LogRecord.flags field, which is protobuf 'fixed32' type and is to -/// be used as bit-fields. Each non-zero value defined in this enum is -/// a bit-mask. To extract the bit-field, for example, use an -/// expression like: -/// -/// (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK) -public enum Opentelemetry_Proto_Logs_V1_LogRecordFlags: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// The zero value for the enum. Should not be used for comparisons. - /// Instead use bitwise "and" with the appropriate mask as shown above. - case doNotUse // = 0 - - /// Bits 0-7 are used for trace flags. - case traceFlagsMask // = 255 - case UNRECOGNIZED(Int) - - public init() { - self = .doNotUse - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .doNotUse - case 255: self = .traceFlagsMask - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .doNotUse: return 0 - case .traceFlagsMask: return 255 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Logs_V1_LogRecordFlags] = [ - .doNotUse, - .traceFlagsMask, - ] - -} - -/// LogsData represents the logs data that can be stored in a persistent storage, -/// OR can be embedded by other protocols that transfer OTLP logs data but do not -/// implement the OTLP protocol. -/// -/// The main difference between this message and collector protocol is that -/// in this message there will not be any "control" or "metadata" specific to -/// OTLP protocol. -/// -/// When new fields are added into this message, the OTLP request MUST be updated -/// as well. -public struct Opentelemetry_Proto_Logs_V1_LogsData: Sendable { - // 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. - - /// An array of ResourceLogs. - /// For data coming from a single resource this array will typically contain - /// one element. Intermediary nodes that receive data from multiple origins - /// typically batch the data before forwarding further and in that case this - /// array will contain multiple elements. - public var resourceLogs: [Opentelemetry_Proto_Logs_V1_ResourceLogs] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// A collection of ScopeLogs from a Resource. -public struct Opentelemetry_Proto_Logs_V1_ResourceLogs: Sendable { - // 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 resource for the logs in this message. - /// If this field is not set then resource info is unknown. - public var resource: Opentelemetry_Proto_Resource_V1_Resource { - get {return _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_resource = newValue} - } - /// Returns true if `resource` has been explicitly set. - 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() {self._resource = nil} - - /// A list of ScopeLogs that originate from a resource. - public var scopeLogs: [Opentelemetry_Proto_Logs_V1_ScopeLogs] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the resource data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to the data in the "resource" field. It does not apply - /// to the data in the "scope_logs" field which have their own schema_url field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil -} - -/// A collection of Logs produced by a Scope. -public struct Opentelemetry_Proto_Logs_V1_ScopeLogs: Sendable { - // 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 instrumentation scope information for the logs in this message. - /// Semantically when InstrumentationScope isn't set, it is equivalent with - /// an empty instrumentation scope name (unknown). - public var scope: Opentelemetry_Proto_Common_V1_InstrumentationScope { - get {return _scope ?? Opentelemetry_Proto_Common_V1_InstrumentationScope()} - set {_scope = newValue} - } - /// Returns true if `scope` has been explicitly set. - public var hasScope: Bool {return self._scope != nil} - /// Clears the value of `scope`. Subsequent reads from it will return its default value. - public mutating func clearScope() {self._scope = nil} - - /// A list of log records. - public var logRecords: [Opentelemetry_Proto_Logs_V1_LogRecord] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the log data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to all logs in the "logs" field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _scope: Opentelemetry_Proto_Common_V1_InstrumentationScope? = nil -} - -/// A log record according to OpenTelemetry Log Data Model: -/// https://github.com/open-telemetry/oteps/blob/main/text/logs/0097-log-data-model.md -public struct Opentelemetry_Proto_Logs_V1_LogRecord: @unchecked Sendable { - // 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. - - /// 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 = 0 - - /// Time when the event was observed by the collection system. - /// For events that originate in OpenTelemetry (e.g. using OpenTelemetry Logging SDK) - /// this timestamp is typically set at the generation time and is equal to Timestamp. - /// For events originating externally and collected by OpenTelemetry (e.g. using - /// Collector) this is the time when OpenTelemetry's code observed the event measured - /// by the clock of the OpenTelemetry code. This field MUST be set once the event is - /// observed by OpenTelemetry. - /// - /// For converting OpenTelemetry log data to formats that support only one timestamp or - /// when receiving OpenTelemetry log data by recipients that support only one timestamp - /// internally the following logic is recommended: - /// - Use time_unix_nano if it is present, otherwise use observed_time_unix_nano. - /// - /// 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 observedTimeUnixNano: UInt64 = 0 - - /// Numerical value of the severity, normalized to values described in Log Data Model. - /// [Optional]. - 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 = 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 _body ?? Opentelemetry_Proto_Common_V1_AnyValue()} - set {_body = newValue} - } - /// Returns true if `body` has been explicitly set. - 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() {self._body = nil} - - /// Additional attributes that describe the specific event occurrence. [Optional]. - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - 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 & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK). [Optional]. - 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 OR - /// of length other than 16 bytes is considered invalid (empty string in OTLP/JSON - /// is zero-length and thus is also invalid). - /// - /// This field is optional. - /// - /// The receivers SHOULD assume that the log record is not associated with a - /// trace if any of the following is true: - /// - the field is not present, - /// - the field contains an invalid value. - 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 OR of length - /// other than 8 bytes is considered invalid (empty string in OTLP/JSON - /// is zero-length and thus is also invalid). - /// - /// This field is optional. If the sender specifies a valid span_id then it SHOULD also - /// specify a valid trace_id. - /// - /// The receivers SHOULD assume that the log record is not associated with a - /// span if any of the following is true: - /// - the field is not present, - /// - the field contains an invalid value. - public var spanID: Data = Data() - - /// A unique identifier of event category/type. - /// All events with the same event_name are expected to conform to the same - /// schema for both their attributes and their body. - /// - /// Recommended to be fully qualified and short (no longer than 256 characters). - /// - /// Presence of event_name on the log record identifies this record - /// as an event. - /// - /// [Optional]. - /// - /// Status: [Development] - public var eventName: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _body: Opentelemetry_Proto_Common_V1_AnyValue? = nil -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.logs.v1" - -extension Opentelemetry_Proto_Logs_V1_SeverityNumber: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "SEVERITY_NUMBER_UNSPECIFIED"), - 1: .same(proto: "SEVERITY_NUMBER_TRACE"), - 2: .same(proto: "SEVERITY_NUMBER_TRACE2"), - 3: .same(proto: "SEVERITY_NUMBER_TRACE3"), - 4: .same(proto: "SEVERITY_NUMBER_TRACE4"), - 5: .same(proto: "SEVERITY_NUMBER_DEBUG"), - 6: .same(proto: "SEVERITY_NUMBER_DEBUG2"), - 7: .same(proto: "SEVERITY_NUMBER_DEBUG3"), - 8: .same(proto: "SEVERITY_NUMBER_DEBUG4"), - 9: .same(proto: "SEVERITY_NUMBER_INFO"), - 10: .same(proto: "SEVERITY_NUMBER_INFO2"), - 11: .same(proto: "SEVERITY_NUMBER_INFO3"), - 12: .same(proto: "SEVERITY_NUMBER_INFO4"), - 13: .same(proto: "SEVERITY_NUMBER_WARN"), - 14: .same(proto: "SEVERITY_NUMBER_WARN2"), - 15: .same(proto: "SEVERITY_NUMBER_WARN3"), - 16: .same(proto: "SEVERITY_NUMBER_WARN4"), - 17: .same(proto: "SEVERITY_NUMBER_ERROR"), - 18: .same(proto: "SEVERITY_NUMBER_ERROR2"), - 19: .same(proto: "SEVERITY_NUMBER_ERROR3"), - 20: .same(proto: "SEVERITY_NUMBER_ERROR4"), - 21: .same(proto: "SEVERITY_NUMBER_FATAL"), - 22: .same(proto: "SEVERITY_NUMBER_FATAL2"), - 23: .same(proto: "SEVERITY_NUMBER_FATAL3"), - 24: .same(proto: "SEVERITY_NUMBER_FATAL4"), - ] -} - -extension Opentelemetry_Proto_Logs_V1_LogRecordFlags: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "LOG_RECORD_FLAGS_DO_NOT_USE"), - 255: .same(proto: "LOG_RECORD_FLAGS_TRACE_FLAGS_MASK"), - ] -} - -extension Opentelemetry_Proto_Logs_V1_LogsData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".LogsData" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_logs"), - ] - - 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.resourceLogs) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceLogs.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceLogs, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Logs_V1_LogsData, rhs: Opentelemetry_Proto_Logs_V1_LogsData) -> Bool { - if lhs.resourceLogs != rhs.resourceLogs {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Logs_V1_ResourceLogs: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ResourceLogs" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "resource"), - 2: .standard(proto: "scope_logs"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._resource) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.scopeLogs) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.scopeLogs.isEmpty { - try visitor.visitRepeatedMessageField(value: self.scopeLogs, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Logs_V1_ResourceLogs, rhs: Opentelemetry_Proto_Logs_V1_ResourceLogs) -> Bool { - if lhs._resource != rhs._resource {return false} - if lhs.scopeLogs != rhs.scopeLogs {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Logs_V1_ScopeLogs: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ScopeLogs" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "scope"), - 2: .standard(proto: "log_records"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._scope) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.logRecords) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._scope { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.logRecords.isEmpty { - try visitor.visitRepeatedMessageField(value: self.logRecords, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Logs_V1_ScopeLogs, rhs: Opentelemetry_Proto_Logs_V1_ScopeLogs) -> Bool { - if lhs._scope != rhs._scope {return false} - if lhs.logRecords != rhs.logRecords {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Logs_V1_LogRecord: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".LogRecord" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "time_unix_nano"), - 11: .standard(proto: "observed_time_unix_nano"), - 2: .standard(proto: "severity_number"), - 3: .standard(proto: "severity_text"), - 5: .same(proto: "body"), - 6: .same(proto: "attributes"), - 7: .standard(proto: "dropped_attributes_count"), - 8: .same(proto: "flags"), - 9: .standard(proto: "trace_id"), - 10: .standard(proto: "span_id"), - 12: .standard(proto: "event_name"), - ] - - 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.decodeSingularFixed64Field(value: &self.timeUnixNano) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self.severityNumber) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.severityText) }() - 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) }() - case 11: try { try decoder.decodeSingularFixed64Field(value: &self.observedTimeUnixNano) }() - case 12: try { try decoder.decodeSingularStringField(value: &self.eventName) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - 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) - } - try { 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) - } - if self.observedTimeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: self.observedTimeUnixNano, fieldNumber: 11) - } - if !self.eventName.isEmpty { - try visitor.visitSingularStringField(value: self.eventName, fieldNumber: 12) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Logs_V1_LogRecord, rhs: Opentelemetry_Proto_Logs_V1_LogRecord) -> Bool { - if lhs.timeUnixNano != rhs.timeUnixNano {return false} - if lhs.observedTimeUnixNano != rhs.observedTimeUnixNano {return false} - if lhs.severityNumber != rhs.severityNumber {return false} - if lhs.severityText != rhs.severityText {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.eventName != rhs.eventName {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/logs_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/logs_service.pb.swift deleted file mode 100644 index af8e7717..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/logs_service.pb.swift +++ /dev/null @@ -1,223 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/collector/logs/v1/logs_service.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// 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 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 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 {} - typealias Version = _2 -} - -public struct Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest: Sendable { - // 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. - - /// An array of ResourceLogs. - /// For data coming from a single resource this array will typically contain one - /// element. Intermediary nodes (such as OpenTelemetry Collector) that receive - /// data from multiple origins typically batch the data before forwarding further and - /// in that case this array will contain multiple elements. - public var resourceLogs: [Opentelemetry_Proto_Logs_V1_ResourceLogs] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -public struct Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse: Sendable { - // 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 details of a partially successful export request. - /// - /// If the request is only partially accepted - /// (i.e. when the server accepts only parts of the data and rejects the rest) - /// the server MUST initialize the `partial_success` field and MUST - /// set the `rejected_` with the number of items it rejected. - /// - /// Servers MAY also make use of the `partial_success` field to convey - /// warnings/suggestions to senders even when the request was fully accepted. - /// In such cases, the `rejected_` MUST have a value of `0` and - /// the `error_message` MUST be non-empty. - /// - /// A `partial_success` message with an empty value (rejected_ = 0 and - /// `error_message` = "") is equivalent to it not being set/present. Senders - /// SHOULD interpret it the same way as in the full success case. - public var partialSuccess: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess { - get {return _partialSuccess ?? Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess()} - set {_partialSuccess = newValue} - } - /// Returns true if `partialSuccess` has been explicitly set. - public var hasPartialSuccess: Bool {return self._partialSuccess != nil} - /// Clears the value of `partialSuccess`. Subsequent reads from it will return its default value. - public mutating func clearPartialSuccess() {self._partialSuccess = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _partialSuccess: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess? = nil -} - -public struct Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess: Sendable { - // 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 number of rejected log records. - /// - /// A `rejected_` field holding a `0` value indicates that the - /// request was fully accepted. - public var rejectedLogRecords: Int64 = 0 - - /// A developer-facing human-readable message in English. It should be used - /// either to explain why the server rejected parts of the data during a partial - /// success or to convey warnings/suggestions during a full success. The message - /// should offer guidance on how users can address such issues. - /// - /// error_message is an optional field. An error_message with an empty value - /// is equivalent to it not being set. - public var errorMessage: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.collector.logs.v1" - -extension Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportLogsServiceRequest" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_logs"), - ] - - 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.resourceLogs) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceLogs.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceLogs, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, rhs: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest) -> Bool { - if lhs.resourceLogs != rhs.resourceLogs {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportLogsServiceResponse" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "partial_success"), - ] - - 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.decodeSingularMessageField(value: &self._partialSuccess) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._partialSuccess { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse, rhs: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse) -> Bool { - if lhs._partialSuccess != rhs._partialSuccess {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportLogsPartialSuccess" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "rejected_log_records"), - 2: .standard(proto: "error_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 { try decoder.decodeSingularInt64Field(value: &self.rejectedLogRecords) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.rejectedLogRecords != 0 { - try visitor.visitSingularInt64Field(value: self.rejectedLogRecords, fieldNumber: 1) - } - if !self.errorMessage.isEmpty { - try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess, rhs: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsPartialSuccess) -> Bool { - if lhs.rejectedLogRecords != rhs.rejectedLogRecords {return false} - if lhs.errorMessage != rhs.errorMessage {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/metrics.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/metrics.pb.swift deleted file mode 100644 index e847bc99..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/metrics.pb.swift +++ /dev/null @@ -1,2069 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/metrics/v1/metrics.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2019, 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 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 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 {} - typealias Version = _2 -} - -/// AggregationTemporality defines how a metric aggregator reports aggregated -/// values. It describes how those values relate to the time interval over -/// which they are aggregated. -public enum Opentelemetry_Proto_Metrics_V1_AggregationTemporality: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// UNSPECIFIED is the default AggregationTemporality, it MUST not be used. - case unspecified // = 0 - - /// DELTA is an AggregationTemporality for a metric aggregator which reports - /// changes since last report time. Successive metrics contain aggregation of - /// values from continuous and non-overlapping intervals. - /// - /// The values for a DELTA metric are based only on the time interval - /// associated with one measurement cycle. There is no dependency on - /// previous measurements like is the case for CUMULATIVE metrics. - /// - /// For example, consider a system measuring the number of requests that - /// it receives and reports the sum of these requests every second as a - /// DELTA metric: - /// - /// 1. The system starts receiving at time=t_0. - /// 2. A request is received, the system measures 1 request. - /// 3. A request is received, the system measures 1 request. - /// 4. A request is received, the system measures 1 request. - /// 5. The 1 second collection cycle ends. A metric is exported for the - /// number of requests received over the interval of time t_0 to - /// t_0+1 with a value of 3. - /// 6. A request is received, the system measures 1 request. - /// 7. A request is received, the system measures 1 request. - /// 8. The 1 second collection cycle ends. A metric is exported for the - /// number of requests received over the interval of time t_0+1 to - /// t_0+2 with a value of 2. - case delta // = 1 - - /// 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 - /// in some form. If this state is lost or invalidated, the CUMULATIVE metric - /// values MUST be reset and a new fixed start time following the last - /// reported measurement time sent MUST be used. - /// - /// For example, consider a system measuring the number of requests that - /// it receives and reports the sum of these requests every second as a - /// CUMULATIVE metric: - /// - /// 1. The system starts receiving at time=t_0. - /// 2. A request is received, the system measures 1 request. - /// 3. A request is received, the system measures 1 request. - /// 4. A request is received, the system measures 1 request. - /// 5. The 1 second collection cycle ends. A metric is exported for the - /// number of requests received over the interval of time t_0 to - /// t_0+1 with a value of 3. - /// 6. A request is received, the system measures 1 request. - /// 7. A request is received, the system measures 1 request. - /// 8. The 1 second collection cycle ends. A metric is exported for the - /// number of requests received over the interval of time t_0 to - /// t_0+2 with a value of 5. - /// 9. The system experiences a fault and loses state. - /// 10. The system recovers and resumes receiving at time=t_1. - /// 11. A request is received, the system measures 1 request. - /// 12. The 1 second collection cycle ends. A metric is exported for the - /// number of requests received over the interval of time t_1 to - /// t_0+1 with a value of 1. - /// - /// Note: Even though, when reporting changes since last report time, using - /// CUMULATIVE is valid, it is not recommended. This may cause problems for - /// systems that do not use start_time to determine when the aggregation - /// value was reset (e.g. Prometheus). - case cumulative // = 2 - case UNRECOGNIZED(Int) - - public init() { - self = .unspecified - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .unspecified - case 1: self = .delta - case 2: self = .cumulative - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .unspecified: return 0 - case .delta: return 1 - case .cumulative: return 2 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Metrics_V1_AggregationTemporality] = [ - .unspecified, - .delta, - .cumulative, - ] - -} - -/// DataPointFlags is defined as a protobuf 'uint32' type and is to be used as a -/// bit-field representing 32 distinct boolean flags. Each flag defined in this -/// enum is a bit-mask. To test the presence of a single flag in the flags of -/// a data point, for example, use an expression like: -/// -/// (point.flags & DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK) == DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK -public enum Opentelemetry_Proto_Metrics_V1_DataPointFlags: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// The zero value for the enum. Should not be used for comparisons. - /// Instead use bitwise "and" with the appropriate mask as shown above. - case doNotUse // = 0 - - /// This DataPoint is valid but has no recorded value. This value - /// SHOULD be used to reflect explicitly missing data in a series, as - /// for an equivalent to the Prometheus "staleness marker". - case noRecordedValueMask // = 1 - case UNRECOGNIZED(Int) - - public init() { - self = .doNotUse - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .doNotUse - case 1: self = .noRecordedValueMask - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .doNotUse: return 0 - case .noRecordedValueMask: return 1 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Metrics_V1_DataPointFlags] = [ - .doNotUse, - .noRecordedValueMask, - ] - -} - -/// MetricsData represents the metrics data that can be stored in a persistent -/// storage, OR can be embedded by other protocols that transfer OTLP metrics -/// data but do not implement the OTLP protocol. -/// -/// MetricsData -/// └─── ResourceMetrics -/// ├── Resource -/// ├── SchemaURL -/// └── ScopeMetrics -/// ├── Scope -/// ├── SchemaURL -/// └── Metric -/// ├── Name -/// ├── Description -/// ├── Unit -/// └── data -/// ├── Gauge -/// ├── Sum -/// ├── Histogram -/// ├── ExponentialHistogram -/// └── Summary -/// -/// The main difference between this message and collector protocol is that -/// in this message there will not be any "control" or "metadata" specific to -/// OTLP protocol. -/// -/// When new fields are added into this message, the OTLP request MUST be updated -/// as well. -public struct Opentelemetry_Proto_Metrics_V1_MetricsData: Sendable { - // 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. - - /// An array of ResourceMetrics. - /// For data coming from a single resource this array will typically contain - /// one element. Intermediary nodes that receive data from multiple origins - /// typically batch the data before forwarding further and in that case this - /// array will contain multiple elements. - public var resourceMetrics: [Opentelemetry_Proto_Metrics_V1_ResourceMetrics] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// A collection of ScopeMetrics from a Resource. -public struct Opentelemetry_Proto_Metrics_V1_ResourceMetrics: Sendable { - // 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 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 _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_resource = newValue} - } - /// Returns true if `resource` has been explicitly set. - 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() {self._resource = nil} - - /// A list of metrics that originate from a resource. - public var scopeMetrics: [Opentelemetry_Proto_Metrics_V1_ScopeMetrics] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the resource data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to the data in the "resource" field. It does not apply - /// to the data in the "scope_metrics" field which have their own schema_url field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil -} - -/// A collection of Metrics produced by an Scope. -public struct Opentelemetry_Proto_Metrics_V1_ScopeMetrics: Sendable { - // 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 instrumentation scope information for the metrics in this message. - /// Semantically when InstrumentationScope isn't set, it is equivalent with - /// an empty instrumentation scope name (unknown). - public var scope: Opentelemetry_Proto_Common_V1_InstrumentationScope { - get {return _scope ?? Opentelemetry_Proto_Common_V1_InstrumentationScope()} - set {_scope = newValue} - } - /// Returns true if `scope` has been explicitly set. - public var hasScope: Bool {return self._scope != nil} - /// Clears the value of `scope`. Subsequent reads from it will return its default value. - public mutating func clearScope() {self._scope = nil} - - /// A list of metrics that originate from an instrumentation library. - public var metrics: [Opentelemetry_Proto_Metrics_V1_Metric] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the metric data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to all metrics in the "metrics" field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _scope: Opentelemetry_Proto_Common_V1_InstrumentationScope? = nil -} - -/// Defines a Metric which has one or more timeseries. The following is a -/// brief summary of the Metric data model. For more details, see: -/// -/// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md -/// -/// The data model and relation between entities is shown in the -/// diagram below. Here, "DataPoint" is the term used to refer to any -/// one of the specific data point value types, and "points" is the term used -/// to refer to any one of the lists of points contained in the Metric. -/// -/// - Metric is composed of a metadata and data. -/// - Metadata part contains a name, description, unit. -/// - Data is one of the possible types (Sum, Gauge, Histogram, Summary). -/// - DataPoint contains timestamps, attributes, and one of the possible value type -/// fields. -/// -/// Metric -/// +------------+ -/// |name | -/// |description | -/// |unit | +------------------------------------+ -/// |data |---> |Gauge, Sum, Histogram, Summary, ... | -/// +------------+ +------------------------------------+ -/// -/// Data [One of Gauge, Sum, Histogram, Summary, ...] -/// +-----------+ -/// |... | // Metadata about the Data. -/// |points |--+ -/// +-----------+ | -/// | +---------------------------+ -/// | |DataPoint 1 | -/// v |+------+------+ +------+ | -/// +-----+ ||label |label |...|label | | -/// | 1 |-->||value1|value2|...|valueN| | -/// +-----+ |+------+------+ +------+ | -/// | . | |+-----+ | -/// | . | ||value| | -/// | . | |+-----+ | -/// | . | +---------------------------+ -/// | . | . -/// | . | . -/// | . | . -/// | . | +---------------------------+ -/// | . | |DataPoint M | -/// +-----+ |+------+------+ +------+ | -/// | M |-->||label |label |...|label | | -/// +-----+ ||value1|value2|...|valueN| | -/// |+------+------+ +------+ | -/// |+-----+ | -/// ||value| | -/// |+-----+ | -/// +---------------------------+ -/// -/// Each distinct type of DataPoint represents the output of a specific -/// aggregation function, the result of applying the DataPoint's -/// associated function of to one or more measurements. -/// -/// All DataPoint types have three common fields: -/// - Attributes includes key-value pairs associated with the data point -/// - TimeUnixNano is required, set to the end time of the aggregation -/// - StartTimeUnixNano is optional, but strongly encouraged for DataPoints -/// having an AggregationTemporality field, as discussed below. -/// -/// Both TimeUnixNano and StartTimeUnixNano values are expressed as -/// UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. -/// -/// # TimeUnixNano -/// -/// This field is required, having consistent interpretation across -/// DataPoint types. TimeUnixNano is the moment corresponding to when -/// the data point's aggregate value was captured. -/// -/// Data points with the 0 value for TimeUnixNano SHOULD be rejected -/// by consumers. -/// -/// # StartTimeUnixNano -/// -/// StartTimeUnixNano in general allows detecting when a sequence of -/// observations is unbroken. This field indicates to consumers the -/// start time for points with cumulative and delta -/// AggregationTemporality, and it should be included whenever possible -/// to support correct rate calculation. Although it may be omitted -/// when the start time is truly unknown, setting StartTimeUnixNano is -/// strongly encouraged. -public struct Opentelemetry_Proto_Metrics_V1_Metric: Sendable { - // 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. - - /// name of the metric. - public var name: String = String() - - /// description of the metric, which can be used in documentation. - 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 = 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 - /// the time interval over which they are reported. - public var data: Opentelemetry_Proto_Metrics_V1_Metric.OneOf_Data? = nil - - public var gauge: Opentelemetry_Proto_Metrics_V1_Gauge { - get { - if case .gauge(let v)? = data {return v} - return Opentelemetry_Proto_Metrics_V1_Gauge() - } - set {data = .gauge(newValue)} - } - - public var sum: Opentelemetry_Proto_Metrics_V1_Sum { - get { - if case .sum(let v)? = data {return v} - return Opentelemetry_Proto_Metrics_V1_Sum() - } - set {data = .sum(newValue)} - } - - public var histogram: Opentelemetry_Proto_Metrics_V1_Histogram { - get { - if case .histogram(let v)? = data {return v} - return Opentelemetry_Proto_Metrics_V1_Histogram() - } - set {data = .histogram(newValue)} - } - - public var exponentialHistogram: Opentelemetry_Proto_Metrics_V1_ExponentialHistogram { - get { - if case .exponentialHistogram(let v)? = data {return v} - return Opentelemetry_Proto_Metrics_V1_ExponentialHistogram() - } - set {data = .exponentialHistogram(newValue)} - } - - public var summary: Opentelemetry_Proto_Metrics_V1_Summary { - get { - if case .summary(let v)? = data {return v} - return Opentelemetry_Proto_Metrics_V1_Summary() - } - set {data = .summary(newValue)} - } - - /// Additional metadata attributes that describe the metric. [Optional]. - /// Attributes are non-identifying. - /// Consumers SHOULD NOT need to be aware of these attributes. - /// These attributes MAY be used to encode information allowing - /// for lossless roundtrip translation to / from another data model. - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var metadata: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// 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 - /// the time interval over which they are reported. - public enum OneOf_Data: Equatable, Sendable { - case gauge(Opentelemetry_Proto_Metrics_V1_Gauge) - case sum(Opentelemetry_Proto_Metrics_V1_Sum) - case histogram(Opentelemetry_Proto_Metrics_V1_Histogram) - case exponentialHistogram(Opentelemetry_Proto_Metrics_V1_ExponentialHistogram) - case summary(Opentelemetry_Proto_Metrics_V1_Summary) - - } - - public init() {} -} - -/// Gauge represents the type of a scalar metric that always exports the -/// "current value" for every data point. It should be used for an "unknown" -/// aggregation. -/// -/// A Gauge does not support different aggregation temporalities. Given the -/// aggregation is unknown, points cannot be combined using the same -/// aggregation, regardless of aggregation temporalities. Therefore, -/// AggregationTemporality is not included. Consequently, this also means -/// "StartTimeUnixNano" is ignored for all data points. -public struct Opentelemetry_Proto_Metrics_V1_Gauge: Sendable { - // 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_NumberDataPoint] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// Sum represents the type of a scalar metric that is calculated as a sum of all -/// reported measurements over a time interval. -public struct Opentelemetry_Proto_Metrics_V1_Sum: Sendable { - // 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_NumberDataPoint] = [] - - /// aggregation_temporality describes if the aggregator reports delta changes - /// since last report time, or cumulative changes since a fixed start time. - public var aggregationTemporality: Opentelemetry_Proto_Metrics_V1_AggregationTemporality = .unspecified - - /// If "true" means that the sum is monotonic. - public var isMonotonic: Bool = false - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// Histogram represents the type of a metric that is calculated by aggregating -/// as a Histogram of all reported measurements over a time interval. -public struct Opentelemetry_Proto_Metrics_V1_Histogram: Sendable { - // 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_HistogramDataPoint] = [] - - /// aggregation_temporality describes if the aggregator reports delta changes - /// since last report time, or cumulative changes since a fixed start time. - public var aggregationTemporality: Opentelemetry_Proto_Metrics_V1_AggregationTemporality = .unspecified - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// ExponentialHistogram represents the type of a metric that is calculated by aggregating -/// as a ExponentialHistogram of all reported double measurements over a time interval. -public struct Opentelemetry_Proto_Metrics_V1_ExponentialHistogram: Sendable { - // 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_ExponentialHistogramDataPoint] = [] - - /// aggregation_temporality describes if the aggregator reports delta changes - /// since last report time, or cumulative changes since a fixed start time. - public var aggregationTemporality: Opentelemetry_Proto_Metrics_V1_AggregationTemporality = .unspecified - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// Summary 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. -/// Summary metrics do not have an aggregation temporality field. This is -/// because the count and sum fields of a SummaryDataPoint are assumed to be -/// cumulative values. -public struct Opentelemetry_Proto_Metrics_V1_Summary: Sendable { - // 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_SummaryDataPoint] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// NumberDataPoint is a single data point in a timeseries that describes the -/// time-varying scalar value of a metric. -public struct Opentelemetry_Proto_Metrics_V1_NumberDataPoint: Sendable { - // 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 key/value pairs that uniquely identify the timeseries from - /// where this point belongs. The list may be empty (may contain 0 elements). - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// StartTimeUnixNano is optional but strongly encouraged, see the - /// the detailed comments above Metric. - /// - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - /// 1970. - public var startTimeUnixNano: UInt64 = 0 - - /// TimeUnixNano is required, see the detailed comments above Metric. - /// - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - /// 1970. - public var timeUnixNano: UInt64 = 0 - - /// The value itself. A point is considered invalid when one of the recognized - /// value fields is not present inside this oneof. - public var value: Opentelemetry_Proto_Metrics_V1_NumberDataPoint.OneOf_Value? = nil - - public var asDouble: Double { - get { - if case .asDouble(let v)? = value {return v} - return 0 - } - set {value = .asDouble(newValue)} - } - - public var asInt: Int64 { - get { - if case .asInt(let v)? = value {return v} - return 0 - } - set {value = .asInt(newValue)} - } - - /// (Optional) List of exemplars collected from - /// measurements that were used to form the data point - public var exemplars: [Opentelemetry_Proto_Metrics_V1_Exemplar] = [] - - /// Flags that apply to this specific data point. See DataPointFlags - /// for the available flags and their meaning. - public var flags: UInt32 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// The value itself. A point is considered invalid when one of the recognized - /// value fields is not present inside this oneof. - public enum OneOf_Value: Equatable, Sendable { - case asDouble(Double) - case asInt(Int64) - - } - - public init() {} -} - -/// HistogramDataPoint is a single data point in a timeseries that describes the -/// time-varying values of a Histogram. A Histogram contains summary statistics -/// for a population of values, it may optionally contain the distribution of -/// those values across a set of buckets. -/// -/// If the histogram contains the distribution of values, then both -/// "explicit_bounds" and "bucket counts" fields must be defined. -/// If the histogram does not contain the distribution of values, then both -/// "explicit_bounds" and "bucket_counts" must be omitted and only "count" and -/// "sum" are known. -public struct Opentelemetry_Proto_Metrics_V1_HistogramDataPoint: Sendable { - // 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 key/value pairs that uniquely identify the timeseries from - /// where this point belongs. The list may be empty (may contain 0 elements). - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// StartTimeUnixNano is optional but strongly encouraged, see the - /// the detailed comments above Metric. - /// - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - /// 1970. - public var startTimeUnixNano: UInt64 = 0 - - /// TimeUnixNano is required, see the detailed comments above Metric. - /// - /// 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. This - /// value must be equal to the sum of the "count" fields in buckets if a - /// histogram is provided. - public var count: UInt64 = 0 - - /// sum of the values in the population. If count is zero then this field - /// must be zero. - /// - /// Note: Sum should only be filled out when measuring non-negative discrete - /// events, and is assumed to be monotonic over the values of these events. - /// Negative events *can* be recorded, but sum should not be filled out when - /// doing so. This is specifically to enforce compatibility w/ OpenMetrics, - /// see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram - public var sum: Double { - get {return _sum ?? 0} - set {_sum = newValue} - } - /// Returns true if `sum` has been explicitly set. - public var hasSum: Bool {return self._sum != nil} - /// Clears the value of `sum`. Subsequent reads from it will return its default value. - public mutating func clearSum() {self._sum = nil} - - /// bucket_counts is an optional field contains the count values of histogram - /// for each bucket. - /// - /// The sum of the bucket_counts must equal the value in the count field. - /// - /// The number of elements in bucket_counts array must be by one greater than - /// the number of elements in explicit_bounds array. - public var bucketCounts: [UInt64] = [] - - /// explicit_bounds specifies buckets with explicitly defined bounds for values. - /// - /// The boundaries for bucket at index i are: - /// - /// (-infinity, explicit_bounds[i]] for i == 0 - /// (explicit_bounds[i-1], explicit_bounds[i]] for 0 < i < size(explicit_bounds) - /// (explicit_bounds[i-1], +infinity) for i == size(explicit_bounds) - /// - /// The values in the explicit_bounds array must be strictly increasing. - /// - /// Histogram buckets are inclusive of their upper boundary, except the last - /// bucket where the boundary is at infinity. This format is intentionally - /// compatible with the OpenMetrics histogram definition. - public var explicitBounds: [Double] = [] - - /// (Optional) List of exemplars collected from - /// measurements that were used to form the data point - public var exemplars: [Opentelemetry_Proto_Metrics_V1_Exemplar] = [] - - /// Flags that apply to this specific data point. See DataPointFlags - /// for the available flags and their meaning. - public var flags: UInt32 = 0 - - /// min is the minimum value over (start_time, end_time]. - public var min: Double { - get {return _min ?? 0} - set {_min = newValue} - } - /// Returns true if `min` has been explicitly set. - public var hasMin: Bool {return self._min != nil} - /// Clears the value of `min`. Subsequent reads from it will return its default value. - public mutating func clearMin() {self._min = nil} - - /// max is the maximum value over (start_time, end_time]. - public var max: Double { - get {return _max ?? 0} - set {_max = newValue} - } - /// Returns true if `max` has been explicitly set. - public var hasMax: Bool {return self._max != nil} - /// Clears the value of `max`. Subsequent reads from it will return its default value. - public mutating func clearMax() {self._max = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _sum: Double? = nil - fileprivate var _min: Double? = nil - fileprivate var _max: Double? = nil -} - -/// ExponentialHistogramDataPoint is a single data point in a timeseries that describes the -/// time-varying values of a ExponentialHistogram of double values. A ExponentialHistogram contains -/// summary statistics for a population of values, it may optionally contain the -/// distribution of those values across a set of buckets. -public struct Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint: Sendable { - // 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 key/value pairs that uniquely identify the timeseries from - /// where this point belongs. The list may be empty (may contain 0 elements). - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// StartTimeUnixNano is optional but strongly encouraged, see the - /// the detailed comments above Metric. - /// - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - /// 1970. - public var startTimeUnixNano: UInt64 = 0 - - /// TimeUnixNano is required, see the detailed comments above Metric. - /// - /// 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. This value must be equal to the sum of the "bucket_counts" - /// values in the positive and negative Buckets plus the "zero_count" field. - public var count: UInt64 = 0 - - /// sum of the values in the population. If count is zero then this field - /// must be zero. - /// - /// Note: Sum should only be filled out when measuring non-negative discrete - /// events, and is assumed to be monotonic over the values of these events. - /// Negative events *can* be recorded, but sum should not be filled out when - /// doing so. This is specifically to enforce compatibility w/ OpenMetrics, - /// see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram - public var sum: Double { - get {return _sum ?? 0} - set {_sum = newValue} - } - /// Returns true if `sum` has been explicitly set. - public var hasSum: Bool {return self._sum != nil} - /// Clears the value of `sum`. Subsequent reads from it will return its default value. - public mutating func clearSum() {self._sum = nil} - - /// scale describes the resolution of the histogram. Boundaries are - /// located at powers of the base, where: - /// - /// base = (2^(2^-scale)) - /// - /// The histogram bucket identified by `index`, a signed integer, - /// contains values that are greater than (base^index) and - /// less than or equal to (base^(index+1)). - /// - /// The positive and negative ranges of the histogram are expressed - /// separately. Negative values are mapped by their absolute value - /// into the negative range using the same scale as the positive range. - /// - /// scale is not restricted by the protocol, as the permissible - /// values depend on the range of the data. - public var scale: Int32 = 0 - - /// zero_count is the count of values that are either exactly zero or - /// within the region considered zero by the instrumentation at the - /// tolerated degree of precision. This bucket stores values that - /// cannot be expressed using the standard exponential formula as - /// well as values that have been rounded to zero. - /// - /// Implementations MAY consider the zero bucket to have probability - /// mass equal to (zero_count / count). - public var zeroCount: UInt64 = 0 - - /// positive carries the positive range of exponential bucket counts. - public var positive: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets { - get {return _positive ?? Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets()} - set {_positive = newValue} - } - /// Returns true if `positive` has been explicitly set. - public var hasPositive: Bool {return self._positive != nil} - /// Clears the value of `positive`. Subsequent reads from it will return its default value. - public mutating func clearPositive() {self._positive = nil} - - /// negative carries the negative range of exponential bucket counts. - public var negative: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets { - get {return _negative ?? Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets()} - set {_negative = newValue} - } - /// Returns true if `negative` has been explicitly set. - public var hasNegative: Bool {return self._negative != nil} - /// Clears the value of `negative`. Subsequent reads from it will return its default value. - public mutating func clearNegative() {self._negative = nil} - - /// Flags that apply to this specific data point. See DataPointFlags - /// for the available flags and their meaning. - public var flags: UInt32 = 0 - - /// (Optional) List of exemplars collected from - /// measurements that were used to form the data point - public var exemplars: [Opentelemetry_Proto_Metrics_V1_Exemplar] = [] - - /// min is the minimum value over (start_time, end_time]. - public var min: Double { - get {return _min ?? 0} - set {_min = newValue} - } - /// Returns true if `min` has been explicitly set. - public var hasMin: Bool {return self._min != nil} - /// Clears the value of `min`. Subsequent reads from it will return its default value. - public mutating func clearMin() {self._min = nil} - - /// max is the maximum value over (start_time, end_time]. - public var max: Double { - get {return _max ?? 0} - set {_max = newValue} - } - /// Returns true if `max` has been explicitly set. - public var hasMax: Bool {return self._max != nil} - /// Clears the value of `max`. Subsequent reads from it will return its default value. - public mutating func clearMax() {self._max = nil} - - /// ZeroThreshold may be optionally set to convey the width of the zero - /// region. Where the zero region is defined as the closed interval - /// [-ZeroThreshold, ZeroThreshold]. - /// When ZeroThreshold is 0, zero count bucket stores values that cannot be - /// expressed using the standard exponential formula as well as values that - /// have been rounded to zero. - public var zeroThreshold: Double = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// Buckets are a set of bucket counts, encoded in a contiguous array - /// of counts. - public struct Buckets: Sendable { - // 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. - - /// Offset is the bucket index of the first entry in the bucket_counts array. - /// - /// Note: This uses a varint encoding as a simple form of compression. - public var offset: Int32 = 0 - - /// bucket_counts is an array of count values, where bucket_counts[i] carries - /// the count of the bucket at index (offset+i). bucket_counts[i] is the count - /// of values greater than base^(offset+i) and less than or equal to - /// base^(offset+i+1). - /// - /// Note: By contrast, the explicit HistogramDataPoint uses - /// fixed64. This field is expected to have many buckets, - /// especially zeros, so uint64 has been selected to ensure - /// varint encoding. - public var bucketCounts: [UInt64] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - } - - public init() {} - - fileprivate var _sum: Double? = nil - fileprivate var _positive: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets? = nil - fileprivate var _negative: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets? = nil - fileprivate var _min: Double? = nil - fileprivate var _max: Double? = nil -} - -/// SummaryDataPoint is a single data point in a timeseries that describes the -/// time-varying values of a Summary metric. The count and sum fields represent -/// cumulative values. -public struct Opentelemetry_Proto_Metrics_V1_SummaryDataPoint: Sendable { - // 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 key/value pairs that uniquely identify the timeseries from - /// where this point belongs. The list may be empty (may contain 0 elements). - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// StartTimeUnixNano is optional but strongly encouraged, see the - /// the detailed comments above Metric. - /// - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - /// 1970. - public var startTimeUnixNano: UInt64 = 0 - - /// TimeUnixNano is required, see the detailed comments above Metric. - /// - /// 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. - /// - /// Note: Sum should only be filled out when measuring non-negative discrete - /// events, and is assumed to be monotonic over the values of these events. - /// Negative events *can* be recorded, but sum should not be filled out when - /// doing so. This is specifically to enforce compatibility w/ OpenMetrics, - /// see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#summary - 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_SummaryDataPoint.ValueAtQuantile] = [] - - /// Flags that apply to this specific data point. See DataPointFlags - /// for the available flags and their meaning. - public var flags: UInt32 = 0 - - 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: Sendable { - // 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. - /// - /// Quantile values must NOT be negative. - public var value: Double = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - } - - public init() {} -} - -/// A representation of an exemplar, which is a sample input 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 -/// exemplar was recorded. -public struct Opentelemetry_Proto_Metrics_V1_Exemplar: @unchecked Sendable { - // 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 key/value pairs that were filtered out by the aggregator, but - /// recorded alongside the original measurement. Only key/value pairs that were - /// filtered out by the aggregator should be included - public var filteredAttributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// time_unix_nano is the exact time when this exemplar was recorded - /// - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - /// 1970. - public var timeUnixNano: UInt64 = 0 - - /// The value of the measurement that was recorded. An exemplar is - /// considered invalid when one of the recognized value fields is not present - /// inside this oneof. - public var value: Opentelemetry_Proto_Metrics_V1_Exemplar.OneOf_Value? = nil - - public var asDouble: Double { - get { - if case .asDouble(let v)? = value {return v} - return 0 - } - set {value = .asDouble(newValue)} - } - - public var asInt: Int64 { - get { - if case .asInt(let v)? = value {return v} - return 0 - } - set {value = .asInt(newValue)} - } - - /// (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 = 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 = Data() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// The value of the measurement that was recorded. An exemplar is - /// considered invalid when one of the recognized value fields is not present - /// inside this oneof. - public enum OneOf_Value: Equatable, Sendable { - case asDouble(Double) - case asInt(Int64) - - } - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.metrics.v1" - -extension Opentelemetry_Proto_Metrics_V1_AggregationTemporality: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "AGGREGATION_TEMPORALITY_UNSPECIFIED"), - 1: .same(proto: "AGGREGATION_TEMPORALITY_DELTA"), - 2: .same(proto: "AGGREGATION_TEMPORALITY_CUMULATIVE"), - ] -} - -extension Opentelemetry_Proto_Metrics_V1_DataPointFlags: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DATA_POINT_FLAGS_DO_NOT_USE"), - 1: .same(proto: "DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK"), - ] -} - -extension Opentelemetry_Proto_Metrics_V1_MetricsData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".MetricsData" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_metrics"), - ] - - 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.resourceMetrics) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceMetrics.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceMetrics, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_MetricsData, rhs: Opentelemetry_Proto_Metrics_V1_MetricsData) -> Bool { - if lhs.resourceMetrics != rhs.resourceMetrics {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_ResourceMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ResourceMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "resource"), - 2: .standard(proto: "scope_metrics"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._resource) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.scopeMetrics) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.scopeMetrics.isEmpty { - try visitor.visitRepeatedMessageField(value: self.scopeMetrics, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_ResourceMetrics, rhs: Opentelemetry_Proto_Metrics_V1_ResourceMetrics) -> Bool { - if lhs._resource != rhs._resource {return false} - if lhs.scopeMetrics != rhs.scopeMetrics {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_ScopeMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ScopeMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "scope"), - 2: .same(proto: "metrics"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._scope) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.metrics) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._scope { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.metrics.isEmpty { - try visitor.visitRepeatedMessageField(value: self.metrics, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_ScopeMetrics, rhs: Opentelemetry_Proto_Metrics_V1_ScopeMetrics) -> Bool { - if lhs._scope != rhs._scope {return false} - if lhs.metrics != rhs.metrics {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_Metric: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Metric" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "name"), - 2: .same(proto: "description"), - 3: .same(proto: "unit"), - 5: .same(proto: "gauge"), - 7: .same(proto: "sum"), - 9: .same(proto: "histogram"), - 10: .standard(proto: "exponential_histogram"), - 11: .same(proto: "summary"), - 12: .same(proto: "metadata"), - ] - - 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.decodeSingularStringField(value: &self.name) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.description_p) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.unit) }() - case 5: try { - var v: Opentelemetry_Proto_Metrics_V1_Gauge? - var hadOneofValue = false - if let current = self.data { - hadOneofValue = true - if case .gauge(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.data = .gauge(v) - } - }() - case 7: try { - var v: Opentelemetry_Proto_Metrics_V1_Sum? - var hadOneofValue = false - if let current = self.data { - hadOneofValue = true - if case .sum(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.data = .sum(v) - } - }() - case 9: try { - var v: Opentelemetry_Proto_Metrics_V1_Histogram? - var hadOneofValue = false - if let current = self.data { - hadOneofValue = true - if case .histogram(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.data = .histogram(v) - } - }() - case 10: try { - var v: Opentelemetry_Proto_Metrics_V1_ExponentialHistogram? - var hadOneofValue = false - if let current = self.data { - hadOneofValue = true - if case .exponentialHistogram(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.data = .exponentialHistogram(v) - } - }() - case 11: try { - var v: Opentelemetry_Proto_Metrics_V1_Summary? - var hadOneofValue = false - if let current = self.data { - hadOneofValue = true - if case .summary(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.data = .summary(v) - } - }() - case 12: try { try decoder.decodeRepeatedMessageField(value: &self.metadata) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - 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) - } - switch self.data { - case .gauge?: try { - guard case .gauge(let v)? = self.data else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - }() - case .sum?: try { - guard case .sum(let v)? = self.data else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - }() - case .histogram?: try { - guard case .histogram(let v)? = self.data else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 9) - }() - case .exponentialHistogram?: try { - guard case .exponentialHistogram(let v)? = self.data else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 10) - }() - case .summary?: try { - guard case .summary(let v)? = self.data else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 11) - }() - case nil: break - } - if !self.metadata.isEmpty { - try visitor.visitRepeatedMessageField(value: self.metadata, fieldNumber: 12) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_Metric, rhs: Opentelemetry_Proto_Metrics_V1_Metric) -> Bool { - 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.metadata != rhs.metadata {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_Gauge: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Gauge" - 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_Gauge, rhs: Opentelemetry_Proto_Metrics_V1_Gauge) -> Bool { - if lhs.dataPoints != rhs.dataPoints {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_Sum: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Sum" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "data_points"), - 2: .standard(proto: "aggregation_temporality"), - 3: .standard(proto: "is_monotonic"), - ] - - 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) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() - case 3: try { try decoder.decodeSingularBoolField(value: &self.isMonotonic) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.dataPoints.isEmpty { - try visitor.visitRepeatedMessageField(value: self.dataPoints, fieldNumber: 1) - } - if self.aggregationTemporality != .unspecified { - try visitor.visitSingularEnumField(value: self.aggregationTemporality, fieldNumber: 2) - } - if self.isMonotonic != false { - try visitor.visitSingularBoolField(value: self.isMonotonic, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_Sum, rhs: Opentelemetry_Proto_Metrics_V1_Sum) -> Bool { - if lhs.dataPoints != rhs.dataPoints {return false} - if lhs.aggregationTemporality != rhs.aggregationTemporality {return false} - if lhs.isMonotonic != rhs.isMonotonic {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_Histogram: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Histogram" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "data_points"), - 2: .standard(proto: "aggregation_temporality"), - ] - - 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) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.dataPoints.isEmpty { - try visitor.visitRepeatedMessageField(value: self.dataPoints, fieldNumber: 1) - } - if self.aggregationTemporality != .unspecified { - try visitor.visitSingularEnumField(value: self.aggregationTemporality, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_Histogram, rhs: Opentelemetry_Proto_Metrics_V1_Histogram) -> Bool { - if lhs.dataPoints != rhs.dataPoints {return false} - if lhs.aggregationTemporality != rhs.aggregationTemporality {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_ExponentialHistogram: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExponentialHistogram" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "data_points"), - 2: .standard(proto: "aggregation_temporality"), - ] - - 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) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.dataPoints.isEmpty { - try visitor.visitRepeatedMessageField(value: self.dataPoints, fieldNumber: 1) - } - if self.aggregationTemporality != .unspecified { - try visitor.visitSingularEnumField(value: self.aggregationTemporality, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_ExponentialHistogram, rhs: Opentelemetry_Proto_Metrics_V1_ExponentialHistogram) -> Bool { - if lhs.dataPoints != rhs.dataPoints {return false} - if lhs.aggregationTemporality != rhs.aggregationTemporality {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_Summary: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Summary" - 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_Summary, rhs: Opentelemetry_Proto_Metrics_V1_Summary) -> Bool { - if lhs.dataPoints != rhs.dataPoints {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_NumberDataPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".NumberDataPoint" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 7: .same(proto: "attributes"), - 2: .standard(proto: "start_time_unix_nano"), - 3: .standard(proto: "time_unix_nano"), - 4: .standard(proto: "as_double"), - 6: .standard(proto: "as_int"), - 5: .same(proto: "exemplars"), - 8: .same(proto: "flags"), - ] - - 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 2: try { try decoder.decodeSingularFixed64Field(value: &self.startTimeUnixNano) }() - case 3: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() - case 4: try { - var v: Double? - try decoder.decodeSingularDoubleField(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .asDouble(v) - } - }() - case 5: try { try decoder.decodeRepeatedMessageField(value: &self.exemplars) }() - case 6: try { - var v: Int64? - try decoder.decodeSingularSFixed64Field(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .asInt(v) - } - }() - case 7: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() - case 8: try { try decoder.decodeSingularUInt32Field(value: &self.flags) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if self.startTimeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: self.startTimeUnixNano, fieldNumber: 2) - } - if self.timeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: self.timeUnixNano, fieldNumber: 3) - } - try { if case .asDouble(let v)? = self.value { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 4) - } }() - if !self.exemplars.isEmpty { - try visitor.visitRepeatedMessageField(value: self.exemplars, fieldNumber: 5) - } - try { if case .asInt(let v)? = self.value { - try visitor.visitSingularSFixed64Field(value: v, fieldNumber: 6) - } }() - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 7) - } - if self.flags != 0 { - try visitor.visitSingularUInt32Field(value: self.flags, fieldNumber: 8) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_NumberDataPoint, rhs: Opentelemetry_Proto_Metrics_V1_NumberDataPoint) -> Bool { - if lhs.attributes != rhs.attributes {return false} - if lhs.startTimeUnixNano != rhs.startTimeUnixNano {return false} - if lhs.timeUnixNano != rhs.timeUnixNano {return false} - if lhs.value != rhs.value {return false} - if lhs.exemplars != rhs.exemplars {return false} - if lhs.flags != rhs.flags {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_HistogramDataPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".HistogramDataPoint" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 9: .same(proto: "attributes"), - 2: .standard(proto: "start_time_unix_nano"), - 3: .standard(proto: "time_unix_nano"), - 4: .same(proto: "count"), - 5: .same(proto: "sum"), - 6: .standard(proto: "bucket_counts"), - 7: .standard(proto: "explicit_bounds"), - 8: .same(proto: "exemplars"), - 10: .same(proto: "flags"), - 11: .same(proto: "min"), - 12: .same(proto: "max"), - ] - - 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 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) }() - case 9: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() - case 10: try { try decoder.decodeSingularUInt32Field(value: &self.flags) }() - case 11: try { try decoder.decodeSingularDoubleField(value: &self._min) }() - case 12: try { try decoder.decodeSingularDoubleField(value: &self._max) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - 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) - } - try { if let v = self._sum { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 5) - } }() - if !self.bucketCounts.isEmpty { - try visitor.visitPackedFixed64Field(value: self.bucketCounts, fieldNumber: 6) - } - if !self.explicitBounds.isEmpty { - try visitor.visitPackedDoubleField(value: self.explicitBounds, fieldNumber: 7) - } - if !self.exemplars.isEmpty { - try visitor.visitRepeatedMessageField(value: self.exemplars, fieldNumber: 8) - } - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 9) - } - if self.flags != 0 { - try visitor.visitSingularUInt32Field(value: self.flags, fieldNumber: 10) - } - try { if let v = self._min { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 11) - } }() - try { if let v = self._max { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 12) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_HistogramDataPoint, rhs: Opentelemetry_Proto_Metrics_V1_HistogramDataPoint) -> Bool { - if lhs.attributes != rhs.attributes {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.bucketCounts != rhs.bucketCounts {return false} - if lhs.explicitBounds != rhs.explicitBounds {return false} - if lhs.exemplars != rhs.exemplars {return false} - if lhs.flags != rhs.flags {return false} - if lhs._min != rhs._min {return false} - if lhs._max != rhs._max {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExponentialHistogramDataPoint" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "attributes"), - 2: .standard(proto: "start_time_unix_nano"), - 3: .standard(proto: "time_unix_nano"), - 4: .same(proto: "count"), - 5: .same(proto: "sum"), - 6: .same(proto: "scale"), - 7: .standard(proto: "zero_count"), - 8: .same(proto: "positive"), - 9: .same(proto: "negative"), - 10: .same(proto: "flags"), - 11: .same(proto: "exemplars"), - 12: .same(proto: "min"), - 13: .same(proto: "max"), - 14: .standard(proto: "zero_threshold"), - ] - - 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.attributes) }() - 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.decodeSingularSInt32Field(value: &self.scale) }() - case 7: try { try decoder.decodeSingularFixed64Field(value: &self.zeroCount) }() - case 8: try { try decoder.decodeSingularMessageField(value: &self._positive) }() - case 9: try { try decoder.decodeSingularMessageField(value: &self._negative) }() - case 10: try { try decoder.decodeSingularUInt32Field(value: &self.flags) }() - case 11: try { try decoder.decodeRepeatedMessageField(value: &self.exemplars) }() - case 12: try { try decoder.decodeSingularDoubleField(value: &self._min) }() - case 13: try { try decoder.decodeSingularDoubleField(value: &self._max) }() - case 14: try { try decoder.decodeSingularDoubleField(value: &self.zeroThreshold) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, 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) - } - try { if let v = self._sum { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 5) - } }() - if self.scale != 0 { - try visitor.visitSingularSInt32Field(value: self.scale, fieldNumber: 6) - } - if self.zeroCount != 0 { - try visitor.visitSingularFixed64Field(value: self.zeroCount, fieldNumber: 7) - } - try { if let v = self._positive { - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - } }() - try { if let v = self._negative { - try visitor.visitSingularMessageField(value: v, fieldNumber: 9) - } }() - if self.flags != 0 { - try visitor.visitSingularUInt32Field(value: self.flags, fieldNumber: 10) - } - if !self.exemplars.isEmpty { - try visitor.visitRepeatedMessageField(value: self.exemplars, fieldNumber: 11) - } - try { if let v = self._min { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 12) - } }() - try { if let v = self._max { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 13) - } }() - if self.zeroThreshold.bitPattern != 0 { - try visitor.visitSingularDoubleField(value: self.zeroThreshold, fieldNumber: 14) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint, rhs: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint) -> Bool { - if lhs.attributes != rhs.attributes {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.scale != rhs.scale {return false} - if lhs.zeroCount != rhs.zeroCount {return false} - if lhs._positive != rhs._positive {return false} - if lhs._negative != rhs._negative {return false} - if lhs.flags != rhs.flags {return false} - if lhs.exemplars != rhs.exemplars {return false} - if lhs._min != rhs._min {return false} - if lhs._max != rhs._max {return false} - if lhs.zeroThreshold != rhs.zeroThreshold {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.protoMessageName + ".Buckets" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "offset"), - 2: .standard(proto: "bucket_counts"), - ] - - 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.decodeSingularSInt32Field(value: &self.offset) }() - case 2: try { try decoder.decodeRepeatedUInt64Field(value: &self.bucketCounts) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.offset != 0 { - try visitor.visitSingularSInt32Field(value: self.offset, fieldNumber: 1) - } - if !self.bucketCounts.isEmpty { - try visitor.visitPackedUInt64Field(value: self.bucketCounts, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets, rhs: Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint.Buckets) -> Bool { - if lhs.offset != rhs.offset {return false} - if lhs.bucketCounts != rhs.bucketCounts {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_SummaryDataPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".SummaryDataPoint" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 7: .same(proto: "attributes"), - 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"), - 8: .same(proto: "flags"), - ] - - 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 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) }() - case 7: try { try decoder.decodeRepeatedMessageField(value: &self.attributes) }() - case 8: try { try decoder.decodeSingularUInt32Field(value: &self.flags) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - 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.bitPattern != 0 { - try visitor.visitSingularDoubleField(value: self.sum, fieldNumber: 5) - } - if !self.quantileValues.isEmpty { - try visitor.visitRepeatedMessageField(value: self.quantileValues, fieldNumber: 6) - } - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 7) - } - if self.flags != 0 { - try visitor.visitSingularUInt32Field(value: self.flags, fieldNumber: 8) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_SummaryDataPoint, rhs: Opentelemetry_Proto_Metrics_V1_SummaryDataPoint) -> Bool { - if lhs.attributes != rhs.attributes {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.flags != rhs.flags {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Metrics_V1_SummaryDataPoint.ValueAtQuantile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = Opentelemetry_Proto_Metrics_V1_SummaryDataPoint.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.bitPattern != 0 { - try visitor.visitSingularDoubleField(value: self.quantile, fieldNumber: 1) - } - if self.value.bitPattern != 0 { - try visitor.visitSingularDoubleField(value: self.value, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_SummaryDataPoint.ValueAtQuantile, rhs: Opentelemetry_Proto_Metrics_V1_SummaryDataPoint.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_Exemplar: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Exemplar" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 7: .standard(proto: "filtered_attributes"), - 2: .standard(proto: "time_unix_nano"), - 3: .standard(proto: "as_double"), - 6: .standard(proto: "as_int"), - 4: .standard(proto: "span_id"), - 5: .standard(proto: "trace_id"), - ] - - 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 2: try { try decoder.decodeSingularFixed64Field(value: &self.timeUnixNano) }() - case 3: try { - var v: Double? - try decoder.decodeSingularDoubleField(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .asDouble(v) - } - }() - case 4: try { try decoder.decodeSingularBytesField(value: &self.spanID) }() - case 5: try { try decoder.decodeSingularBytesField(value: &self.traceID) }() - case 6: try { - var v: Int64? - try decoder.decodeSingularSFixed64Field(value: &v) - if let v = v { - if self.value != nil {try decoder.handleConflictingOneOf()} - self.value = .asInt(v) - } - }() - case 7: try { try decoder.decodeRepeatedMessageField(value: &self.filteredAttributes) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if self.timeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: self.timeUnixNano, fieldNumber: 2) - } - try { if case .asDouble(let v)? = self.value { - try visitor.visitSingularDoubleField(value: v, fieldNumber: 3) - } }() - if !self.spanID.isEmpty { - try visitor.visitSingularBytesField(value: self.spanID, fieldNumber: 4) - } - if !self.traceID.isEmpty { - try visitor.visitSingularBytesField(value: self.traceID, fieldNumber: 5) - } - try { if case .asInt(let v)? = self.value { - try visitor.visitSingularSFixed64Field(value: v, fieldNumber: 6) - } }() - if !self.filteredAttributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.filteredAttributes, fieldNumber: 7) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Metrics_V1_Exemplar, rhs: Opentelemetry_Proto_Metrics_V1_Exemplar) -> Bool { - if lhs.filteredAttributes != rhs.filteredAttributes {return false} - if lhs.timeUnixNano != rhs.timeUnixNano {return false} - if lhs.value != rhs.value {return false} - if lhs.spanID != rhs.spanID {return false} - if lhs.traceID != rhs.traceID {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/metrics_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/metrics_service.pb.swift deleted file mode 100644 index 7c113835..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/metrics_service.pb.swift +++ /dev/null @@ -1,223 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2019, 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 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 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 {} - typealias Version = _2 -} - -public struct Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest: Sendable { - // 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. - - /// An array of ResourceMetrics. - /// For data coming from a single resource this array will typically contain one - /// element. Intermediary nodes (such as OpenTelemetry Collector) that receive - /// data from multiple origins typically batch the data before forwarding further and - /// in that case this array will contain multiple elements. - public var resourceMetrics: [Opentelemetry_Proto_Metrics_V1_ResourceMetrics] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -public struct Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse: Sendable { - // 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 details of a partially successful export request. - /// - /// If the request is only partially accepted - /// (i.e. when the server accepts only parts of the data and rejects the rest) - /// the server MUST initialize the `partial_success` field and MUST - /// set the `rejected_` with the number of items it rejected. - /// - /// Servers MAY also make use of the `partial_success` field to convey - /// warnings/suggestions to senders even when the request was fully accepted. - /// In such cases, the `rejected_` MUST have a value of `0` and - /// the `error_message` MUST be non-empty. - /// - /// A `partial_success` message with an empty value (rejected_ = 0 and - /// `error_message` = "") is equivalent to it not being set/present. Senders - /// SHOULD interpret it the same way as in the full success case. - public var partialSuccess: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess { - get {return _partialSuccess ?? Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess()} - set {_partialSuccess = newValue} - } - /// Returns true if `partialSuccess` has been explicitly set. - public var hasPartialSuccess: Bool {return self._partialSuccess != nil} - /// Clears the value of `partialSuccess`. Subsequent reads from it will return its default value. - public mutating func clearPartialSuccess() {self._partialSuccess = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _partialSuccess: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess? = nil -} - -public struct Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess: Sendable { - // 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 number of rejected data points. - /// - /// A `rejected_` field holding a `0` value indicates that the - /// request was fully accepted. - public var rejectedDataPoints: Int64 = 0 - - /// A developer-facing human-readable message in English. It should be used - /// either to explain why the server rejected parts of the data during a partial - /// success or to convey warnings/suggestions during a full success. The message - /// should offer guidance on how users can address such issues. - /// - /// error_message is an optional field. An error_message with an empty value - /// is equivalent to it not being set. - public var errorMessage: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.collector.metrics.v1" - -extension Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportMetricsServiceRequest" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_metrics"), - ] - - 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.resourceMetrics) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceMetrics.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceMetrics, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, rhs: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest) -> Bool { - if lhs.resourceMetrics != rhs.resourceMetrics {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportMetricsServiceResponse" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "partial_success"), - ] - - 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.decodeSingularMessageField(value: &self._partialSuccess) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._partialSuccess { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse, rhs: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse) -> Bool { - if lhs._partialSuccess != rhs._partialSuccess {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportMetricsPartialSuccess" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "rejected_data_points"), - 2: .standard(proto: "error_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 { try decoder.decodeSingularInt64Field(value: &self.rejectedDataPoints) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.rejectedDataPoints != 0 { - try visitor.visitSingularInt64Field(value: self.rejectedDataPoints, fieldNumber: 1) - } - if !self.errorMessage.isEmpty { - try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess, rhs: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsPartialSuccess) -> Bool { - if lhs.rejectedDataPoints != rhs.rejectedDataPoints {return false} - if lhs.errorMessage != rhs.errorMessage {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/profiles.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/profiles.pb.swift deleted file mode 100644 index 3c193601..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/profiles.pb.swift +++ /dev/null @@ -1,1471 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/profiles/v1development/profiles.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2023, 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. -// -// This file includes work covered by the following copyright and permission notices: -// -// Copyright 2016 Google Inc. All Rights Reserved. -// -// 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 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 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 {} - typealias Version = _2 -} - -/// Specifies the method of aggregating metric values, either DELTA (change since last report) -/// or CUMULATIVE (total since a fixed start time). -public enum Opentelemetry_Proto_Profiles_V1development_AggregationTemporality: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// UNSPECIFIED is the default AggregationTemporality, it MUST not be used. - case unspecified // = 0 - - ///* DELTA is an AggregationTemporality for a profiler which reports - ///changes since last report time. Successive metrics contain aggregation of - ///values from continuous and non-overlapping intervals. - /// - ///The values for a DELTA metric are based only on the time interval - ///associated with one measurement cycle. There is no dependency on - ///previous measurements like is the case for CUMULATIVE metrics. - /// - ///For example, consider a system measuring the number of requests that - ///it receives and reports the sum of these requests every second as a - ///DELTA metric: - /// - ///1. The system starts receiving at time=t_0. - ///2. A request is received, the system measures 1 request. - ///3. A request is received, the system measures 1 request. - ///4. A request is received, the system measures 1 request. - ///5. The 1 second collection cycle ends. A metric is exported for the - ///number of requests received over the interval of time t_0 to - ///t_0+1 with a value of 3. - ///6. A request is received, the system measures 1 request. - ///7. A request is received, the system measures 1 request. - ///8. The 1 second collection cycle ends. A metric is exported for the - ///number of requests received over the interval of time t_0+1 to - ///t_0+2 with a value of 2. - case delta // = 1 - - ///* CUMULATIVE is an AggregationTemporality for a profiler 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 - ///in some form. If this state is lost or invalidated, the CUMULATIVE metric - ///values MUST be reset and a new fixed start time following the last - ///reported measurement time sent MUST be used. - /// - ///For example, consider a system measuring the number of requests that - ///it receives and reports the sum of these requests every second as a - ///CUMULATIVE metric: - /// - ///1. The system starts receiving at time=t_0. - ///2. A request is received, the system measures 1 request. - ///3. A request is received, the system measures 1 request. - ///4. A request is received, the system measures 1 request. - ///5. The 1 second collection cycle ends. A metric is exported for the - ///number of requests received over the interval of time t_0 to - ///t_0+1 with a value of 3. - ///6. A request is received, the system measures 1 request. - ///7. A request is received, the system measures 1 request. - ///8. The 1 second collection cycle ends. A metric is exported for the - ///number of requests received over the interval of time t_0 to - ///t_0+2 with a value of 5. - ///9. The system experiences a fault and loses state. - ///10. The system recovers and resumes receiving at time=t_1. - ///11. A request is received, the system measures 1 request. - ///12. The 1 second collection cycle ends. A metric is exported for the - ///number of requests received over the interval of time t_1 to - ///t_1+1 with a value of 1. - /// - ///Note: Even though, when reporting changes since last report time, using - ///CUMULATIVE is valid, it is not recommended. - case cumulative // = 2 - case UNRECOGNIZED(Int) - - public init() { - self = .unspecified - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .unspecified - case 1: self = .delta - case 2: self = .cumulative - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .unspecified: return 0 - case .delta: return 1 - case .cumulative: return 2 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Profiles_V1development_AggregationTemporality] = [ - .unspecified, - .delta, - .cumulative, - ] - -} - -/// ProfilesData represents the profiles data that can be stored in persistent storage, -/// OR can be embedded by other protocols that transfer OTLP profiles data but do not -/// implement the OTLP protocol. -/// -/// The main difference between this message and collector protocol is that -/// in this message there will not be any "control" or "metadata" specific to -/// OTLP protocol. -/// -/// When new fields are added into this message, the OTLP request MUST be updated -/// as well. -public struct Opentelemetry_Proto_Profiles_V1development_ProfilesData: Sendable { - // 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. - - /// An array of ResourceProfiles. - /// For data coming from a single resource this array will typically contain - /// one element. Intermediary nodes that receive data from multiple origins - /// typically batch the data before forwarding further and in that case this - /// array will contain multiple elements. - public var resourceProfiles: [Opentelemetry_Proto_Profiles_V1development_ResourceProfiles] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// A collection of ScopeProfiles from a Resource. -public struct Opentelemetry_Proto_Profiles_V1development_ResourceProfiles: Sendable { - // 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 resource for the profiles 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 _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_resource = newValue} - } - /// Returns true if `resource` has been explicitly set. - 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() {self._resource = nil} - - /// A list of ScopeProfiles that originate from a resource. - public var scopeProfiles: [Opentelemetry_Proto_Profiles_V1development_ScopeProfiles] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the resource data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to the data in the "resource" field. It does not apply - /// to the data in the "scope_profiles" field which have their own schema_url field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil -} - -/// A collection of Profiles produced by an InstrumentationScope. -public struct Opentelemetry_Proto_Profiles_V1development_ScopeProfiles: Sendable { - // 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 instrumentation scope information for the profiles in this message. - /// Semantically when InstrumentationScope isn't set, it is equivalent with - /// an empty instrumentation scope name (unknown). - public var scope: Opentelemetry_Proto_Common_V1_InstrumentationScope { - get {return _scope ?? Opentelemetry_Proto_Common_V1_InstrumentationScope()} - set {_scope = newValue} - } - /// Returns true if `scope` has been explicitly set. - public var hasScope: Bool {return self._scope != nil} - /// Clears the value of `scope`. Subsequent reads from it will return its default value. - public mutating func clearScope() {self._scope = nil} - - /// A list of Profiles that originate from an instrumentation scope. - public var profiles: [Opentelemetry_Proto_Profiles_V1development_Profile] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the profile data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to all profiles in the "profiles" field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _scope: Opentelemetry_Proto_Common_V1_InstrumentationScope? = nil -} - -/// Represents a complete profile, including sample types, samples, -/// mappings to binaries, locations, functions, string table, and additional metadata. -/// It modifies and annotates pprof Profile with OpenTelemetry specific fields. -/// -/// Note that whilst fields in this message retain the name and field id from pprof in most cases -/// for ease of understanding data migration, it is not intended that pprof:Profile and -/// OpenTelemetry:Profile encoding be wire compatible. -public struct Opentelemetry_Proto_Profiles_V1development_Profile: @unchecked Sendable { - // 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. - - /// A description of the samples associated with each Sample.value. - /// For a cpu profile this might be: - /// [["cpu","nanoseconds"]] or [["wall","seconds"]] or [["syscall","count"]] - /// For a heap profile, this might be: - /// [["allocations","count"], ["space","bytes"]], - /// If one of the values represents the number of events represented - /// by the sample, by convention it should be at index 0 and use - /// sample_type.unit == "count". - public var sampleType: [Opentelemetry_Proto_Profiles_V1development_ValueType] { - get {return _storage._sampleType} - set {_uniqueStorage()._sampleType = newValue} - } - - /// The set of samples recorded in this profile. - public var sample: [Opentelemetry_Proto_Profiles_V1development_Sample] { - get {return _storage._sample} - set {_uniqueStorage()._sample = newValue} - } - - /// Mapping from address ranges to the image/binary/library mapped - /// into that address range. mapping[0] will be the main binary. - /// If multiple binaries contribute to the Profile and no main - /// binary can be identified, mapping[0] has no special meaning. - public var mappingTable: [Opentelemetry_Proto_Profiles_V1development_Mapping] { - get {return _storage._mappingTable} - set {_uniqueStorage()._mappingTable = newValue} - } - - /// Locations referenced by samples via location_indices. - public var locationTable: [Opentelemetry_Proto_Profiles_V1development_Location] { - get {return _storage._locationTable} - set {_uniqueStorage()._locationTable = newValue} - } - - /// Array of locations referenced by samples. - public var locationIndices: [Int32] { - get {return _storage._locationIndices} - set {_uniqueStorage()._locationIndices = newValue} - } - - /// Functions referenced by locations. - public var functionTable: [Opentelemetry_Proto_Profiles_V1development_Function] { - get {return _storage._functionTable} - set {_uniqueStorage()._functionTable = newValue} - } - - /// Lookup table for attributes. - public var attributeTable: [Opentelemetry_Proto_Common_V1_KeyValue] { - get {return _storage._attributeTable} - set {_uniqueStorage()._attributeTable = newValue} - } - - /// Represents a mapping between Attribute Keys and Units. - public var attributeUnits: [Opentelemetry_Proto_Profiles_V1development_AttributeUnit] { - get {return _storage._attributeUnits} - set {_uniqueStorage()._attributeUnits = newValue} - } - - /// Lookup table for links. - public var linkTable: [Opentelemetry_Proto_Profiles_V1development_Link] { - get {return _storage._linkTable} - set {_uniqueStorage()._linkTable = newValue} - } - - /// A common table for strings referenced by various messages. - /// string_table[0] must always be "". - public var stringTable: [String] { - get {return _storage._stringTable} - set {_uniqueStorage()._stringTable = newValue} - } - - /// Time of collection (UTC) represented as nanoseconds past the epoch. - public var timeNanos: Int64 { - get {return _storage._timeNanos} - set {_uniqueStorage()._timeNanos = newValue} - } - - /// Duration of the profile, if a duration makes sense. - public var durationNanos: Int64 { - get {return _storage._durationNanos} - set {_uniqueStorage()._durationNanos = newValue} - } - - /// The kind of events between sampled occurrences. - /// e.g [ "cpu","cycles" ] or [ "heap","bytes" ] - public var periodType: Opentelemetry_Proto_Profiles_V1development_ValueType { - get {return _storage._periodType ?? Opentelemetry_Proto_Profiles_V1development_ValueType()} - set {_uniqueStorage()._periodType = newValue} - } - /// Returns true if `periodType` has been explicitly set. - public var hasPeriodType: Bool {return _storage._periodType != nil} - /// Clears the value of `periodType`. Subsequent reads from it will return its default value. - public mutating func clearPeriodType() {_uniqueStorage()._periodType = nil} - - /// The number of events between sampled occurrences. - public var period: Int64 { - get {return _storage._period} - set {_uniqueStorage()._period = newValue} - } - - /// Free-form text associated with the profile. The text is displayed as is - /// to the user by the tools that read profiles (e.g. by pprof). This field - /// should not be used to store any machine-readable information, it is only - /// for human-friendly content. The profile must stay functional if this field - /// is cleaned. - public var commentStrindices: [Int32] { - get {return _storage._commentStrindices} - set {_uniqueStorage()._commentStrindices = newValue} - } - - /// Index into the string table of the type of the preferred sample - /// value. If unset, clients should default to the last sample value. - public var defaultSampleTypeStrindex: Int32 { - get {return _storage._defaultSampleTypeStrindex} - set {_uniqueStorage()._defaultSampleTypeStrindex = newValue} - } - - /// A globally unique identifier for a profile. The ID is a 16-byte array. An ID with - /// all zeroes is considered invalid. - /// - /// This field is required. - public var profileID: Data { - get {return _storage._profileID} - set {_uniqueStorage()._profileID = newValue} - } - - /// dropped_attributes_count is the number of attributes that were discarded. Attributes - /// can be discarded because their keys are too long or because there are too many - /// attributes. If this value is 0, then no attributes were dropped. - public var droppedAttributesCount: UInt32 { - get {return _storage._droppedAttributesCount} - set {_uniqueStorage()._droppedAttributesCount = newValue} - } - - /// Specifies format of the original payload. Common values are defined in semantic conventions. [required if original_payload is present] - public var originalPayloadFormat: String { - get {return _storage._originalPayloadFormat} - set {_uniqueStorage()._originalPayloadFormat = newValue} - } - - /// Original payload can be stored in this field. This can be useful for users who want to get the original payload. - /// Formats such as JFR are highly extensible and can contain more information than what is defined in this spec. - /// Inclusion of original payload should be configurable by the user. Default behavior should be to not include the original payload. - /// If the original payload is in pprof format, it SHOULD not be included in this field. - /// The field is optional, however if it is present then equivalent converted data should be populated in other fields - /// of this message as far as is practicable. - public var originalPayload: Data { - get {return _storage._originalPayload} - set {_uniqueStorage()._originalPayload = newValue} - } - - /// References to attributes in attribute_table. [optional] - /// It is a collection of key/value pairs. Note, global attributes - /// like server name can be set using the resource API. Examples of attributes: - /// - /// "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" - /// "/http/server_latency": 300 - /// "abc.com/myattribute": true - /// "abc.com/score": 10.239 - /// - /// The OpenTelemetry API specification further restricts the allowed value types: - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributeIndices: [Int32] { - get {return _storage._attributeIndices} - set {_uniqueStorage()._attributeIndices = newValue} - } - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _storage = _StorageClass.defaultInstance -} - -/// Represents a mapping between Attribute Keys and Units. -public struct Opentelemetry_Proto_Profiles_V1development_AttributeUnit: Sendable { - // 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. - - /// Index into string table. - public var attributeKeyStrindex: Int32 = 0 - - /// Index into string table. - public var unitStrindex: Int32 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// A pointer from a profile Sample to a trace Span. -/// Connects a profile sample to a trace span, identified by unique trace and span IDs. -public struct Opentelemetry_Proto_Profiles_V1development_Link: @unchecked Sendable { - // 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. - - /// A unique identifier of a trace that this linked span is part of. The ID is a - /// 16-byte array. - public var traceID: Data = Data() - - /// A unique identifier for the linked span. The ID is an 8-byte array. - public var spanID: Data = Data() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// ValueType describes the type and units of a value, with an optional aggregation temporality. -public struct Opentelemetry_Proto_Profiles_V1development_ValueType: Sendable { - // 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. - - /// Index into string table. - public var typeStrindex: Int32 = 0 - - /// Index into string table. - public var unitStrindex: Int32 = 0 - - public var aggregationTemporality: Opentelemetry_Proto_Profiles_V1development_AggregationTemporality = .unspecified - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// Each Sample records values encountered in some program -/// context. The program context is typically a stack trace, perhaps -/// augmented with auxiliary information like the thread-id, some -/// indicator of a higher level request being handled etc. -public struct Opentelemetry_Proto_Profiles_V1development_Sample: Sendable { - // 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. - - /// locations_start_index along with locations_length refers to to a slice of locations in Profile.location_indices. - public var locationsStartIndex: Int32 = 0 - - /// locations_length along with locations_start_index refers to a slice of locations in Profile.location_indices. - /// Supersedes location_index. - public var locationsLength: Int32 = 0 - - /// The type and unit of each value is defined by the corresponding - /// entry in Profile.sample_type. All samples must have the same - /// number of values, the same as the length of Profile.sample_type. - /// When aggregating multiple samples into a single sample, the - /// result has a list of values that is the element-wise sum of the - /// lists of the originals. - public var value: [Int64] = [] - - /// References to attributes in Profile.attribute_table. [optional] - public var attributeIndices: [Int32] = [] - - /// Reference to link in Profile.link_table. [optional] - public var linkIndex: Int32 { - get {return _linkIndex ?? 0} - set {_linkIndex = newValue} - } - /// Returns true if `linkIndex` has been explicitly set. - public var hasLinkIndex: Bool {return self._linkIndex != nil} - /// Clears the value of `linkIndex`. Subsequent reads from it will return its default value. - public mutating func clearLinkIndex() {self._linkIndex = nil} - - /// Timestamps associated with Sample represented in nanoseconds. These timestamps are expected - /// to fall within the Profile's time range. [optional] - public var timestampsUnixNano: [UInt64] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _linkIndex: Int32? = nil -} - -/// Describes the mapping of a binary in memory, including its address range, -/// file offset, and metadata like build ID -public struct Opentelemetry_Proto_Profiles_V1development_Mapping: Sendable { - // 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. - - /// Address at which the binary (or DLL) is loaded into memory. - public var memoryStart: UInt64 = 0 - - /// The limit of the address range occupied by this mapping. - public var memoryLimit: UInt64 = 0 - - /// Offset in the binary that corresponds to the first mapped address. - public var fileOffset: UInt64 = 0 - - /// The object this entry is loaded from. This can be a filename on - /// disk for the main binary and shared libraries, or virtual - /// abstractions like "[vdso]". - public var filenameStrindex: Int32 = 0 - - /// References to attributes in Profile.attribute_table. [optional] - public var attributeIndices: [Int32] = [] - - /// The following fields indicate the resolution of symbolic info. - public var hasFunctions_p: Bool = false - - public var hasFilenames_p: Bool = false - - public var hasLineNumbers_p: Bool = false - - public var hasInlineFrames_p: Bool = false - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// Describes function and line table debug information. -public struct Opentelemetry_Proto_Profiles_V1development_Location: Sendable { - // 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. - - /// Reference to mapping in Profile.mapping_table. - /// It can be unset if the mapping is unknown or not applicable for - /// this profile type. - public var mappingIndex: Int32 { - get {return _mappingIndex ?? 0} - set {_mappingIndex = newValue} - } - /// Returns true if `mappingIndex` has been explicitly set. - public var hasMappingIndex: Bool {return self._mappingIndex != nil} - /// Clears the value of `mappingIndex`. Subsequent reads from it will return its default value. - public mutating func clearMappingIndex() {self._mappingIndex = nil} - - /// The instruction address for this location, if available. It - /// should be within [Mapping.memory_start...Mapping.memory_limit] - /// for the corresponding mapping. A non-leaf address may be in the - /// middle of a call instruction. It is up to display tools to find - /// the beginning of the instruction if necessary. - public var address: UInt64 = 0 - - /// Multiple line indicates this location has inlined functions, - /// where the last entry represents the caller into which the - /// preceding entries were inlined. - /// - /// E.g., if memcpy() is inlined into printf: - /// line[0].function_name == "memcpy" - /// line[1].function_name == "printf" - public var line: [Opentelemetry_Proto_Profiles_V1development_Line] = [] - - /// Provides an indication that multiple symbols map to this location's - /// address, for example due to identical code folding by the linker. In that - /// case the line information above represents one of the multiple - /// symbols. This field must be recomputed when the symbolization state of the - /// profile changes. - public var isFolded: Bool = false - - /// References to attributes in Profile.attribute_table. [optional] - public var attributeIndices: [Int32] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _mappingIndex: Int32? = nil -} - -/// Details a specific line in a source code, linked to a function. -public struct Opentelemetry_Proto_Profiles_V1development_Line: Sendable { - // 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. - - /// Reference to function in Profile.function_table. - public var functionIndex: Int32 = 0 - - /// Line number in source code. - public var line: Int64 = 0 - - /// Column number in source code. - public var column: Int64 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// Describes a function, including its human-readable name, system name, -/// source file, and starting line number in the source. -public struct Opentelemetry_Proto_Profiles_V1development_Function: Sendable { - // 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. - - /// Name of the function, in human-readable form if available. - public var nameStrindex: Int32 = 0 - - /// Name of the function, as identified by the system. - /// For instance, it can be a C++ mangled name. - public var systemNameStrindex: Int32 = 0 - - /// Source file containing the function. - public var filenameStrindex: Int32 = 0 - - /// Line number in source file. - public var startLine: Int64 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.profiles.v1development" - -extension Opentelemetry_Proto_Profiles_V1development_AggregationTemporality: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "AGGREGATION_TEMPORALITY_UNSPECIFIED"), - 1: .same(proto: "AGGREGATION_TEMPORALITY_DELTA"), - 2: .same(proto: "AGGREGATION_TEMPORALITY_CUMULATIVE"), - ] -} - -extension Opentelemetry_Proto_Profiles_V1development_ProfilesData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ProfilesData" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_profiles"), - ] - - 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.resourceProfiles) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceProfiles.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceProfiles, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_ProfilesData, rhs: Opentelemetry_Proto_Profiles_V1development_ProfilesData) -> Bool { - if lhs.resourceProfiles != rhs.resourceProfiles {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_ResourceProfiles: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ResourceProfiles" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "resource"), - 2: .standard(proto: "scope_profiles"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._resource) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.scopeProfiles) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.scopeProfiles.isEmpty { - try visitor.visitRepeatedMessageField(value: self.scopeProfiles, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_ResourceProfiles, rhs: Opentelemetry_Proto_Profiles_V1development_ResourceProfiles) -> Bool { - if lhs._resource != rhs._resource {return false} - if lhs.scopeProfiles != rhs.scopeProfiles {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_ScopeProfiles: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ScopeProfiles" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "scope"), - 2: .same(proto: "profiles"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._scope) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.profiles) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._scope { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.profiles.isEmpty { - try visitor.visitRepeatedMessageField(value: self.profiles, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_ScopeProfiles, rhs: Opentelemetry_Proto_Profiles_V1development_ScopeProfiles) -> Bool { - if lhs._scope != rhs._scope {return false} - if lhs.profiles != rhs.profiles {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Profile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Profile" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "sample_type"), - 2: .same(proto: "sample"), - 3: .standard(proto: "mapping_table"), - 4: .standard(proto: "location_table"), - 5: .standard(proto: "location_indices"), - 6: .standard(proto: "function_table"), - 7: .standard(proto: "attribute_table"), - 8: .standard(proto: "attribute_units"), - 9: .standard(proto: "link_table"), - 10: .standard(proto: "string_table"), - 11: .standard(proto: "time_nanos"), - 12: .standard(proto: "duration_nanos"), - 13: .standard(proto: "period_type"), - 14: .same(proto: "period"), - 15: .standard(proto: "comment_strindices"), - 16: .standard(proto: "default_sample_type_strindex"), - 17: .standard(proto: "profile_id"), - 19: .standard(proto: "dropped_attributes_count"), - 20: .standard(proto: "original_payload_format"), - 21: .standard(proto: "original_payload"), - 22: .standard(proto: "attribute_indices"), - ] - - fileprivate class _StorageClass { - var _sampleType: [Opentelemetry_Proto_Profiles_V1development_ValueType] = [] - var _sample: [Opentelemetry_Proto_Profiles_V1development_Sample] = [] - var _mappingTable: [Opentelemetry_Proto_Profiles_V1development_Mapping] = [] - var _locationTable: [Opentelemetry_Proto_Profiles_V1development_Location] = [] - var _locationIndices: [Int32] = [] - var _functionTable: [Opentelemetry_Proto_Profiles_V1development_Function] = [] - var _attributeTable: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - var _attributeUnits: [Opentelemetry_Proto_Profiles_V1development_AttributeUnit] = [] - var _linkTable: [Opentelemetry_Proto_Profiles_V1development_Link] = [] - var _stringTable: [String] = [] - var _timeNanos: Int64 = 0 - var _durationNanos: Int64 = 0 - var _periodType: Opentelemetry_Proto_Profiles_V1development_ValueType? = nil - var _period: Int64 = 0 - var _commentStrindices: [Int32] = [] - var _defaultSampleTypeStrindex: Int32 = 0 - var _profileID: Data = Data() - var _droppedAttributesCount: UInt32 = 0 - var _originalPayloadFormat: String = String() - var _originalPayload: Data = Data() - var _attributeIndices: [Int32] = [] - - #if swift(>=5.10) - // This property is used as the initial default value for new instances of the type. - // The type itself is protecting the reference to its storage via CoW semantics. - // This will force a copy to be made of this reference when the first mutation occurs; - // hence, it is safe to mark this as `nonisolated(unsafe)`. - static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif - - private init() {} - - init(copying source: _StorageClass) { - _sampleType = source._sampleType - _sample = source._sample - _mappingTable = source._mappingTable - _locationTable = source._locationTable - _locationIndices = source._locationIndices - _functionTable = source._functionTable - _attributeTable = source._attributeTable - _attributeUnits = source._attributeUnits - _linkTable = source._linkTable - _stringTable = source._stringTable - _timeNanos = source._timeNanos - _durationNanos = source._durationNanos - _periodType = source._periodType - _period = source._period - _commentStrindices = source._commentStrindices - _defaultSampleTypeStrindex = source._defaultSampleTypeStrindex - _profileID = source._profileID - _droppedAttributesCount = source._droppedAttributesCount - _originalPayloadFormat = source._originalPayloadFormat - _originalPayload = source._originalPayload - _attributeIndices = source._attributeIndices - } - } - - 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() { - // 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: &_storage._sampleType) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &_storage._sample) }() - case 3: try { try decoder.decodeRepeatedMessageField(value: &_storage._mappingTable) }() - case 4: try { try decoder.decodeRepeatedMessageField(value: &_storage._locationTable) }() - case 5: try { try decoder.decodeRepeatedInt32Field(value: &_storage._locationIndices) }() - case 6: try { try decoder.decodeRepeatedMessageField(value: &_storage._functionTable) }() - case 7: try { try decoder.decodeRepeatedMessageField(value: &_storage._attributeTable) }() - case 8: try { try decoder.decodeRepeatedMessageField(value: &_storage._attributeUnits) }() - case 9: try { try decoder.decodeRepeatedMessageField(value: &_storage._linkTable) }() - case 10: try { try decoder.decodeRepeatedStringField(value: &_storage._stringTable) }() - case 11: try { try decoder.decodeSingularInt64Field(value: &_storage._timeNanos) }() - case 12: try { try decoder.decodeSingularInt64Field(value: &_storage._durationNanos) }() - case 13: try { try decoder.decodeSingularMessageField(value: &_storage._periodType) }() - case 14: try { try decoder.decodeSingularInt64Field(value: &_storage._period) }() - case 15: try { try decoder.decodeRepeatedInt32Field(value: &_storage._commentStrindices) }() - case 16: try { try decoder.decodeSingularInt32Field(value: &_storage._defaultSampleTypeStrindex) }() - case 17: try { try decoder.decodeSingularBytesField(value: &_storage._profileID) }() - case 19: try { try decoder.decodeSingularUInt32Field(value: &_storage._droppedAttributesCount) }() - case 20: try { try decoder.decodeSingularStringField(value: &_storage._originalPayloadFormat) }() - case 21: try { try decoder.decodeSingularBytesField(value: &_storage._originalPayload) }() - case 22: try { try decoder.decodeRepeatedInt32Field(value: &_storage._attributeIndices) }() - default: break - } - } - } - } - - public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !_storage._sampleType.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._sampleType, fieldNumber: 1) - } - if !_storage._sample.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._sample, fieldNumber: 2) - } - if !_storage._mappingTable.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._mappingTable, fieldNumber: 3) - } - if !_storage._locationTable.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._locationTable, fieldNumber: 4) - } - if !_storage._locationIndices.isEmpty { - try visitor.visitPackedInt32Field(value: _storage._locationIndices, fieldNumber: 5) - } - if !_storage._functionTable.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._functionTable, fieldNumber: 6) - } - if !_storage._attributeTable.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._attributeTable, fieldNumber: 7) - } - if !_storage._attributeUnits.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._attributeUnits, fieldNumber: 8) - } - if !_storage._linkTable.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._linkTable, fieldNumber: 9) - } - if !_storage._stringTable.isEmpty { - try visitor.visitRepeatedStringField(value: _storage._stringTable, fieldNumber: 10) - } - if _storage._timeNanos != 0 { - try visitor.visitSingularInt64Field(value: _storage._timeNanos, fieldNumber: 11) - } - if _storage._durationNanos != 0 { - try visitor.visitSingularInt64Field(value: _storage._durationNanos, fieldNumber: 12) - } - try { if let v = _storage._periodType { - try visitor.visitSingularMessageField(value: v, fieldNumber: 13) - } }() - if _storage._period != 0 { - try visitor.visitSingularInt64Field(value: _storage._period, fieldNumber: 14) - } - if !_storage._commentStrindices.isEmpty { - try visitor.visitPackedInt32Field(value: _storage._commentStrindices, fieldNumber: 15) - } - if _storage._defaultSampleTypeStrindex != 0 { - try visitor.visitSingularInt32Field(value: _storage._defaultSampleTypeStrindex, fieldNumber: 16) - } - if !_storage._profileID.isEmpty { - try visitor.visitSingularBytesField(value: _storage._profileID, fieldNumber: 17) - } - if _storage._droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: _storage._droppedAttributesCount, fieldNumber: 19) - } - if !_storage._originalPayloadFormat.isEmpty { - try visitor.visitSingularStringField(value: _storage._originalPayloadFormat, fieldNumber: 20) - } - if !_storage._originalPayload.isEmpty { - try visitor.visitSingularBytesField(value: _storage._originalPayload, fieldNumber: 21) - } - if !_storage._attributeIndices.isEmpty { - try visitor.visitPackedInt32Field(value: _storage._attributeIndices, fieldNumber: 22) - } - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Profile, rhs: Opentelemetry_Proto_Profiles_V1development_Profile) -> 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._sampleType != rhs_storage._sampleType {return false} - if _storage._sample != rhs_storage._sample {return false} - if _storage._mappingTable != rhs_storage._mappingTable {return false} - if _storage._locationTable != rhs_storage._locationTable {return false} - if _storage._locationIndices != rhs_storage._locationIndices {return false} - if _storage._functionTable != rhs_storage._functionTable {return false} - if _storage._attributeTable != rhs_storage._attributeTable {return false} - if _storage._attributeUnits != rhs_storage._attributeUnits {return false} - if _storage._linkTable != rhs_storage._linkTable {return false} - if _storage._stringTable != rhs_storage._stringTable {return false} - if _storage._timeNanos != rhs_storage._timeNanos {return false} - if _storage._durationNanos != rhs_storage._durationNanos {return false} - if _storage._periodType != rhs_storage._periodType {return false} - if _storage._period != rhs_storage._period {return false} - if _storage._commentStrindices != rhs_storage._commentStrindices {return false} - if _storage._defaultSampleTypeStrindex != rhs_storage._defaultSampleTypeStrindex {return false} - if _storage._profileID != rhs_storage._profileID {return false} - if _storage._droppedAttributesCount != rhs_storage._droppedAttributesCount {return false} - if _storage._originalPayloadFormat != rhs_storage._originalPayloadFormat {return false} - if _storage._originalPayload != rhs_storage._originalPayload {return false} - if _storage._attributeIndices != rhs_storage._attributeIndices {return false} - return true - } - if !storagesAreEqual {return false} - } - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_AttributeUnit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".AttributeUnit" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "attribute_key_strindex"), - 2: .standard(proto: "unit_strindex"), - ] - - 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.decodeSingularInt32Field(value: &self.attributeKeyStrindex) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self.unitStrindex) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.attributeKeyStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.attributeKeyStrindex, fieldNumber: 1) - } - if self.unitStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.unitStrindex, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_AttributeUnit, rhs: Opentelemetry_Proto_Profiles_V1development_AttributeUnit) -> Bool { - if lhs.attributeKeyStrindex != rhs.attributeKeyStrindex {return false} - if lhs.unitStrindex != rhs.unitStrindex {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Link: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Link" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "trace_id"), - 2: .standard(proto: "span_id"), - ] - - 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.decodeSingularBytesField(value: &self.traceID) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self.spanID) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.traceID.isEmpty { - try visitor.visitSingularBytesField(value: self.traceID, fieldNumber: 1) - } - if !self.spanID.isEmpty { - try visitor.visitSingularBytesField(value: self.spanID, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Link, rhs: Opentelemetry_Proto_Profiles_V1development_Link) -> Bool { - if lhs.traceID != rhs.traceID {return false} - if lhs.spanID != rhs.spanID {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_ValueType: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ValueType" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "type_strindex"), - 2: .standard(proto: "unit_strindex"), - 3: .standard(proto: "aggregation_temporality"), - ] - - 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.decodeSingularInt32Field(value: &self.typeStrindex) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self.unitStrindex) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self.aggregationTemporality) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.typeStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.typeStrindex, fieldNumber: 1) - } - if self.unitStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.unitStrindex, fieldNumber: 2) - } - if self.aggregationTemporality != .unspecified { - try visitor.visitSingularEnumField(value: self.aggregationTemporality, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_ValueType, rhs: Opentelemetry_Proto_Profiles_V1development_ValueType) -> Bool { - if lhs.typeStrindex != rhs.typeStrindex {return false} - if lhs.unitStrindex != rhs.unitStrindex {return false} - if lhs.aggregationTemporality != rhs.aggregationTemporality {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Sample: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Sample" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "locations_start_index"), - 2: .standard(proto: "locations_length"), - 3: .same(proto: "value"), - 4: .standard(proto: "attribute_indices"), - 5: .standard(proto: "link_index"), - 6: .standard(proto: "timestamps_unix_nano"), - ] - - 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.decodeSingularInt32Field(value: &self.locationsStartIndex) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self.locationsLength) }() - case 3: try { try decoder.decodeRepeatedInt64Field(value: &self.value) }() - case 4: try { try decoder.decodeRepeatedInt32Field(value: &self.attributeIndices) }() - case 5: try { try decoder.decodeSingularInt32Field(value: &self._linkIndex) }() - case 6: try { try decoder.decodeRepeatedUInt64Field(value: &self.timestampsUnixNano) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if self.locationsStartIndex != 0 { - try visitor.visitSingularInt32Field(value: self.locationsStartIndex, fieldNumber: 1) - } - if self.locationsLength != 0 { - try visitor.visitSingularInt32Field(value: self.locationsLength, fieldNumber: 2) - } - if !self.value.isEmpty { - try visitor.visitPackedInt64Field(value: self.value, fieldNumber: 3) - } - if !self.attributeIndices.isEmpty { - try visitor.visitPackedInt32Field(value: self.attributeIndices, fieldNumber: 4) - } - try { if let v = self._linkIndex { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 5) - } }() - if !self.timestampsUnixNano.isEmpty { - try visitor.visitPackedUInt64Field(value: self.timestampsUnixNano, fieldNumber: 6) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Sample, rhs: Opentelemetry_Proto_Profiles_V1development_Sample) -> Bool { - if lhs.locationsStartIndex != rhs.locationsStartIndex {return false} - if lhs.locationsLength != rhs.locationsLength {return false} - if lhs.value != rhs.value {return false} - if lhs.attributeIndices != rhs.attributeIndices {return false} - if lhs._linkIndex != rhs._linkIndex {return false} - if lhs.timestampsUnixNano != rhs.timestampsUnixNano {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Mapping: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Mapping" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "memory_start"), - 2: .standard(proto: "memory_limit"), - 3: .standard(proto: "file_offset"), - 4: .standard(proto: "filename_strindex"), - 5: .standard(proto: "attribute_indices"), - 6: .standard(proto: "has_functions"), - 7: .standard(proto: "has_filenames"), - 8: .standard(proto: "has_line_numbers"), - 9: .standard(proto: "has_inline_frames"), - ] - - 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.decodeSingularUInt64Field(value: &self.memoryStart) }() - case 2: try { try decoder.decodeSingularUInt64Field(value: &self.memoryLimit) }() - case 3: try { try decoder.decodeSingularUInt64Field(value: &self.fileOffset) }() - case 4: try { try decoder.decodeSingularInt32Field(value: &self.filenameStrindex) }() - case 5: try { try decoder.decodeRepeatedInt32Field(value: &self.attributeIndices) }() - case 6: try { try decoder.decodeSingularBoolField(value: &self.hasFunctions_p) }() - case 7: try { try decoder.decodeSingularBoolField(value: &self.hasFilenames_p) }() - case 8: try { try decoder.decodeSingularBoolField(value: &self.hasLineNumbers_p) }() - case 9: try { try decoder.decodeSingularBoolField(value: &self.hasInlineFrames_p) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.memoryStart != 0 { - try visitor.visitSingularUInt64Field(value: self.memoryStart, fieldNumber: 1) - } - if self.memoryLimit != 0 { - try visitor.visitSingularUInt64Field(value: self.memoryLimit, fieldNumber: 2) - } - if self.fileOffset != 0 { - try visitor.visitSingularUInt64Field(value: self.fileOffset, fieldNumber: 3) - } - if self.filenameStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.filenameStrindex, fieldNumber: 4) - } - if !self.attributeIndices.isEmpty { - try visitor.visitPackedInt32Field(value: self.attributeIndices, fieldNumber: 5) - } - if self.hasFunctions_p != false { - try visitor.visitSingularBoolField(value: self.hasFunctions_p, fieldNumber: 6) - } - if self.hasFilenames_p != false { - try visitor.visitSingularBoolField(value: self.hasFilenames_p, fieldNumber: 7) - } - if self.hasLineNumbers_p != false { - try visitor.visitSingularBoolField(value: self.hasLineNumbers_p, fieldNumber: 8) - } - if self.hasInlineFrames_p != false { - try visitor.visitSingularBoolField(value: self.hasInlineFrames_p, fieldNumber: 9) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Mapping, rhs: Opentelemetry_Proto_Profiles_V1development_Mapping) -> Bool { - if lhs.memoryStart != rhs.memoryStart {return false} - if lhs.memoryLimit != rhs.memoryLimit {return false} - if lhs.fileOffset != rhs.fileOffset {return false} - if lhs.filenameStrindex != rhs.filenameStrindex {return false} - if lhs.attributeIndices != rhs.attributeIndices {return false} - if lhs.hasFunctions_p != rhs.hasFunctions_p {return false} - if lhs.hasFilenames_p != rhs.hasFilenames_p {return false} - if lhs.hasLineNumbers_p != rhs.hasLineNumbers_p {return false} - if lhs.hasInlineFrames_p != rhs.hasInlineFrames_p {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Location: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Location" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "mapping_index"), - 2: .same(proto: "address"), - 3: .same(proto: "line"), - 4: .standard(proto: "is_folded"), - 5: .standard(proto: "attribute_indices"), - ] - - 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.decodeSingularInt32Field(value: &self._mappingIndex) }() - case 2: try { try decoder.decodeSingularUInt64Field(value: &self.address) }() - case 3: try { try decoder.decodeRepeatedMessageField(value: &self.line) }() - case 4: try { try decoder.decodeSingularBoolField(value: &self.isFolded) }() - case 5: try { try decoder.decodeRepeatedInt32Field(value: &self.attributeIndices) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._mappingIndex { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - if self.address != 0 { - try visitor.visitSingularUInt64Field(value: self.address, fieldNumber: 2) - } - if !self.line.isEmpty { - try visitor.visitRepeatedMessageField(value: self.line, fieldNumber: 3) - } - if self.isFolded != false { - try visitor.visitSingularBoolField(value: self.isFolded, fieldNumber: 4) - } - if !self.attributeIndices.isEmpty { - try visitor.visitPackedInt32Field(value: self.attributeIndices, fieldNumber: 5) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Location, rhs: Opentelemetry_Proto_Profiles_V1development_Location) -> Bool { - if lhs._mappingIndex != rhs._mappingIndex {return false} - if lhs.address != rhs.address {return false} - if lhs.line != rhs.line {return false} - if lhs.isFolded != rhs.isFolded {return false} - if lhs.attributeIndices != rhs.attributeIndices {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Line: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Line" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "function_index"), - 2: .same(proto: "line"), - 3: .same(proto: "column"), - ] - - 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.decodeSingularInt32Field(value: &self.functionIndex) }() - case 2: try { try decoder.decodeSingularInt64Field(value: &self.line) }() - case 3: try { try decoder.decodeSingularInt64Field(value: &self.column) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.functionIndex != 0 { - try visitor.visitSingularInt32Field(value: self.functionIndex, fieldNumber: 1) - } - if self.line != 0 { - try visitor.visitSingularInt64Field(value: self.line, fieldNumber: 2) - } - if self.column != 0 { - try visitor.visitSingularInt64Field(value: self.column, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Line, rhs: Opentelemetry_Proto_Profiles_V1development_Line) -> Bool { - if lhs.functionIndex != rhs.functionIndex {return false} - if lhs.line != rhs.line {return false} - if lhs.column != rhs.column {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Profiles_V1development_Function: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Function" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "name_strindex"), - 2: .standard(proto: "system_name_strindex"), - 3: .standard(proto: "filename_strindex"), - 4: .standard(proto: "start_line"), - ] - - 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.decodeSingularInt32Field(value: &self.nameStrindex) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self.systemNameStrindex) }() - case 3: try { try decoder.decodeSingularInt32Field(value: &self.filenameStrindex) }() - case 4: try { try decoder.decodeSingularInt64Field(value: &self.startLine) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.nameStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.nameStrindex, fieldNumber: 1) - } - if self.systemNameStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.systemNameStrindex, fieldNumber: 2) - } - if self.filenameStrindex != 0 { - try visitor.visitSingularInt32Field(value: self.filenameStrindex, fieldNumber: 3) - } - if self.startLine != 0 { - try visitor.visitSingularInt64Field(value: self.startLine, fieldNumber: 4) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Profiles_V1development_Function, rhs: Opentelemetry_Proto_Profiles_V1development_Function) -> Bool { - if lhs.nameStrindex != rhs.nameStrindex {return false} - if lhs.systemNameStrindex != rhs.systemNameStrindex {return false} - if lhs.filenameStrindex != rhs.filenameStrindex {return false} - if lhs.startLine != rhs.startLine {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/profiles_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/profiles_service.pb.swift deleted file mode 100644 index 20976b2e..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/profiles_service.pb.swift +++ /dev/null @@ -1,223 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/collector/profiles/v1development/profiles_service.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2023, 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 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 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 {} - typealias Version = _2 -} - -public struct Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest: Sendable { - // 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. - - /// An array of ResourceProfiles. - /// For data coming from a single resource this array will typically contain one - /// element. Intermediary nodes (such as OpenTelemetry Collector) that receive - /// data from multiple origins typically batch the data before forwarding further and - /// in that case this array will contain multiple elements. - public var resourceProfiles: [Opentelemetry_Proto_Profiles_V1development_ResourceProfiles] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -public struct Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceResponse: Sendable { - // 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 details of a partially successful export request. - /// - /// If the request is only partially accepted - /// (i.e. when the server accepts only parts of the data and rejects the rest) - /// the server MUST initialize the `partial_success` field and MUST - /// set the `rejected_` with the number of items it rejected. - /// - /// Servers MAY also make use of the `partial_success` field to convey - /// warnings/suggestions to senders even when the request was fully accepted. - /// In such cases, the `rejected_` MUST have a value of `0` and - /// the `error_message` MUST be non-empty. - /// - /// A `partial_success` message with an empty value (rejected_ = 0 and - /// `error_message` = "") is equivalent to it not being set/present. Senders - /// SHOULD interpret it the same way as in the full success case. - public var partialSuccess: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess { - get {return _partialSuccess ?? Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess()} - set {_partialSuccess = newValue} - } - /// Returns true if `partialSuccess` has been explicitly set. - public var hasPartialSuccess: Bool {return self._partialSuccess != nil} - /// Clears the value of `partialSuccess`. Subsequent reads from it will return its default value. - public mutating func clearPartialSuccess() {self._partialSuccess = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _partialSuccess: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess? = nil -} - -public struct Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess: Sendable { - // 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 number of rejected profiles. - /// - /// A `rejected_` field holding a `0` value indicates that the - /// request was fully accepted. - public var rejectedProfiles: Int64 = 0 - - /// A developer-facing human-readable message in English. It should be used - /// either to explain why the server rejected parts of the data during a partial - /// success or to convey warnings/suggestions during a full success. The message - /// should offer guidance on how users can address such issues. - /// - /// error_message is an optional field. An error_message with an empty value - /// is equivalent to it not being set. - public var errorMessage: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.collector.profiles.v1development" - -extension Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportProfilesServiceRequest" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_profiles"), - ] - - 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.resourceProfiles) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceProfiles.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceProfiles, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest, rhs: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest) -> Bool { - if lhs.resourceProfiles != rhs.resourceProfiles {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportProfilesServiceResponse" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "partial_success"), - ] - - 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.decodeSingularMessageField(value: &self._partialSuccess) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._partialSuccess { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceResponse, rhs: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceResponse) -> Bool { - if lhs._partialSuccess != rhs._partialSuccess {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportProfilesPartialSuccess" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "rejected_profiles"), - 2: .standard(proto: "error_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 { try decoder.decodeSingularInt64Field(value: &self.rejectedProfiles) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.rejectedProfiles != 0 { - try visitor.visitSingularInt64Field(value: self.rejectedProfiles, fieldNumber: 1) - } - if !self.errorMessage.isEmpty { - try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess, rhs: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesPartialSuccess) -> Bool { - if lhs.rejectedProfiles != rhs.rejectedProfiles {return false} - if lhs.errorMessage != rhs.errorMessage {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/resource.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/resource.pb.swift deleted file mode 100644 index 5198114b..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/resource.pb.swift +++ /dev/null @@ -1,97 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/resource/v1/resource.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2019, 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 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 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 {} - typealias Version = _2 -} - -/// Resource information. -public struct Opentelemetry_Proto_Resource_V1_Resource: Sendable { - // 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. - - /// Set of attributes that describe the resource. - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// dropped_attributes_count is the number of dropped attributes. If the value is 0, then - /// no attributes were dropped. - public var droppedAttributesCount: UInt32 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.resource.v1" - -extension Opentelemetry_Proto_Resource_V1_Resource: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Resource" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "attributes"), - 2: .standard(proto: "dropped_attributes_count"), - ] - - 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.attributes) }() - case 2: try { try decoder.decodeSingularUInt32Field(value: &self.droppedAttributesCount) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 1) - } - if self.droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: self.droppedAttributesCount, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Resource_V1_Resource, rhs: Opentelemetry_Proto_Resource_V1_Resource) -> Bool { - if lhs.attributes != rhs.attributes {return false} - if lhs.droppedAttributesCount != rhs.droppedAttributesCount {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/trace.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/trace.pb.swift deleted file mode 100644 index b130318b..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/trace.pb.swift +++ /dev/null @@ -1,1108 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/trace/v1/trace.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2019, 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 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 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 {} - typealias Version = _2 -} - -/// SpanFlags represents constants used to interpret the -/// Span.flags field, which is protobuf 'fixed32' type and is to -/// be used as bit-fields. Each non-zero value defined in this enum is -/// a bit-mask. To extract the bit-field, for example, use an -/// expression like: -/// -/// (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK) -/// -/// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. -/// -/// Note that Span flags were introduced in version 1.1 of the -/// OpenTelemetry protocol. Older Span producers do not set this -/// field, consequently consumers should not rely on the absence of a -/// particular flag bit to indicate the presence of a particular feature. -public enum Opentelemetry_Proto_Trace_V1_SpanFlags: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// The zero value for the enum. Should not be used for comparisons. - /// Instead use bitwise "and" with the appropriate mask as shown above. - case doNotUse // = 0 - - /// Bits 0-7 are used for trace flags. - case traceFlagsMask // = 255 - - /// Bits 8 and 9 are used to indicate that the parent span or link span is remote. - /// Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. - /// Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote. - case contextHasIsRemoteMask // = 256 - case contextIsRemoteMask // = 512 - case UNRECOGNIZED(Int) - - public init() { - self = .doNotUse - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .doNotUse - case 255: self = .traceFlagsMask - case 256: self = .contextHasIsRemoteMask - case 512: self = .contextIsRemoteMask - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .doNotUse: return 0 - case .traceFlagsMask: return 255 - case .contextHasIsRemoteMask: return 256 - case .contextIsRemoteMask: return 512 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Trace_V1_SpanFlags] = [ - .doNotUse, - .traceFlagsMask, - .contextHasIsRemoteMask, - .contextIsRemoteMask, - ] - -} - -/// TracesData represents the traces data that can be stored in a persistent storage, -/// OR can be embedded by other protocols that transfer OTLP traces data but do -/// not implement the OTLP protocol. -/// -/// The main difference between this message and collector protocol is that -/// in this message there will not be any "control" or "metadata" specific to -/// OTLP protocol. -/// -/// When new fields are added into this message, the OTLP request MUST be updated -/// as well. -public struct Opentelemetry_Proto_Trace_V1_TracesData: Sendable { - // 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. - - /// An array of ResourceSpans. - /// For data coming from a single resource this array will typically contain - /// one element. Intermediary nodes that receive data from multiple origins - /// typically batch the data before forwarding further and in that case this - /// array will contain multiple elements. - public var resourceSpans: [Opentelemetry_Proto_Trace_V1_ResourceSpans] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -/// A collection of ScopeSpans from a Resource. -public struct Opentelemetry_Proto_Trace_V1_ResourceSpans: Sendable { - // 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 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 _resource ?? Opentelemetry_Proto_Resource_V1_Resource()} - set {_resource = newValue} - } - /// Returns true if `resource` has been explicitly set. - 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() {self._resource = nil} - - /// A list of ScopeSpans that originate from a resource. - public var scopeSpans: [Opentelemetry_Proto_Trace_V1_ScopeSpans] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the resource data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to the data in the "resource" field. It does not apply - /// to the data in the "scope_spans" field which have their own schema_url field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _resource: Opentelemetry_Proto_Resource_V1_Resource? = nil -} - -/// A collection of Spans produced by an InstrumentationScope. -public struct Opentelemetry_Proto_Trace_V1_ScopeSpans: Sendable { - // 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 instrumentation scope information for the spans in this message. - /// Semantically when InstrumentationScope isn't set, it is equivalent with - /// an empty instrumentation scope name (unknown). - public var scope: Opentelemetry_Proto_Common_V1_InstrumentationScope { - get {return _scope ?? Opentelemetry_Proto_Common_V1_InstrumentationScope()} - set {_scope = newValue} - } - /// Returns true if `scope` has been explicitly set. - public var hasScope: Bool {return self._scope != nil} - /// Clears the value of `scope`. Subsequent reads from it will return its default value. - public mutating func clearScope() {self._scope = nil} - - /// A list of Spans that originate from an instrumentation scope. - public var spans: [Opentelemetry_Proto_Trace_V1_Span] = [] - - /// The Schema URL, if known. This is the identifier of the Schema that the span data - /// is recorded in. Notably, the last part of the URL path is the version number of the - /// schema: http[s]://server[:port]/path/. To learn more about Schema URL see - /// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - /// This schema_url applies to all spans and span events in the "spans" field. - public var schemaURL: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _scope: Opentelemetry_Proto_Common_V1_InstrumentationScope? = nil -} - -/// A Span represents a single operation performed by a single component of the system. -/// -/// The next available field id is 17. -public struct Opentelemetry_Proto_Trace_V1_Span: @unchecked Sendable { - // 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. - - /// A unique identifier for a trace. All spans from the same trace share - /// the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR - /// of length other than 16 bytes is considered invalid (empty string in OTLP/JSON - /// is zero-length and thus is also invalid). - /// - /// This field is required. - public var traceID: Data { - get {return _storage._traceID} - set {_uniqueStorage()._traceID = newValue} - } - - /// 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 OR of length - /// other than 8 bytes is considered invalid (empty string in OTLP/JSON - /// is zero-length and thus is also invalid). - /// - /// This field is required. - public var spanID: Data { - get {return _storage._spanID} - set {_uniqueStorage()._spanID = newValue} - } - - /// trace_state conveys information about request position in multiple distributed tracing graphs. - /// It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header - /// See also https://github.com/w3c/distributed-tracing for more details about this field. - public var traceState: String { - get {return _storage._traceState} - set {_uniqueStorage()._traceState = newValue} - } - - /// The `span_id` of this span's parent span. If this is a root span, then this - /// field must be empty. The ID is an 8-byte array. - public var parentSpanID: Data { - get {return _storage._parentSpanID} - set {_uniqueStorage()._parentSpanID = newValue} - } - - /// Flags, a bit field. - /// - /// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace - /// Context specification. To read the 8-bit W3C trace flag, use - /// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. - /// - /// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. - /// - /// Bits 8 and 9 represent the 3 states of whether a span's parent - /// is remote. The states are (unknown, is not remote, is remote). - /// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. - /// To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. - /// - /// When creating span messages, if the message is logically forwarded from another source - /// with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD - /// be copied as-is. If creating from a source that does not have an equivalent flags field - /// (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST - /// be set to zero. - /// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. - /// - /// [Optional]. - public var flags: UInt32 { - get {return _storage._flags} - set {_uniqueStorage()._flags = newValue} - } - - /// A description of the span's operation. - /// - /// For example, the name can be a qualified method name or a file name - /// and a line number where the operation is called. A best practice is to use - /// the same display name at the same call point in an application. - /// This makes it easier to correlate spans in different traces. - /// - /// This field is semantically required to be set to non-empty string. - /// Empty value is equivalent to an unknown span name. - /// - /// This field is required. - public var name: String { - get {return _storage._name} - set {_uniqueStorage()._name = newValue} - } - - /// Distinguishes between spans generated in a particular context. For example, - /// two spans with the same name may be distinguished using `CLIENT` (caller) - /// and `SERVER` (callee) to identify queueing latency associated with the span. - public var kind: Opentelemetry_Proto_Trace_V1_Span.SpanKind { - get {return _storage._kind} - set {_uniqueStorage()._kind = newValue} - } - - /// start_time_unix_nano is the start time of the span. On the client side, this is the time - /// kept by the local machine where the span execution starts. On the server side, this - /// is the time when the server's application handler starts running. - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - /// - /// This field is semantically required and it is expected that end_time >= start_time. - public var startTimeUnixNano: UInt64 { - get {return _storage._startTimeUnixNano} - set {_uniqueStorage()._startTimeUnixNano = newValue} - } - - /// end_time_unix_nano is the end time of the span. On the client side, this is the time - /// kept by the local machine where the span execution ends. On the server side, this - /// is the time when the server application handler stops running. - /// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - /// - /// This field is semantically required and it is expected that end_time >= start_time. - public var endTimeUnixNano: UInt64 { - get {return _storage._endTimeUnixNano} - set {_uniqueStorage()._endTimeUnixNano = newValue} - } - - /// attributes is a collection of key/value pairs. Note, global attributes - /// like server name can be set using the resource API. Examples of attributes: - /// - /// "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" - /// "/http/server_latency": 300 - /// "example.com/myattribute": true - /// "example.com/score": 10.239 - /// - /// The OpenTelemetry API specification further restricts the allowed value types: - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] { - get {return _storage._attributes} - set {_uniqueStorage()._attributes = newValue} - } - - /// dropped_attributes_count is the number of attributes that were discarded. Attributes - /// can be discarded because their keys are too long or because there are too many - /// attributes. If this value is 0, then no attributes were dropped. - public var droppedAttributesCount: UInt32 { - get {return _storage._droppedAttributesCount} - set {_uniqueStorage()._droppedAttributesCount = newValue} - } - - /// events is a collection of Event items. - public var events: [Opentelemetry_Proto_Trace_V1_Span.Event] { - get {return _storage._events} - set {_uniqueStorage()._events = newValue} - } - - /// dropped_events_count is the number of dropped events. If the value is 0, then no - /// events were dropped. - public var droppedEventsCount: UInt32 { - get {return _storage._droppedEventsCount} - set {_uniqueStorage()._droppedEventsCount = newValue} - } - - /// links is a collection of Links, which are references from this span to a span - /// in the same or different trace. - public var links: [Opentelemetry_Proto_Trace_V1_Span.Link] { - get {return _storage._links} - set {_uniqueStorage()._links = newValue} - } - - /// dropped_links_count is the number of dropped links after the maximum size was - /// enforced. If this value is 0, then no links were dropped. - public var droppedLinksCount: UInt32 { - get {return _storage._droppedLinksCount} - set {_uniqueStorage()._droppedLinksCount = newValue} - } - - /// An optional final status for this span. Semantically when Status isn't set, it means - /// span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0). - public var status: Opentelemetry_Proto_Trace_V1_Status { - get {return _storage._status ?? Opentelemetry_Proto_Trace_V1_Status()} - set {_uniqueStorage()._status = newValue} - } - /// Returns true if `status` has been explicitly set. - public var hasStatus: Bool {return _storage._status != nil} - /// Clears the value of `status`. Subsequent reads from it will return its default value. - public mutating func clearStatus() {_uniqueStorage()._status = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// SpanKind is the type of span. Can be used to specify additional relationships between spans - /// in addition to a parent/child relationship. - public enum SpanKind: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// Unspecified. Do NOT use as default. - /// Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. - case unspecified // = 0 - - /// Indicates that the span represents an internal operation within an application, - /// as opposed to an operation happening at the boundaries. Default value. - case `internal` // = 1 - - /// Indicates that the span covers server-side handling of an RPC or other - /// remote network request. - case server // = 2 - - /// Indicates that the span describes a request to some remote service. - case client // = 3 - - /// Indicates that the span describes a producer sending a message to a broker. - /// Unlike CLIENT and SERVER, there is often no direct critical path latency relationship - /// between producer and consumer spans. A PRODUCER span ends when the message was accepted - /// by the broker while the logical processing of the message might span a much longer time. - case producer // = 4 - - /// Indicates that the span describes consumer receiving a message from a broker. - /// Like the PRODUCER kind, there is often no direct critical path latency relationship - /// between producer and consumer spans. - case consumer // = 5 - case UNRECOGNIZED(Int) - - public init() { - self = .unspecified - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .unspecified - case 1: self = .internal - case 2: self = .server - case 3: self = .client - case 4: self = .producer - case 5: self = .consumer - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .unspecified: return 0 - case .internal: return 1 - case .server: return 2 - case .client: return 3 - case .producer: return 4 - case .consumer: return 5 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Trace_V1_Span.SpanKind] = [ - .unspecified, - .internal, - .server, - .client, - .producer, - .consumer, - ] - - } - - /// Event is a time-stamped annotation of the span, consisting of user-supplied - /// text description and key-value pairs. - public struct Event: Sendable { - // 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. - - /// time_unix_nano is the time the event occurred. - public var timeUnixNano: UInt64 = 0 - - /// name of the event. - /// This field is semantically required to be set to non-empty string. - public var name: String = String() - - /// attributes is a collection of attribute key/value pairs on the event. - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// dropped_attributes_count is the number of dropped attributes. If the value is 0, - /// then no attributes were dropped. - public var droppedAttributesCount: UInt32 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - } - - /// A pointer from the current span to another span in the same trace or in a - /// different trace. For example, this can be used in batching operations, - /// where a single batch handler processes multiple requests from different - /// traces or when the handler receives a request from a different project. - public struct Link: @unchecked Sendable { - // 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. - - /// A unique identifier of a trace that this linked span is part of. The ID is a - /// 16-byte array. - public var traceID: Data = Data() - - /// A unique identifier for the linked span. The ID is an 8-byte array. - public var spanID: Data = Data() - - /// The trace_state associated with the link. - public var traceState: String = String() - - /// attributes is a collection of attribute key/value pairs on the link. - /// Attribute keys MUST be unique (it is not allowed to have more than one - /// attribute with the same key). - public var attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - - /// dropped_attributes_count is the number of dropped attributes. If the value is 0, - /// then no attributes were dropped. - public var droppedAttributesCount: UInt32 = 0 - - /// Flags, a bit field. - /// - /// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace - /// Context specification. To read the 8-bit W3C trace flag, use - /// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. - /// - /// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. - /// - /// Bits 8 and 9 represent the 3 states of whether the link is remote. - /// The states are (unknown, is not remote, is remote). - /// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. - /// To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. - /// - /// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. - /// When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. - /// - /// [Optional]. - public var flags: UInt32 = 0 - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - } - - public init() {} - - fileprivate var _storage = _StorageClass.defaultInstance -} - -/// The Status type defines a logical error model that is suitable for different -/// programming environments, including REST APIs and RPC APIs. -public struct Opentelemetry_Proto_Trace_V1_Status: Sendable { - // 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. - - /// A developer-facing human readable error message. - public var message: String = String() - - /// The status code. - public var code: Opentelemetry_Proto_Trace_V1_Status.StatusCode = .unset - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - /// For the semantics of status codes see - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status - public enum StatusCode: SwiftProtobuf.Enum, Swift.CaseIterable { - public typealias RawValue = Int - - /// The default status. - case unset // = 0 - - /// The Span has been validated by an Application developer or Operator to - /// have completed successfully. - case ok // = 1 - - /// The Span contains an error. - case error // = 2 - case UNRECOGNIZED(Int) - - public init() { - self = .unset - } - - public init?(rawValue: Int) { - switch rawValue { - case 0: self = .unset - case 1: self = .ok - case 2: self = .error - default: self = .UNRECOGNIZED(rawValue) - } - } - - public var rawValue: Int { - switch self { - case .unset: return 0 - case .ok: return 1 - case .error: return 2 - case .UNRECOGNIZED(let i): return i - } - } - - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Opentelemetry_Proto_Trace_V1_Status.StatusCode] = [ - .unset, - .ok, - .error, - ] - - } - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.trace.v1" - -extension Opentelemetry_Proto_Trace_V1_SpanFlags: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "SPAN_FLAGS_DO_NOT_USE"), - 255: .same(proto: "SPAN_FLAGS_TRACE_FLAGS_MASK"), - 256: .same(proto: "SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK"), - 512: .same(proto: "SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK"), - ] -} - -extension Opentelemetry_Proto_Trace_V1_TracesData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".TracesData" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_spans"), - ] - - 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.resourceSpans) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceSpans.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceSpans, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_TracesData, rhs: Opentelemetry_Proto_Trace_V1_TracesData) -> Bool { - if lhs.resourceSpans != rhs.resourceSpans {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_ResourceSpans: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ResourceSpans" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "resource"), - 2: .standard(proto: "scope_spans"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._resource) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.scopeSpans) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._resource { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.scopeSpans.isEmpty { - try visitor.visitRepeatedMessageField(value: self.scopeSpans, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_ResourceSpans, rhs: Opentelemetry_Proto_Trace_V1_ResourceSpans) -> Bool { - if lhs._resource != rhs._resource {return false} - if lhs.scopeSpans != rhs.scopeSpans {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_ScopeSpans: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ScopeSpans" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "scope"), - 2: .same(proto: "spans"), - 3: .standard(proto: "schema_url"), - ] - - 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.decodeSingularMessageField(value: &self._scope) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.spans) }() - case 3: try { try decoder.decodeSingularStringField(value: &self.schemaURL) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._scope { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.spans.isEmpty { - try visitor.visitRepeatedMessageField(value: self.spans, fieldNumber: 2) - } - if !self.schemaURL.isEmpty { - try visitor.visitSingularStringField(value: self.schemaURL, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_ScopeSpans, rhs: Opentelemetry_Proto_Trace_V1_ScopeSpans) -> Bool { - if lhs._scope != rhs._scope {return false} - if lhs.spans != rhs.spans {return false} - if lhs.schemaURL != rhs.schemaURL {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_Span: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Span" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "trace_id"), - 2: .standard(proto: "span_id"), - 3: .standard(proto: "trace_state"), - 4: .standard(proto: "parent_span_id"), - 16: .same(proto: "flags"), - 5: .same(proto: "name"), - 6: .same(proto: "kind"), - 7: .standard(proto: "start_time_unix_nano"), - 8: .standard(proto: "end_time_unix_nano"), - 9: .same(proto: "attributes"), - 10: .standard(proto: "dropped_attributes_count"), - 11: .same(proto: "events"), - 12: .standard(proto: "dropped_events_count"), - 13: .same(proto: "links"), - 14: .standard(proto: "dropped_links_count"), - 15: .same(proto: "status"), - ] - - fileprivate class _StorageClass { - var _traceID: Data = Data() - var _spanID: Data = Data() - var _traceState: String = String() - var _parentSpanID: Data = Data() - var _flags: UInt32 = 0 - var _name: String = String() - var _kind: Opentelemetry_Proto_Trace_V1_Span.SpanKind = .unspecified - var _startTimeUnixNano: UInt64 = 0 - var _endTimeUnixNano: UInt64 = 0 - var _attributes: [Opentelemetry_Proto_Common_V1_KeyValue] = [] - var _droppedAttributesCount: UInt32 = 0 - var _events: [Opentelemetry_Proto_Trace_V1_Span.Event] = [] - var _droppedEventsCount: UInt32 = 0 - var _links: [Opentelemetry_Proto_Trace_V1_Span.Link] = [] - var _droppedLinksCount: UInt32 = 0 - var _status: Opentelemetry_Proto_Trace_V1_Status? = nil - - #if swift(>=5.10) - // This property is used as the initial default value for new instances of the type. - // The type itself is protecting the reference to its storage via CoW semantics. - // This will force a copy to be made of this reference when the first mutation occurs; - // hence, it is safe to mark this as `nonisolated(unsafe)`. - static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif - - private init() {} - - init(copying source: _StorageClass) { - _traceID = source._traceID - _spanID = source._spanID - _traceState = source._traceState - _parentSpanID = source._parentSpanID - _flags = source._flags - _name = source._name - _kind = source._kind - _startTimeUnixNano = source._startTimeUnixNano - _endTimeUnixNano = source._endTimeUnixNano - _attributes = source._attributes - _droppedAttributesCount = source._droppedAttributesCount - _events = source._events - _droppedEventsCount = source._droppedEventsCount - _links = source._links - _droppedLinksCount = source._droppedLinksCount - _status = source._status - } - } - - 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() { - // 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.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) }() - case 16: try { try decoder.decodeSingularFixed32Field(value: &_storage._flags) }() - default: break - } - } - } - } - - public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !_storage._traceID.isEmpty { - try visitor.visitSingularBytesField(value: _storage._traceID, fieldNumber: 1) - } - if !_storage._spanID.isEmpty { - try visitor.visitSingularBytesField(value: _storage._spanID, fieldNumber: 2) - } - if !_storage._traceState.isEmpty { - try visitor.visitSingularStringField(value: _storage._traceState, fieldNumber: 3) - } - if !_storage._parentSpanID.isEmpty { - try visitor.visitSingularBytesField(value: _storage._parentSpanID, fieldNumber: 4) - } - if !_storage._name.isEmpty { - try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 5) - } - if _storage._kind != .unspecified { - try visitor.visitSingularEnumField(value: _storage._kind, fieldNumber: 6) - } - if _storage._startTimeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: _storage._startTimeUnixNano, fieldNumber: 7) - } - if _storage._endTimeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: _storage._endTimeUnixNano, fieldNumber: 8) - } - if !_storage._attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._attributes, fieldNumber: 9) - } - if _storage._droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: _storage._droppedAttributesCount, fieldNumber: 10) - } - if !_storage._events.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._events, fieldNumber: 11) - } - if _storage._droppedEventsCount != 0 { - try visitor.visitSingularUInt32Field(value: _storage._droppedEventsCount, fieldNumber: 12) - } - if !_storage._links.isEmpty { - try visitor.visitRepeatedMessageField(value: _storage._links, fieldNumber: 13) - } - if _storage._droppedLinksCount != 0 { - try visitor.visitSingularUInt32Field(value: _storage._droppedLinksCount, fieldNumber: 14) - } - try { if let v = _storage._status { - try visitor.visitSingularMessageField(value: v, fieldNumber: 15) - } }() - if _storage._flags != 0 { - try visitor.visitSingularFixed32Field(value: _storage._flags, fieldNumber: 16) - } - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_Span, rhs: Opentelemetry_Proto_Trace_V1_Span) -> 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._traceID != rhs_storage._traceID {return false} - if _storage._spanID != rhs_storage._spanID {return false} - if _storage._traceState != rhs_storage._traceState {return false} - if _storage._parentSpanID != rhs_storage._parentSpanID {return false} - if _storage._flags != rhs_storage._flags {return false} - if _storage._name != rhs_storage._name {return false} - if _storage._kind != rhs_storage._kind {return false} - if _storage._startTimeUnixNano != rhs_storage._startTimeUnixNano {return false} - if _storage._endTimeUnixNano != rhs_storage._endTimeUnixNano {return false} - if _storage._attributes != rhs_storage._attributes {return false} - if _storage._droppedAttributesCount != rhs_storage._droppedAttributesCount {return false} - if _storage._events != rhs_storage._events {return false} - if _storage._droppedEventsCount != rhs_storage._droppedEventsCount {return false} - if _storage._links != rhs_storage._links {return false} - if _storage._droppedLinksCount != rhs_storage._droppedLinksCount {return false} - if _storage._status != rhs_storage._status {return false} - return true - } - if !storagesAreEqual {return false} - } - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_Span.SpanKind: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "SPAN_KIND_UNSPECIFIED"), - 1: .same(proto: "SPAN_KIND_INTERNAL"), - 2: .same(proto: "SPAN_KIND_SERVER"), - 3: .same(proto: "SPAN_KIND_CLIENT"), - 4: .same(proto: "SPAN_KIND_PRODUCER"), - 5: .same(proto: "SPAN_KIND_CONSUMER"), - ] -} - -extension Opentelemetry_Proto_Trace_V1_Span.Event: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = Opentelemetry_Proto_Trace_V1_Span.protoMessageName + ".Event" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "time_unix_nano"), - 2: .same(proto: "name"), - 3: .same(proto: "attributes"), - 4: .standard(proto: "dropped_attributes_count"), - ] - - 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.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 - } - } - } - - public func traverse(visitor: inout V) throws { - if self.timeUnixNano != 0 { - try visitor.visitSingularFixed64Field(value: self.timeUnixNano, fieldNumber: 1) - } - if !self.name.isEmpty { - try visitor.visitSingularStringField(value: self.name, fieldNumber: 2) - } - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 3) - } - if self.droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: self.droppedAttributesCount, fieldNumber: 4) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_Span.Event, rhs: Opentelemetry_Proto_Trace_V1_Span.Event) -> Bool { - if lhs.timeUnixNano != rhs.timeUnixNano {return false} - if lhs.name != rhs.name {return false} - if lhs.attributes != rhs.attributes {return false} - if lhs.droppedAttributesCount != rhs.droppedAttributesCount {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_Span.Link: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = Opentelemetry_Proto_Trace_V1_Span.protoMessageName + ".Link" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "trace_id"), - 2: .standard(proto: "span_id"), - 3: .standard(proto: "trace_state"), - 4: .same(proto: "attributes"), - 5: .standard(proto: "dropped_attributes_count"), - 6: .same(proto: "flags"), - ] - - 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.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) }() - case 6: try { try decoder.decodeSingularFixed32Field(value: &self.flags) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.traceID.isEmpty { - try visitor.visitSingularBytesField(value: self.traceID, fieldNumber: 1) - } - if !self.spanID.isEmpty { - try visitor.visitSingularBytesField(value: self.spanID, fieldNumber: 2) - } - if !self.traceState.isEmpty { - try visitor.visitSingularStringField(value: self.traceState, fieldNumber: 3) - } - if !self.attributes.isEmpty { - try visitor.visitRepeatedMessageField(value: self.attributes, fieldNumber: 4) - } - if self.droppedAttributesCount != 0 { - try visitor.visitSingularUInt32Field(value: self.droppedAttributesCount, fieldNumber: 5) - } - if self.flags != 0 { - try visitor.visitSingularFixed32Field(value: self.flags, fieldNumber: 6) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_Span.Link, rhs: Opentelemetry_Proto_Trace_V1_Span.Link) -> Bool { - if lhs.traceID != rhs.traceID {return false} - if lhs.spanID != rhs.spanID {return false} - if lhs.traceState != rhs.traceState {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.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_Status: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".Status" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .same(proto: "message"), - 3: .same(proto: "code"), - ] - - 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 2: try { try decoder.decodeSingularStringField(value: &self.message) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self.code) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.message.isEmpty { - try visitor.visitSingularStringField(value: self.message, fieldNumber: 2) - } - if self.code != .unset { - try visitor.visitSingularEnumField(value: self.code, fieldNumber: 3) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Trace_V1_Status, rhs: Opentelemetry_Proto_Trace_V1_Status) -> Bool { - if lhs.message != rhs.message {return false} - if lhs.code != rhs.code {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Trace_V1_Status.StatusCode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "STATUS_CODE_UNSET"), - 1: .same(proto: "STATUS_CODE_OK"), - 2: .same(proto: "STATUS_CODE_ERROR"), - ] -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/trace_service.pb.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/proto/trace_service.pb.swift deleted file mode 100644 index 3be4943b..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/proto/trace_service.pb.swift +++ /dev/null @@ -1,223 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// swiftlint:disable all -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: opentelemetry/proto/collector/trace/v1/trace_service.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2019, 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 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 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 {} - typealias Version = _2 -} - -public struct Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest: Sendable { - // 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. - - /// An array of ResourceSpans. - /// For data coming from a single resource this array will typically contain one - /// element. Intermediary nodes (such as OpenTelemetry Collector) that receive - /// data from multiple origins typically batch the data before forwarding further and - /// in that case this array will contain multiple elements. - public var resourceSpans: [Opentelemetry_Proto_Trace_V1_ResourceSpans] = [] - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -public struct Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse: Sendable { - // 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 details of a partially successful export request. - /// - /// If the request is only partially accepted - /// (i.e. when the server accepts only parts of the data and rejects the rest) - /// the server MUST initialize the `partial_success` field and MUST - /// set the `rejected_` with the number of items it rejected. - /// - /// Servers MAY also make use of the `partial_success` field to convey - /// warnings/suggestions to senders even when the request was fully accepted. - /// In such cases, the `rejected_` MUST have a value of `0` and - /// the `error_message` MUST be non-empty. - /// - /// A `partial_success` message with an empty value (rejected_ = 0 and - /// `error_message` = "") is equivalent to it not being set/present. Senders - /// SHOULD interpret it the same way as in the full success case. - public var partialSuccess: Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess { - get {return _partialSuccess ?? Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess()} - set {_partialSuccess = newValue} - } - /// Returns true if `partialSuccess` has been explicitly set. - public var hasPartialSuccess: Bool {return self._partialSuccess != nil} - /// Clears the value of `partialSuccess`. Subsequent reads from it will return its default value. - public mutating func clearPartialSuccess() {self._partialSuccess = nil} - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} - - fileprivate var _partialSuccess: Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess? = nil -} - -public struct Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess: Sendable { - // 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 number of rejected spans. - /// - /// A `rejected_` field holding a `0` value indicates that the - /// request was fully accepted. - public var rejectedSpans: Int64 = 0 - - /// A developer-facing human-readable message in English. It should be used - /// either to explain why the server rejected parts of the data during a partial - /// success or to convey warnings/suggestions during a full success. The message - /// should offer guidance on how users can address such issues. - /// - /// error_message is an optional field. An error_message with an empty value - /// is equivalent to it not being set. - public var errorMessage: String = String() - - public var unknownFields = SwiftProtobuf.UnknownStorage() - - public init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "opentelemetry.proto.collector.trace.v1" - -extension Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportTraceServiceRequest" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "resource_spans"), - ] - - 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.resourceSpans) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if !self.resourceSpans.isEmpty { - try visitor.visitRepeatedMessageField(value: self.resourceSpans, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, rhs: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest) -> Bool { - if lhs.resourceSpans != rhs.resourceSpans {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportTraceServiceResponse" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "partial_success"), - ] - - 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.decodeSingularMessageField(value: &self._partialSuccess) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._partialSuccess { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse, rhs: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse) -> Bool { - if lhs._partialSuccess != rhs._partialSuccess {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".ExportTracePartialSuccess" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "rejected_spans"), - 2: .standard(proto: "error_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 { try decoder.decodeSingularInt64Field(value: &self.rejectedSpans) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() - default: break - } - } - } - - public func traverse(visitor: inout V) throws { - if self.rejectedSpans != 0 { - try visitor.visitSingularInt64Field(value: self.rejectedSpans, fieldNumber: 1) - } - if !self.errorMessage.isEmpty { - try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - public static func ==(lhs: Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess, rhs: Opentelemetry_Proto_Collector_Trace_V1_ExportTracePartialSuccess) -> Bool { - if lhs.rejectedSpans != rhs.rejectedSpans {return false} - if lhs.errorMessage != rhs.errorMessage {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/trace/OtlpSpan.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/trace/OtlpSpan.swift deleted file mode 100644 index b5d47366..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/trace/OtlpSpan.swift +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -// Model class -public struct OtlpSpan: Codable { - var resourceSpans: [ResourceSpan]? - - struct ResourceSpan: Codable { - var resource: Resource? - var scopeSpans: [scopeSpan]? - - struct Resource: Codable { - var attributes: [Attribute]? - } - - struct scopeSpan: Codable { - var instrumentationScope: InstrumentationScope? - var spans: [Span]? - - struct InstrumentationScope: Codable { - var name: String? - var version: String? - } - - struct Span: Codable { - var traceId: String? - var spanId: String? - var name: String? - var kind: String? - var startTimeUnixNano: String? - var endTimeUnixNano: String? - var attributes: [Attribute]? - var status: SpanStatus? - - struct SpanStatus: Codable { - var status: String? - } - } - } - } -} - -public struct Attribute: Codable { - var key: String? - var value: Value? - - public struct Value: Codable { - var stringValue: String? - var boolValue: Bool? - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/trace/SpanAdapter.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/trace/SpanAdapter.swift deleted file mode 100644 index 6e540b12..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/trace/SpanAdapter.swift +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public enum SpanAdapter { - public static func toProtoResourceSpans(spanDataList: [SpanData]) -> [Opentelemetry_Proto_Trace_V1_ResourceSpans] { - let resourceAndScopeMap = groupByResourceAndScope(spanDataList: spanDataList) - var resourceSpans = [Opentelemetry_Proto_Trace_V1_ResourceSpans]() - resourceAndScopeMap.forEach { resMap in - var scopeSpans = [Opentelemetry_Proto_Trace_V1_ScopeSpans]() - resMap.value.forEach { instScope in - var protoInst = Opentelemetry_Proto_Trace_V1_ScopeSpans() - protoInst.scope = CommonAdapter.toProtoInstrumentationScope(instrumentationScopeInfo: instScope.key) - instScope.value.forEach { - protoInst.spans.append($0) - } - scopeSpans.append(protoInst) - } - - var resourceSpan = Opentelemetry_Proto_Trace_V1_ResourceSpans() - resourceSpan.resource = ResourceAdapter.toProtoResource(resource: resMap.key) - resourceSpan.scopeSpans.append(contentsOf: scopeSpans) - resourceSpans.append(resourceSpan) - } - return resourceSpans - } - - private static func groupByResourceAndScope(spanDataList: [SpanData]) -> [Resource: [InstrumentationScopeInfo: [Opentelemetry_Proto_Trace_V1_Span]]] { - var result = [Resource: [InstrumentationScopeInfo: [Opentelemetry_Proto_Trace_V1_Span]]]() - spanDataList.forEach { - result[$0.resource, default: [InstrumentationScopeInfo: [Opentelemetry_Proto_Trace_V1_Span]]()][$0.instrumentationScope, default: [Opentelemetry_Proto_Trace_V1_Span]()] - .append(toProtoSpan(spanData: $0)) - } - return result - } - - public static func toProtoSpan(spanData: SpanData) -> Opentelemetry_Proto_Trace_V1_Span { - var protoSpan = Opentelemetry_Proto_Trace_V1_Span() - protoSpan.traceID = TraceProtoUtils.toProtoTraceId(traceId: spanData.traceId) - protoSpan.spanID = TraceProtoUtils.toProtoSpanId(spanId: spanData.spanId) - if let parentId = spanData.parentSpanId { - protoSpan.parentSpanID = TraceProtoUtils.toProtoSpanId(spanId: parentId) - } - protoSpan.name = spanData.name - protoSpan.kind = toProtoSpanKind(kind: spanData.kind) - protoSpan.startTimeUnixNano = spanData.startTime.timeIntervalSince1970.toNanoseconds - protoSpan.endTimeUnixNano = spanData.endTime.timeIntervalSince1970.toNanoseconds - spanData.attributes.forEach { - protoSpan.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - protoSpan.droppedAttributesCount = UInt32(spanData.totalAttributeCount - spanData.attributes.count) - spanData.events.forEach { - protoSpan.events.append(toProtoSpanEvent(event: $0)) - } - protoSpan.droppedEventsCount = UInt32(spanData.totalRecordedEvents - spanData.events.count) - - spanData.links.forEach { - protoSpan.links.append(toProtoSpanLink(link: $0)) - } - protoSpan.droppedLinksCount = UInt32(spanData.totalRecordedLinks - spanData.links.count) - protoSpan.status = toStatusProto(status: spanData.status) - return protoSpan - } - - public static func toProtoSpanKind(kind: SpanKind) -> Opentelemetry_Proto_Trace_V1_Span.SpanKind { - switch kind { - case .internal: - return Opentelemetry_Proto_Trace_V1_Span.SpanKind.internal - case .server: - return Opentelemetry_Proto_Trace_V1_Span.SpanKind.server - case .client: - return Opentelemetry_Proto_Trace_V1_Span.SpanKind.client - case .producer: - return Opentelemetry_Proto_Trace_V1_Span.SpanKind.producer - case .consumer: - return Opentelemetry_Proto_Trace_V1_Span.SpanKind.consumer - } - } - - public static func toProtoSpanEvent(event: SpanData.Event) -> Opentelemetry_Proto_Trace_V1_Span.Event { - var protoEvent = Opentelemetry_Proto_Trace_V1_Span.Event() - protoEvent.name = event.name - protoEvent.timeUnixNano = event.timestamp.timeIntervalSince1970.toNanoseconds - event.attributes.forEach { - protoEvent.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - return protoEvent - } - - public static func toProtoSpanLink(link: SpanData.Link) -> Opentelemetry_Proto_Trace_V1_Span.Link { - var protoLink = Opentelemetry_Proto_Trace_V1_Span.Link() - protoLink.traceID = TraceProtoUtils.toProtoTraceId(traceId: link.context.traceId) - protoLink.spanID = TraceProtoUtils.toProtoSpanId(spanId: link.context.spanId) - link.attributes.forEach { - protoLink.attributes.append(CommonAdapter.toProtoAttribute(key: $0.key, attributeValue: $0.value)) - } - return protoLink - } - - public static func toStatusProto(status: Status) -> Opentelemetry_Proto_Trace_V1_Status { - var statusProto = Opentelemetry_Proto_Trace_V1_Status() - switch status { - case .ok: - statusProto.code = .ok - case .unset: - statusProto.code = .unset - case let .error(description): - statusProto.code = .error - statusProto.message = description - } - return statusProto - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/trace/utils/TraceProtoUtils.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/trace/utils/TraceProtoUtils.swift deleted file mode 100644 index 4fa3fdc3..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/trace/utils/TraceProtoUtils.swift +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import SwiftProtobuf - -enum TraceProtoUtils { - static func toProtoSpanId(spanId: SpanId) -> Data { - var spanIdData = Data(count: SpanId.size) - spanId.copyBytesTo(dest: &spanIdData, destOffset: 0) - return spanIdData - } - - static func toProtoTraceId(traceId: TraceId) -> Data { - var traceIdData = Data(count: TraceId.size) - traceId.copyBytesTo(dest: &traceIdData, destOffset: 0) - return traceIdData - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/logs/OtlpLogExporter.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/logs/OtlpLogExporter.swift deleted file mode 100644 index b43dd24b..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/logs/OtlpLogExporter.swift +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import GRPC -import Logging -import NIO -import NIOHPACK -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk - -public class OtlpLogExporter: LogRecordExporter { - let channel: GRPCChannel - var logClient: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceNIOClient - let config: OtlpConfiguration - var callOptions: CallOptions - - public init(channel: GRPCChannel, - config: OtlpConfiguration = OtlpConfiguration(), - logger: Logging.Logger = Logging.Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.channel = channel - logClient = Opentelemetry_Proto_Collector_Logs_V1_LogsServiceNIOClient(channel: channel) - self.config = config - let userAgentHeader = (Constants.HTTP.userAgent, Headers.getUserAgentHeader()) - if let headers = envVarHeaders { - var updatedHeaders = headers - updatedHeaders.append(userAgentHeader) - callOptions = CallOptions(customMetadata: HPACKHeaders(updatedHeaders), logger: logger) - } else if let headers = config.headers { - var updatedHeaders = headers - updatedHeaders.append(userAgentHeader) - callOptions = CallOptions(customMetadata: HPACKHeaders(updatedHeaders), logger: logger) - } else { - var headers = [(String, String)]() - headers.append(userAgentHeader) - callOptions = CallOptions(customMetadata: HPACKHeaders(headers), logger: logger) - } - } - - public func export(logRecords: [ReadableLogRecord], explicitTimeout: TimeInterval? = nil) -> ExportResult { - let logRequest = Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest.with { request in - request.resourceLogs = LogRecordAdapter.toProtoResourceRecordLog(logRecordList: logRecords) - } - let timeout = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, config.timeout) - if timeout > 0 { - callOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(timeout.toNanoseconds))) - } - - let export = logClient.export(logRequest, callOptions: callOptions) - do { - _ = try export.response.wait() - return .success - } catch { - return .failure - } - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) { - _ = channel.close() - } - - public func forceFlush(explicitTimeout: TimeInterval? = nil) -> ExportResult { - .success - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/metric/OtlpMetricExporter.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/metric/OtlpMetricExporter.swift deleted file mode 100644 index 26c0b103..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/metric/OtlpMetricExporter.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import GRPC -import Logging -import NIO -import NIOHPACK -import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk - -public class OtlpMetricExporter: MetricExporter { - public func getAggregationTemporality(for instrument: OpenTelemetrySdk.InstrumentType) -> OpenTelemetrySdk.AggregationTemporality { - return aggregationTemporalitySelector.getAggregationTemporality(for: instrument) - } - - let channel: GRPCChannel - var metricClient: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceNIOClient - let config: OtlpConfiguration - var callOptions: CallOptions? - var aggregationTemporalitySelector: AggregationTemporalitySelector - var defaultAggregationSelector: DefaultAggregationSelector - - public init(channel: GRPCChannel, config: OtlpConfiguration = OtlpConfiguration(), aggregationTemporalitySelector: AggregationTemporalitySelector = AggregationTemporality.alwaysCumulative(), - defaultAggregationSelector: DefaultAggregationSelector = AggregationSelector.instance, - logger: Logging.Logger = Logging.Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }), envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.defaultAggregationSelector = defaultAggregationSelector - self.aggregationTemporalitySelector = aggregationTemporalitySelector - self.channel = channel - self.config = config - metricClient = Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceNIOClient(channel: self.channel) - if let headers = envVarHeaders { - callOptions = CallOptions(customMetadata: HPACKHeaders(headers), logger: logger) - } else if let headers = config.headers { - callOptions = CallOptions(customMetadata: HPACKHeaders(headers), logger: logger) - } else { - callOptions = CallOptions(logger: logger) - } - } - - public func export(metrics: [OpenTelemetrySdk.MetricData]) -> OpenTelemetrySdk.ExportResult { - let exportRequest = Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest.with { - $0.resourceMetrics = MetricsAdapter.toProtoResourceMetrics(metricData: metrics) - } - if config.timeout > 0 { - metricClient.defaultCallOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(config.timeout.toNanoseconds))) - } - let export = metricClient.export(exportRequest, callOptions: callOptions) - do { - _ = try export.response.wait() - return .success - } catch { - return .failure - } - } - - public func flush() -> OpenTelemetrySdk.ExportResult { - return .success - } - - public func shutdown() -> OpenTelemetrySdk.ExportResult { - _ = channel.close() - - return .success - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/logs_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/logs_service.grpc.swift deleted file mode 100644 index 02050427..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/logs_service.grpc.swift +++ /dev/null @@ -1,319 +0,0 @@ -// -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the protocol buffer compiler. -// Source: opentelemetry/proto/collector/logs/v1/logs_service.proto -// -import GRPC -import NIO -import NIOConcurrencyHelpers -import SwiftProtobuf -import OpenTelemetryProtocolExporterCommon - -/// 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_LogsServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(*, deprecated) -extension Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClient: @unchecked Sendable {} - -@available(*, deprecated, renamed: "Opentelemetry_Proto_Collector_Logs_V1_LogsServiceNIOClient") -public final class Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClient: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol { - private let lock = Lock() - private var _defaultCallOptions: CallOptions - private var _interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? - public let channel: GRPCChannel - public var defaultCallOptions: CallOptions { - get { self.lock.withLock { return self._defaultCallOptions } } - set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } - } - public var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? { - get { self.lock.withLock { return self._interceptors } } - set { self.lock.withLockVoid { self._interceptors = newValue } } - } - - /// 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. - /// - 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 - } -} - -public struct Opentelemetry_Proto_Collector_Logs_V1_LogsServiceNIOClient: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientProtocol { - public var 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. - /// - 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 - } -} - -/// 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). -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncClientProtocol: GRPCClient { - static var serviceDescriptor: GRPCServiceDescriptor { get } - var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? { get } - - func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, - callOptions: CallOptions? - ) -> GRPCAsyncUnaryCall -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncClientProtocol { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientMetadata.serviceDescriptor - } - - public var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? { - return nil - } - - public func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, - callOptions: CallOptions? = nil - ) -> GRPCAsyncUnaryCall { - return self.makeAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncClientProtocol { - public func export( - _ request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, - callOptions: CallOptions? = nil - ) async throws -> Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse { - return try await self.performAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public struct Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncClient: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncClientProtocol { - public var channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? - - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors - } -} - -public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when invoking 'export'. - func makeExportInterceptors() -> [ClientInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "LogsService", - fullName: "opentelemetry.proto.collector.logs.v1.LogsService", - methods: [ - Opentelemetry_Proto_Collector_Logs_V1_LogsServiceClientMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.logs.v1.LogsService/Export", - type: GRPCCallType.unary - ) - } -} - -/// 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: Substring { - return Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerMetadata.serviceDescriptor.fullName[...] - } - - /// 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 handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return UnaryServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - userFunction: self.export(request:context:) - ) - - default: - return nil - } - } -} - -/// 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 implement a server, implement an object which conforms to this protocol. -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncProvider: CallHandlerProvider, Sendable { - static var serviceDescriptor: GRPCServiceDescriptor { get } - 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: GRPCAsyncServerCallContext - ) async throws -> Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Logs_V1_LogsServiceAsyncProvider { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerMetadata.serviceDescriptor - } - - public var serviceName: Substring { - return Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerMetadata.serviceDescriptor.fullName[...] - } - - public var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerInterceptorFactoryProtocol? { - return nil - } - - public func handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return GRPCAsyncServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - wrapping: { try await self.export(request: $0, context: $1) } - ) - - default: - return nil - } - } -} - -public protocol Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when handling 'export'. - /// Defaults to calling `self.makeInterceptors()`. - func makeExportInterceptors() -> [ServerInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "LogsService", - fullName: "opentelemetry.proto.collector.logs.v1.LogsService", - methods: [ - Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.logs.v1.LogsService/Export", - type: GRPCCallType.unary - ) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/metrics_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/metrics_service.grpc.swift deleted file mode 100644 index ffcef573..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/metrics_service.grpc.swift +++ /dev/null @@ -1,319 +0,0 @@ -// -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the protocol buffer compiler. -// Source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto -// -import GRPC -import NIO -import NIOConcurrencyHelpers -import SwiftProtobuf -import OpenTelemetryProtocolExporterCommon - -/// 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_MetricsServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(*, deprecated) -extension Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient: @unchecked Sendable {} - -@available(*, deprecated, renamed: "Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceNIOClient") -public final class Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClient: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol { - private let lock = Lock() - private var _defaultCallOptions: CallOptions - private var _interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? - public let channel: GRPCChannel - public var defaultCallOptions: CallOptions { - get { self.lock.withLock { return self._defaultCallOptions } } - set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } - } - public var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? { - get { self.lock.withLock { return self._interceptors } } - set { self.lock.withLockVoid { self._interceptors = newValue } } - } - - /// 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. - /// - 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 - } -} - -public struct Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceNIOClient: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientProtocol { - public var 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. - /// - 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 - } -} - -/// 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. -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncClientProtocol: GRPCClient { - static var serviceDescriptor: GRPCServiceDescriptor { get } - var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? { get } - - func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, - callOptions: CallOptions? - ) -> GRPCAsyncUnaryCall -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncClientProtocol { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientMetadata.serviceDescriptor - } - - public var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? { - return nil - } - - public func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, - callOptions: CallOptions? = nil - ) -> GRPCAsyncUnaryCall { - return self.makeAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncClientProtocol { - public func export( - _ request: Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest, - callOptions: CallOptions? = nil - ) async throws -> Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse { - return try await self.performAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public struct Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncClient: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncClientProtocol { - public var channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? - - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors - } -} - -public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when invoking 'export'. - func makeExportInterceptors() -> [ClientInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "MetricsService", - fullName: "opentelemetry.proto.collector.metrics.v1.MetricsService", - methods: [ - Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceClientMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", - type: GRPCCallType.unary - ) - } -} - -/// 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: Substring { - return Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerMetadata.serviceDescriptor.fullName[...] - } - - /// 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 handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return UnaryServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - userFunction: self.export(request:context:) - ) - - default: - return nil - } - } -} - -/// 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 implement a server, implement an object which conforms to this protocol. -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncProvider: CallHandlerProvider, Sendable { - static var serviceDescriptor: GRPCServiceDescriptor { get } - 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: GRPCAsyncServerCallContext - ) async throws -> Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceResponse -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceAsyncProvider { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerMetadata.serviceDescriptor - } - - public var serviceName: Substring { - return Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerMetadata.serviceDescriptor.fullName[...] - } - - public var interceptors: Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerInterceptorFactoryProtocol? { - return nil - } - - public func handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return GRPCAsyncServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - wrapping: { try await self.export(request: $0, context: $1) } - ) - - default: - return nil - } - } -} - -public protocol Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when handling 'export'. - /// Defaults to calling `self.makeInterceptors()`. - func makeExportInterceptors() -> [ServerInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "MetricsService", - fullName: "opentelemetry.proto.collector.metrics.v1.MetricsService", - methods: [ - Opentelemetry_Proto_Collector_Metrics_V1_MetricsServiceServerMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", - type: GRPCCallType.unary - ) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/profiles_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/profiles_service.grpc.swift deleted file mode 100644 index a40f8005..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/profiles_service.grpc.swift +++ /dev/null @@ -1,315 +0,0 @@ -// -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the protocol buffer compiler. -// Source: opentelemetry/proto/collector/profiles/v1development/profiles_service.proto -// -import GRPC -import NIO -import NIOConcurrencyHelpers -import SwiftProtobuf -import OpenTelemetryProtocolExporterCommon - -/// Service that can be used to push profiles between one Application instrumented with -/// OpenTelemetry and a collector, or between a collector and a central collector. -/// -/// Usage: instantiate `Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClient`, then call methods of this protocol to make API calls. -public protocol Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientProtocol: GRPCClient { - var serviceName: String { get } - var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? { get } - - func export( - _ request: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest, - callOptions: CallOptions? - ) -> UnaryCall -} - -extension Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientProtocol { - public var serviceName: String { - return "opentelemetry.proto.collector.profiles.v1development.ProfilesService" - } - - /// 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_Profiles_V1development_ExportProfilesServiceRequest, - callOptions: CallOptions? = nil - ) -> UnaryCall { - return self.makeUnaryCall( - path: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(*, deprecated) -extension Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClient: @unchecked Sendable {} - -@available(*, deprecated, renamed: "Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceNIOClient") -public final class Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClient: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientProtocol { - private let lock = Lock() - private var _defaultCallOptions: CallOptions - private var _interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? - public let channel: GRPCChannel - public var defaultCallOptions: CallOptions { - get { self.lock.withLock { return self._defaultCallOptions } } - set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } - } - public var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? { - get { self.lock.withLock { return self._interceptors } } - set { self.lock.withLockVoid { self._interceptors = newValue } } - } - - /// Creates a client for the opentelemetry.proto.collector.profiles.v1development.ProfilesService service. - /// - /// - Parameters: - /// - channel: `GRPCChannel` to the service host. - /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. - /// - interceptors: A factory providing interceptors for each RPC. - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self._defaultCallOptions = defaultCallOptions - self._interceptors = interceptors - } -} - -public struct Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceNIOClient: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientProtocol { - public var channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? - - /// Creates a client for the opentelemetry.proto.collector.profiles.v1development.ProfilesService service. - /// - /// - Parameters: - /// - channel: `GRPCChannel` to the service host. - /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. - /// - interceptors: A factory providing interceptors for each RPC. - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors - } -} - -/// Service that can be used to push profiles between one Application instrumented with -/// OpenTelemetry and a collector, or between a collector and a central collector. -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncClientProtocol: GRPCClient { - static var serviceDescriptor: GRPCServiceDescriptor { get } - var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? { get } - - func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest, - callOptions: CallOptions? - ) -> GRPCAsyncUnaryCall -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncClientProtocol { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientMetadata.serviceDescriptor - } - - public var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? { - return nil - } - - public func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest, - callOptions: CallOptions? = nil - ) -> GRPCAsyncUnaryCall { - return self.makeAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncClientProtocol { - public func export( - _ request: Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceRequest, - callOptions: CallOptions? = nil - ) async throws -> Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceResponse { - return try await self.performAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public struct Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncClient: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncClientProtocol { - public var channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? - - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors - } -} - -public protocol Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when invoking 'export'. - func makeExportInterceptors() -> [ClientInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "ProfilesService", - fullName: "opentelemetry.proto.collector.profiles.v1development.ProfilesService", - methods: [ - Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceClientMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.profiles.v1development.ProfilesService/Export", - type: GRPCCallType.unary - ) - } -} - -/// Service that can be used to push profiles 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_Profiles_V1development_ProfilesServiceProvider: CallHandlerProvider { - var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerInterceptorFactoryProtocol? { 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_Profiles_V1development_ExportProfilesServiceRequest, context: StatusOnlyCallContext) -> EventLoopFuture -} - -extension Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceProvider { - public var serviceName: Substring { - return Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerMetadata.serviceDescriptor.fullName[...] - } - - /// 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 handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return UnaryServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - userFunction: self.export(request:context:) - ) - - default: - return nil - } - } -} - -/// Service that can be used to push profiles between one Application instrumented with -/// OpenTelemetry and a collector, or between a collector and a central collector. -/// -/// To implement a server, implement an object which conforms to this protocol. -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncProvider: CallHandlerProvider, Sendable { - static var serviceDescriptor: GRPCServiceDescriptor { get } - var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerInterceptorFactoryProtocol? { 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_Profiles_V1development_ExportProfilesServiceRequest, - context: GRPCAsyncServerCallContext - ) async throws -> Opentelemetry_Proto_Collector_Profiles_V1development_ExportProfilesServiceResponse -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceAsyncProvider { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerMetadata.serviceDescriptor - } - - public var serviceName: Substring { - return Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerMetadata.serviceDescriptor.fullName[...] - } - - public var interceptors: Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerInterceptorFactoryProtocol? { - return nil - } - - public func handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return GRPCAsyncServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - wrapping: { try await self.export(request: $0, context: $1) } - ) - - default: - return nil - } - } -} - -public protocol Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when handling 'export'. - /// Defaults to calling `self.makeInterceptors()`. - func makeExportInterceptors() -> [ServerInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "ProfilesService", - fullName: "opentelemetry.proto.collector.profiles.v1development.ProfilesService", - methods: [ - Opentelemetry_Proto_Collector_Profiles_V1development_ProfilesServiceServerMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.profiles.v1development.ProfilesService/Export", - type: GRPCCallType.unary - ) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/trace_service.grpc.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/trace_service.grpc.swift deleted file mode 100644 index c01821fa..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/proto/trace_service.grpc.swift +++ /dev/null @@ -1,319 +0,0 @@ -// -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the protocol buffer compiler. -// Source: opentelemetry/proto/collector/trace/v1/trace_service.proto -// -import GRPC -import NIO -import NIOConcurrencyHelpers -import SwiftProtobuf -import OpenTelemetryProtocolExporterCommon - -/// Service that can be used to push spans between one Application instrumented with -/// OpenTelemetry and a collector, or between a 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_TraceServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(*, deprecated) -extension Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient: @unchecked Sendable {} - -@available(*, deprecated, renamed: "Opentelemetry_Proto_Collector_Trace_V1_TraceServiceNIOClient") -public final class Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol { - private let lock = Lock() - private var _defaultCallOptions: CallOptions - private var _interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? - public let channel: GRPCChannel - public var defaultCallOptions: CallOptions { - get { self.lock.withLock { return self._defaultCallOptions } } - set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } - } - public var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? { - get { self.lock.withLock { return self._interceptors } } - set { self.lock.withLockVoid { self._interceptors = newValue } } - } - - /// 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. - /// - 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 - } -} - -public struct Opentelemetry_Proto_Collector_Trace_V1_TraceServiceNIOClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientProtocol { - public var 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. - /// - 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 - } -} - -/// Service that can be used to push spans between one Application instrumented with -/// OpenTelemetry and a collector, or between a collector and a central collector (in this -/// case spans are sent/received to/from multiple Applications). -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncClientProtocol: GRPCClient { - static var serviceDescriptor: GRPCServiceDescriptor { get } - var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? { get } - - func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, - callOptions: CallOptions? - ) -> GRPCAsyncUnaryCall -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncClientProtocol { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientMetadata.serviceDescriptor - } - - public var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? { - return nil - } - - public func makeExportCall( - _ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, - callOptions: CallOptions? = nil - ) -> GRPCAsyncUnaryCall { - return self.makeAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncClientProtocol { - public func export( - _ request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, - callOptions: CallOptions? = nil - ) async throws -> Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse { - return try await self.performAsyncUnaryCall( - path: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientMetadata.Methods.export.path, - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeExportInterceptors() ?? [] - ) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public struct Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncClientProtocol { - public var channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? - - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors - } -} - -public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when invoking 'export'. - func makeExportInterceptors() -> [ClientInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "TraceService", - fullName: "opentelemetry.proto.collector.trace.v1.TraceService", - methods: [ - Opentelemetry_Proto_Collector_Trace_V1_TraceServiceClientMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.trace.v1.TraceService/Export", - type: GRPCCallType.unary - ) - } -} - -/// Service that can be used to push spans between one Application instrumented with -/// OpenTelemetry and a collector, or between a 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: Substring { - return Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerMetadata.serviceDescriptor.fullName[...] - } - - /// 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 handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return UnaryServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - userFunction: self.export(request:context:) - ) - - default: - return nil - } - } -} - -/// Service that can be used to push spans between one Application instrumented with -/// OpenTelemetry and a collector, or between a collector and a central collector (in this -/// case spans are sent/received to/from multiple Applications). -/// -/// To implement a server, implement an object which conforms to this protocol. -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncProvider: CallHandlerProvider, Sendable { - static var serviceDescriptor: GRPCServiceDescriptor { get } - 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: GRPCAsyncServerCallContext - ) async throws -> Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension Opentelemetry_Proto_Collector_Trace_V1_TraceServiceAsyncProvider { - public static var serviceDescriptor: GRPCServiceDescriptor { - return Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerMetadata.serviceDescriptor - } - - public var serviceName: Substring { - return Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerMetadata.serviceDescriptor.fullName[...] - } - - public var interceptors: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerInterceptorFactoryProtocol? { - return nil - } - - public func handle( - method name: Substring, - context: CallHandlerContext - ) -> GRPCServerHandlerProtocol? { - switch name { - case "Export": - return GRPCAsyncServerHandler( - context: context, - requestDeserializer: ProtobufDeserializer(), - responseSerializer: ProtobufSerializer(), - interceptors: self.interceptors?.makeExportInterceptors() ?? [], - wrapping: { try await self.export(request: $0, context: $1) } - ) - - default: - return nil - } - } -} - -public protocol Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerInterceptorFactoryProtocol: Sendable { - - /// - Returns: Interceptors to use when handling 'export'. - /// Defaults to calling `self.makeInterceptors()`. - func makeExportInterceptors() -> [ServerInterceptor] -} - -public enum Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerMetadata { - public static let serviceDescriptor = GRPCServiceDescriptor( - name: "TraceService", - fullName: "opentelemetry.proto.collector.trace.v1.TraceService", - methods: [ - Opentelemetry_Proto_Collector_Trace_V1_TraceServiceServerMetadata.Methods.export - ] - ) - - public enum Methods { - public static let export = GRPCMethodDescriptor( - name: "Export", - path: "/opentelemetry.proto.collector.trace.v1.TraceService/Export", - type: GRPCCallType.unary - ) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceExporter.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceExporter.swift deleted file mode 100644 index c9e41510..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceExporter.swift +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import GRPC -import Logging -import NIO -import NIOHPACK -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk - -public class OtlpTraceExporter: SpanExporter { - let channel: GRPCChannel - var traceClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceNIOClient - let config: OtlpConfiguration - var callOptions: CallOptions - - public init(channel: GRPCChannel, config: OtlpConfiguration = OtlpConfiguration(), logger: Logging.Logger = Logging.Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }), envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.channel = channel - traceClient = Opentelemetry_Proto_Collector_Trace_V1_TraceServiceNIOClient(channel: channel) - self.config = config - let userAgentHeader = (Constants.HTTP.userAgent, Headers.getUserAgentHeader()) - if let headers = envVarHeaders { - var updatedHeaders = headers - updatedHeaders.append(userAgentHeader) - callOptions = CallOptions(customMetadata: HPACKHeaders(updatedHeaders), logger: logger) - } else if let headers = config.headers { - var updatedHeaders = headers - updatedHeaders.append(userAgentHeader) - callOptions = CallOptions(customMetadata: HPACKHeaders(updatedHeaders), logger: logger) - } else { - var headers = [(String, String)]() - headers.append(userAgentHeader) - callOptions = CallOptions(customMetadata: HPACKHeaders(headers), logger: logger) - } - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - let exportRequest = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans) - } - let timeout = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, config.timeout) - if timeout > 0 { - callOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(timeout.toNanoseconds))) - } - - let export = traceClient.export(exportRequest, callOptions: callOptions) - - do { - // wait() on the response to stop the program from exiting before the response is received. - _ = try export.response.wait() - return .success - } catch { - return .failure - } - } - - public func flush(explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - return .success - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) { - _ = channel.close() - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceJsonExporter.swift b/Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceJsonExporter.swift deleted file mode 100644 index eb48c6ca..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceJsonExporter.swift +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk -import OpenTelemetryProtocolExporterCommon - -public class OtlpTraceJsonExporter: SpanExporter { - // MARK: - Variables declaration - - private var exportedSpans = [OtlpSpan]() - private var isRunning: Bool = true - - // MARK: - Json Exporter helper methods - - public func getExportedSpans() -> [OtlpSpan] { - exportedSpans - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - guard isRunning else { return .failure } - - let exportRequest = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans) - } - - do { - let jsonData = try exportRequest.jsonUTF8Data() - do { - let span = try JSONDecoder().decode(OtlpSpan.self, from: jsonData) - exportedSpans.append(span) - } catch { - print("Decode Error: \(error)") - } - return .success - } catch { - return .failure - } - } - - public func flush(explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - guard isRunning else { return .failure } - return .success - } - - public func reset() { - exportedSpans.removeAll() - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) { - exportedSpans.removeAll() - isRunning = false - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolHttp/HTTPClient.swift b/Sources/Exporters/OpenTelemetryProtocolHttp/HTTPClient.swift deleted file mode 100644 index 59633e85..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolHttp/HTTPClient.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation - -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -/// Protocol for sending HTTP requests, allowing custom implementations for authentication and other behaviors. -public protocol HTTPClient { - /// Sends an HTTP request and calls the completion handler with the result. - /// - Parameters: - /// - request: The URLRequest to send - /// - completion: Completion handler called with Result - func send(request: URLRequest, - completion: @escaping (Result) -> Void) -} - -/// Default implementation of HTTPClient using URLSession. -public final class BaseHTTPClient: HTTPClient { - private let session: URLSession - - /// Creates a BaseHTTPClient with default ephemeral session configuration. - public convenience init() { - let configuration: URLSessionConfiguration = .ephemeral - // NOTE: RUMM-610 Default behaviour of `.ephemeral` session is to cache requests. - // To not leak requests memory (including their `.httpBody` which may be significant) - // we explicitly opt-out from using cache. This cannot be achieved using `.requestCachePolicy`. - configuration.urlCache = nil - // TODO: RUMM-123 Optimize `URLSessionConfiguration` for good traffic performance - // and move session configuration constants to `PerformancePreset`. - self.init(session: URLSession(configuration: configuration)) - } - - /// Creates a BaseHTTPClient with a custom URLSession. - /// - Parameter session: The URLSession to use for HTTP requests - public init(session: URLSession) { - self.session = session - } - - public func send(request: URLRequest, - completion: @escaping (Result) -> Void) { - let task = session.dataTask(with: request) { data, response, error in - completion(httpClientResult(for: (data, response, error))) - } - task.resume() - } -} - -/// An error returned if `URLSession` response state is inconsistent (like no data, no response and no error). -struct HTTPClientError: Error, CustomStringConvertible { - let description: String -} - -/// Maps `URLSessionDataTask` response to `HTTPClient` response. -func httpClientResult(for taskResult: (Data?, URLResponse?, Error?)) -> Result { - let (_, response, error) = taskResult - - if let error = error { - return .failure(error) - } - - guard let httpResponse = response as? HTTPURLResponse else { - return .failure( - HTTPClientError( - description: "Failed to receive HTTPURLResponse: \(String(describing: response))" - ) - ) - } - - return .success(httpResponse) -} \ No newline at end of file diff --git a/Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift b/Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift deleted file mode 100644 index 772cf2e3..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -// ===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Metrics API open source project -// -// Copyright (c) 2018-2019 Apple Inc. and the Swift Metrics API project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Metrics API project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -// ===----------------------------------------------------------------------===// - -// ===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftNIO project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -// ===----------------------------------------------------------------------===// - -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) - import Darwin -#elseif canImport(Glibc) - import Glibc -#elseif canImport(Musl) - import Musl -#else - #error("Unsupported platform") -#endif - -/// A threading lock based on `libpthread` instead of `libdispatch`. -/// -/// This object provides a lock on top of a single `pthread_mutex_t`. This kind -/// of lock is safe to use with `libpthread`-based threading models, such as the -/// one used by NIO. -final class Lock { - private let mutex: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: 1) - - /// Create a new lock. - public init() { - let err = pthread_mutex_init(mutex, nil) - precondition(err == 0, "pthread_mutex_init failed with error \(err)") - } - - deinit { - let err = pthread_mutex_destroy(self.mutex) - precondition(err == 0, "pthread_mutex_destroy failed with error \(err)") - self.mutex.deallocate() - } - - /// Acquire the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lock() { - let err = pthread_mutex_lock(mutex) - precondition(err == 0, "pthread_mutex_lock failed with error \(err)") - } - - /// Release the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `lock`, to simplify lock handling. - public func unlock() { - let err = pthread_mutex_unlock(mutex) - precondition(err == 0, "pthread_mutex_unlock failed with error \(err)") - } -} - -extension Lock { - /// Acquire the lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withLock(_ body: () throws -> T) rethrows -> T { - lock() - defer { - self.unlock() - } - return try body() - } - - // specialise Void return (for performance) - @inlinable - func withLockVoid(_ body: () throws -> Void) rethrows { - try withLock(body) - } -} - -/// A threading lock based on `libpthread` instead of `libdispatch`. -/// -/// This object provides a lock on top of a single `pthread_mutex_t`. This kind -/// of lock is safe to use with `libpthread`-based threading models, such as the -/// one used by NIO. -final class ReadWriteLock { - private let rwlock: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: 1) - - /// Create a new lock. - public init() { - let err = pthread_rwlock_init(rwlock, nil) - precondition(err == 0, "pthread_rwlock_init failed with error \(err)") - } - - deinit { - let err = pthread_rwlock_destroy(self.rwlock) - precondition(err == 0, "pthread_rwlock_destroy failed with error \(err)") - self.rwlock.deallocate() - } - - /// Acquire a reader lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lockRead() { - let err = pthread_rwlock_rdlock(rwlock) - precondition(err == 0, "pthread_rwlock_rdlock failed with error \(err)") - } - - /// Acquire a writer lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lockWrite() { - let err = pthread_rwlock_wrlock(rwlock) - precondition(err == 0, "pthread_rwlock_wrlock failed with error \(err)") - } - - /// Release the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `lock`, to simplify lock handling. - public func unlock() { - let err = pthread_rwlock_unlock(rwlock) - precondition(err == 0, "pthread_rwlock_unlock failed with error \(err)") - } -} - -extension ReadWriteLock { - /// Acquire the reader lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withReaderLock(_ body: () throws -> T) rethrows -> T { - lockRead() - defer { - self.unlock() - } - return try body() - } - - /// Acquire the writer lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withWriterLock(_ body: () throws -> T) rethrows -> T { - lockWrite() - defer { - self.unlock() - } - return try body() - } - - // specialise Void return (for performance) - @inlinable - func withReaderLockVoid(_ body: () throws -> Void) rethrows { - try withReaderLock(body) - } - - // specialise Void return (for performance) - @inlinable - func withWriterLockVoid(_ body: () throws -> Void) rethrows { - try withWriterLock(body) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolHttp/OtlpHttpExporterBase.swift b/Sources/Exporters/OpenTelemetryProtocolHttp/OtlpHttpExporterBase.swift deleted file mode 100644 index aa769a20..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolHttp/OtlpHttpExporterBase.swift +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -#if canImport(Compression) - import DataCompression -#endif -import Foundation -import OpenTelemetryProtocolExporterCommon -import SwiftProtobuf -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -@available(*, deprecated, renamed: "OtlpHttpExporterBase") -public typealias StableOtlpHTTPExporterBase = OtlpHttpExporterBase - -public class OtlpHttpExporterBase { - let endpoint: URL - let httpClient: HTTPClient - let envVarHeaders: [(String, String)]? - let config: OtlpConfiguration - - // MARK: - Init - - // New initializer with HTTPClient support - public init(endpoint: URL, - config: OtlpConfiguration = OtlpConfiguration(), - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.envVarHeaders = envVarHeaders - self.endpoint = endpoint - self.config = config - self.httpClient = httpClient - } - - // Deprecated initializer for backward compatibility - @available(*, deprecated, message: "Use init(endpoint:config:httpClient:envVarHeaders:) instead") - public init(endpoint: URL, - config: OtlpConfiguration = OtlpConfiguration(), - useSession: URLSession? = nil, - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.envVarHeaders = envVarHeaders - self.endpoint = endpoint - self.config = config - if let providedSession = useSession { - self.httpClient = BaseHTTPClient(session: providedSession) - } else { - self.httpClient = BaseHTTPClient() - } - } - - public func createRequest(body: Message, endpoint: URL) -> URLRequest { - var request = URLRequest(url: endpoint) - - if let headers = envVarHeaders { - headers.forEach { key, value in - request.addValue(value, forHTTPHeaderField: key) - } - - } else if let headers = config.headers { - headers.forEach { key, value in - request.addValue(value, forHTTPHeaderField: key) - } - } - - do { - let rawData = try body.serializedData() - request.httpMethod = "POST" - request.setValue(Headers.getUserAgentHeader(), forHTTPHeaderField: Constants.HTTP.userAgent) - request.setValue("application/x-protobuf", forHTTPHeaderField: "Content-Type") - - var compressedData = rawData - - #if canImport(Compression) - switch config.compression { - case .gzip: - if let data = rawData.gzip() { - compressedData = data - request.setValue("gzip", forHTTPHeaderField: "Content-Encoding") - } - - case .deflate: - if let data = rawData.deflate() { - compressedData = data - request.setValue("deflate", forHTTPHeaderField: "Content-Encoding") - } - - case .none: - break - } - #endif - - // Apply final data. Could be compressed or raw - // but it doesn't matter here - request.httpBody = compressedData - } catch { - print("Error serializing body: \(error)") - } - return request - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) {} -} \ No newline at end of file diff --git a/Sources/Exporters/OpenTelemetryProtocolHttp/logs/OtlpHttpLogExporter.swift b/Sources/Exporters/OpenTelemetryProtocolHttp/logs/OtlpHttpLogExporter.swift deleted file mode 100644 index 850f7bfa..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolHttp/logs/OtlpHttpLogExporter.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk - -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -public func defaultOltpHttpLoggingEndpoint() -> URL { - URL(string: "http://localhost:4318/v1/logs")! -} - -public class OtlpHttpLogExporter: OtlpHttpExporterBase, LogRecordExporter { - var pendingLogRecords: [ReadableLogRecord] = [] - private let exporterLock = Lock() - private var exporterMetrics: ExporterMetrics? - - override public init(endpoint: URL = defaultOltpHttpLoggingEndpoint(), - config: OtlpConfiguration = OtlpConfiguration(), - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - super.init(endpoint: endpoint, - config: config, - httpClient: httpClient, - envVarHeaders: envVarHeaders) - } - - /// A `convenience` constructor to provide support for exporter metric using`StableMeterProvider` type - /// - Parameters: - /// - endpoint: Exporter endpoint injected as dependency - /// - config: Exporter configuration including type of exporter - /// - meterProvider: Injected `StableMeterProvider` for metric - /// - httpClient: Custom HTTPClient implementation - /// - envVarHeaders: Extra header key-values - public convenience init(endpoint: URL = defaultOltpHttpLoggingEndpoint(), - config: OtlpConfiguration = OtlpConfiguration(), - meterProvider: any MeterProvider, - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.init(endpoint: endpoint, config: config, httpClient: httpClient, - envVarHeaders: envVarHeaders) - exporterMetrics = ExporterMetrics(type: "log", - meterProvider: meterProvider, - exporterName: "otlp", - transportName: config.exportAsJson - ? ExporterMetrics.TransporterType.httpJson - : ExporterMetrics.TransporterType.grpc) - } - - public func export(logRecords: [OpenTelemetrySdk.ReadableLogRecord], - explicitTimeout: TimeInterval? = nil) -> OpenTelemetrySdk.ExportResult { - var sendingLogRecords: [ReadableLogRecord] = [] - exporterLock.withLockVoid { - pendingLogRecords.append(contentsOf: logRecords) - sendingLogRecords = pendingLogRecords - pendingLogRecords = [] - } - - let body = - Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest.with { request in - request.resourceLogs = LogRecordAdapter.toProtoResourceRecordLog( - logRecordList: sendingLogRecords) - } - - var request = createRequest(body: body, endpoint: endpoint) - exporterMetrics?.addSeen(value: sendingLogRecords.count) - request.timeoutInterval = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, config.timeout) - httpClient.send(request: request) { [weak self] result in - switch result { - case .success: - self?.exporterMetrics?.addSuccess(value: sendingLogRecords.count) - case let .failure(error): - self?.exporterMetrics?.addFailed(value: sendingLogRecords.count) - self?.exporterLock.withLockVoid { - self?.pendingLogRecords.append(contentsOf: sendingLogRecords) - } - print(error) - } - } - - return .success - } - - public func forceFlush(explicitTimeout: TimeInterval? = nil) -> ExportResult { - flush(explicitTimeout: explicitTimeout) - } - - public func flush(explicitTimeout: TimeInterval? = nil) -> ExportResult { - var exporterResult: ExportResult = .success - var pendingLogRecords: [ReadableLogRecord] = [] - exporterLock.withLockVoid { - pendingLogRecords = self.pendingLogRecords - } - - if !pendingLogRecords.isEmpty { - let body = - Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest.with { request in - request.resourceLogs = LogRecordAdapter.toProtoResourceRecordLog( - logRecordList: pendingLogRecords) - } - let semaphore = DispatchSemaphore(value: 0) - var request = createRequest(body: body, endpoint: endpoint) - request.timeoutInterval = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, config.timeout) - if let headers = envVarHeaders { - headers.forEach { key, value in - request.addValue(value, forHTTPHeaderField: key) - } - } else if let headers = config.headers { - headers.forEach { key, value in - request.addValue(value, forHTTPHeaderField: key) - } - } - httpClient.send(request: request) { [weak self] result in - switch result { - case .success: - self?.exporterMetrics?.addSuccess(value: pendingLogRecords.count) - exporterResult = ExportResult.success - case let .failure(error): - self?.exporterMetrics?.addFailed(value: pendingLogRecords.count) - print(error) - exporterResult = ExportResult.failure - } - semaphore.signal() - } - semaphore.wait() - } - - return exporterResult - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolHttp/metric/OtlpHttpMetricExporter.swift b/Sources/Exporters/OpenTelemetryProtocolHttp/metric/OtlpHttpMetricExporter.swift deleted file mode 100644 index d1a26fcc..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolHttp/metric/OtlpHttpMetricExporter.swift +++ /dev/null @@ -1,171 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk - -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -public func defaultOtlpHttpMetricsEndpoint() -> URL { - URL(string: "http://localhost:4318/v1/metrics")! -} - -@available(*, deprecated, renamed: "defaultOtlpHttpMetricsEndpoint") -public func defaultStableOtlpHTTPMetricsEndpoint() -> URL { - URL(string: "http://localhost:4318/v1/metrics")! -} - -@available(*, deprecated, renamed: "OtlpHttpMetricExporter") -public typealias StableOtlpHTTPMetricExporter = OtlpHttpMetricExporter - -@available(*, deprecated, renamed: "OtlpHttpMetricExporter") -public typealias OtlpHTTPMetricExporter = OtlpHttpMetricExporter - -public class OtlpHttpMetricExporter: OtlpHttpExporterBase, MetricExporter { - var aggregationTemporalitySelector: AggregationTemporalitySelector - var defaultAggregationSelector: DefaultAggregationSelector - - var pendingMetrics: [MetricData] = [] - private let exporterLock = Lock() - private var exporterMetrics: ExporterMetrics? - - // MARK: - Init - - public init(endpoint: URL, config: OtlpConfiguration = OtlpConfiguration(), - aggregationTemporalitySelector: AggregationTemporalitySelector = - AggregationTemporality.alwaysCumulative(), - defaultAggregationSelector: DefaultAggregationSelector = AggregationSelector.instance, - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.aggregationTemporalitySelector = aggregationTemporalitySelector - self.defaultAggregationSelector = defaultAggregationSelector - - super.init(endpoint: endpoint, config: config, httpClient: httpClient, - envVarHeaders: envVarHeaders) - } - - /// A `convenience` constructor to provide support for exporter metric using`StableMeterProvider` type - /// - Parameters: - /// - endpoint: Exporter endpoint injected as dependency - /// - config: Exporter configuration including type of exporter - /// - meterProvider: Injected `StableMeterProvider` for metric - /// - aggregationTemporalitySelector: aggregator - /// - defaultAggregationSelector: default aggregator - /// - httpClient: Custom HTTPClient implementation - /// - envVarHeaders: Extra header key-values - public convenience init(endpoint: URL, - config: OtlpConfiguration = OtlpConfiguration(), - meterProvider: any MeterProvider, - aggregationTemporalitySelector: AggregationTemporalitySelector = - AggregationTemporality.alwaysCumulative(), - defaultAggregationSelector: DefaultAggregationSelector = AggregationSelector - .instance, - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.init(endpoint: endpoint, - config: config, - aggregationTemporalitySelector: aggregationTemporalitySelector, - defaultAggregationSelector: defaultAggregationSelector, - httpClient: httpClient, - envVarHeaders: envVarHeaders) - exporterMetrics = ExporterMetrics(type: "metric", - meterProvider: meterProvider, - exporterName: "otlp", - transportName: config.exportAsJson - ? ExporterMetrics.TransporterType.httpJson - : ExporterMetrics.TransporterType.grpc) - } - - // MARK: - StableMetricsExporter - - public func export(metrics: [MetricData]) -> ExportResult { - var sendingMetrics: [MetricData] = [] - exporterLock.withLockVoid { - pendingMetrics.append(contentsOf: metrics) - sendingMetrics = pendingMetrics - pendingMetrics = [] - } - let body = - Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest.with { - $0.resourceMetrics = MetricsAdapter.toProtoResourceMetrics( - metricData: sendingMetrics) - } - exporterMetrics?.addSeen(value: sendingMetrics.count) - var request = createRequest(body: body, endpoint: endpoint) - request.timeoutInterval = min(TimeInterval.greatestFiniteMagnitude, config.timeout) - httpClient.send(request: request) { [weak self] result in - switch result { - case .success: - self?.exporterMetrics?.addSuccess(value: sendingMetrics.count) - case let .failure(error): - self?.exporterMetrics?.addFailed(value: sendingMetrics.count) - self?.exporterLock.withLockVoid { - self?.pendingMetrics.append(contentsOf: sendingMetrics) - } - print(error) - } - } - - return .success - } - - public func flush() -> ExportResult { - var exporterResult: ExportResult = .success - var pendingMetrics: [MetricData] = [] - exporterLock.withLockVoid { - pendingMetrics = self.pendingMetrics - } - if !pendingMetrics.isEmpty { - let body = - Opentelemetry_Proto_Collector_Metrics_V1_ExportMetricsServiceRequest - .with { - $0.resourceMetrics = MetricsAdapter.toProtoResourceMetrics( - metricData: pendingMetrics) - } - let semaphore = DispatchSemaphore(value: 0) - var request = createRequest(body: body, endpoint: endpoint) - request.timeoutInterval = min(TimeInterval.greatestFiniteMagnitude, config.timeout) - httpClient.send(request: request) { [weak self] result in - switch result { - case .success: - self?.exporterMetrics?.addSuccess(value: pendingMetrics.count) - case let .failure(error): - self?.exporterMetrics?.addFailed(value: pendingMetrics.count) - print(error) - exporterResult = .failure - } - semaphore.signal() - } - semaphore.wait() - } - - return exporterResult - } - - public func shutdown() -> ExportResult { - return .success - } - - // MARK: - AggregationTemporalitySelectorProtocol - - public func getAggregationTemporality( - for instrument: OpenTelemetrySdk.InstrumentType - ) -> OpenTelemetrySdk.AggregationTemporality { - return aggregationTemporalitySelector.getAggregationTemporality( - for: instrument) - } - - // MARK: - DefaultAggregationSelector - - public func getDefaultAggregation( - for instrument: OpenTelemetrySdk.InstrumentType - ) -> OpenTelemetrySdk.Aggregation { - return defaultAggregationSelector.getDefaultAggregation(for: instrument) - } -} diff --git a/Sources/Exporters/OpenTelemetryProtocolHttp/trace/OtlpHttpTraceExporter.swift b/Sources/Exporters/OpenTelemetryProtocolHttp/trace/OtlpHttpTraceExporter.swift deleted file mode 100644 index 73633e89..00000000 --- a/Sources/Exporters/OpenTelemetryProtocolHttp/trace/OtlpHttpTraceExporter.swift +++ /dev/null @@ -1,119 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk - -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -public func defaultOltpHttpTracesEndpoint() -> URL { - URL(string: "http://localhost:4318/v1/traces")! -} - -public class OtlpHttpTraceExporter: OtlpHttpExporterBase, SpanExporter { - var pendingSpans: [SpanData] = [] - - private let exporterLock = Lock() - private var exporterMetrics: ExporterMetrics? - - override public init(endpoint: URL = defaultOltpHttpTracesEndpoint(), - config: OtlpConfiguration = OtlpConfiguration(), - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - super.init(endpoint: endpoint, - config: config, - httpClient: httpClient, - envVarHeaders: envVarHeaders) - } - - /// A `convenience` constructor to provide support for exporter metric using`StableMeterProvider` type - /// - Parameters: - /// - endpoint: Exporter endpoint injected as dependency - /// - config: Exporter configuration including type of exporter - /// - meterProvider: Injected `StableMeterProvider` for metric - /// - httpClient: Custom HTTPClient implementation - /// - envVarHeaders: Extra header key-values - public convenience init(endpoint: URL, - config: OtlpConfiguration, - meterProvider: any MeterProvider, - httpClient: HTTPClient = BaseHTTPClient(), - envVarHeaders: [(String, String)]? = EnvVarHeaders.attributes) { - self.init(endpoint: endpoint, config: config, httpClient: httpClient, - envVarHeaders: envVarHeaders) - exporterMetrics = ExporterMetrics(type: "span", - meterProvider: meterProvider, - exporterName: "otlp", - transportName: config.exportAsJson - ? ExporterMetrics.TransporterType.httpJson - : ExporterMetrics.TransporterType.grpc) - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) - -> SpanExporterResultCode { - var sendingSpans: [SpanData] = [] - exporterLock.withLockVoid { - pendingSpans.append(contentsOf: spans) - sendingSpans = pendingSpans - pendingSpans = [] - } - - let body = - Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans( - spanDataList: sendingSpans) - } - let request = createRequest(body: body, endpoint: endpoint) - exporterMetrics?.addSeen(value: sendingSpans.count) - httpClient.send(request: request) { [weak self] result in - switch result { - case .success: - self?.exporterMetrics?.addSuccess(value: sendingSpans.count) - case let .failure(error): - self?.exporterMetrics?.addFailed(value: sendingSpans.count) - self?.exporterLock.withLockVoid { - self?.pendingSpans.append(contentsOf: sendingSpans) - } - print(error) - } - } - return .success - } - - public func flush(explicitTimeout: TimeInterval? = nil) - -> SpanExporterResultCode { - var resultValue: SpanExporterResultCode = .success - var pendingSpans: [SpanData] = [] - exporterLock.withLockVoid { - pendingSpans = self.pendingSpans - } - if !pendingSpans.isEmpty { - let body = - Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans( - spanDataList: pendingSpans) - } - let semaphore = DispatchSemaphore(value: 0) - let request = createRequest(body: body, endpoint: endpoint) - - httpClient.send(request: request) { [weak self] result in - switch result { - case .success: - self?.exporterMetrics?.addSuccess(value: pendingSpans.count) - case let .failure(error): - self?.exporterMetrics?.addFailed(value: pendingSpans.count) - print(error) - resultValue = .failure - } - semaphore.signal() - } - semaphore.wait() - } - return resultValue - } -} \ No newline at end of file diff --git a/Sources/Exporters/Persistence/Export/DataExportDelay.swift b/Sources/Exporters/Persistence/Export/DataExportDelay.swift deleted file mode 100644 index 6351be7e..00000000 --- a/Sources/Exporters/Persistence/Export/DataExportDelay.swift +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -protocol Delay { - var current: TimeInterval { get } - mutating func decrease() - mutating func increase() -} - -/// Mutable interval used for periodic data exports. -struct DataExportDelay: Delay { - private let defaultDelay: TimeInterval - private let minDelay: TimeInterval - private let maxDelay: TimeInterval - private let changeRate: Double - - private var delay: TimeInterval - - init(performance: ExportPerformancePreset) { - defaultDelay = performance.defaultExportDelay - minDelay = performance.minExportDelay - maxDelay = performance.maxExportDelay - changeRate = performance.exportDelayChangeRate - delay = performance.initialExportDelay - } - - var current: TimeInterval { delay } - - mutating func decrease() { - delay = max(minDelay, delay * (1.0 - changeRate)) - } - - mutating func increase() { - delay = min(delay * (1.0 + changeRate), maxDelay) - } -} diff --git a/Sources/Exporters/Persistence/Export/DataExportStatus.swift b/Sources/Exporters/Persistence/Export/DataExportStatus.swift deleted file mode 100644 index 77c98fd9..00000000 --- a/Sources/Exporters/Persistence/Export/DataExportStatus.swift +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -/// The status of a single export attempt. -struct DataExportStatus { - /// If export needs to be retried (`true`) because its associated data was not delivered but it may succeed - /// in the next attempt (i.e. it failed due to device leaving signal range or a temporary server unavailability occurred). - /// If set to `false` then data associated with the upload should be deleted as it does not need any more export - /// attempts (i.e. the upload succeeded or failed due to unrecoverable client error). - let needsRetry: Bool -} diff --git a/Sources/Exporters/Persistence/Export/DataExportWorker.swift b/Sources/Exporters/Persistence/Export/DataExportWorker.swift deleted file mode 100644 index eb4bee00..00000000 --- a/Sources/Exporters/Persistence/Export/DataExportWorker.swift +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -// a protocol for an exporter of `Data` to which a `DataExportWorker` can delegate persisted -// data export -protocol DataExporter { - func export(data: Data) -> DataExportStatus -} - -// a protocol needed for mocking `DataExportWorker` -protocol DataExportWorkerProtocol { - func flush() -> Bool -} - -class DataExportWorker: DataExportWorkerProtocol { - /// Queue to execute exports. - let queue = DispatchQueue(label: "com.otel.persistence.dataExportWorker", target: .global(qos: .utility)) - /// File reader providing data to export. - private let fileReader: FileReader - /// Data exporter sending data to server. - private let dataExporter: DataExporter - /// Variable system conditions determining if export should be performed. - private let exportCondition: () -> Bool - - /// Delay used to schedule consecutive exports. - private var delay: Delay - - /// Export work scheduled by this worker. - private var exportWork: DispatchWorkItem? - - init(fileReader: FileReader, - dataExporter: DataExporter, - exportCondition: @escaping () -> Bool, - delay: Delay) { - self.fileReader = fileReader - self.exportCondition = exportCondition - self.dataExporter = dataExporter - self.delay = delay - - let exportWork = DispatchWorkItem { [weak self] in - guard let self else { - return - } - - let isSystemReady = self.exportCondition() - let nextBatch = isSystemReady ? self.fileReader.readNextBatch() : nil - if let batch = nextBatch { - // Export batch - let exportStatus = self.dataExporter.export(data: batch.data) - - // Delete or keep batch depending on the export status - if exportStatus.needsRetry { - self.delay.increase() - } else { - self.fileReader.markBatchAsRead(batch) - self.delay.decrease() - } - } else { - self.delay.increase() - } - - scheduleNextExport(after: self.delay.current) - } - - self.exportWork = exportWork - - scheduleNextExport(after: self.delay.current) - } - - private func scheduleNextExport(after delay: TimeInterval) { - guard let work = exportWork else { - return - } - - queue.asyncAfter(deadline: .now() + delay, execute: work) - } - - /// This method gets remaining files at once, and exports them - /// It assures that periodic exporter cannot read or export the files while the flush is being processed - func flush() -> Bool { - let success = queue.sync { - self.fileReader.onRemainingBatches { - let exportStatus = self.dataExporter.export(data: $0.data) - if !exportStatus.needsRetry { - self.fileReader.markBatchAsRead($0) - } - } - } - return success - } - - /// Cancels scheduled exports and stops scheduling next ones. - /// - It does not affect the export that has already begun. - /// - It blocks the caller thread if called in the middle of export execution. - func cancelSynchronously() { - queue.sync(flags: .barrier) { - // This cancellation must be performed on the `queue` to ensure that it is not called - // in the middle of a `DispatchWorkItem` execution - otherwise, as the pending block would be - // fully executed, it will schedule another export by calling `nextScheduledWork(after:)` at the end. - self.exportWork?.cancel() - self.exportWork = nil - } - } -} diff --git a/Sources/Exporters/Persistence/PersistenceExporterDecorator.swift b/Sources/Exporters/Persistence/PersistenceExporterDecorator.swift deleted file mode 100644 index 01749c82..00000000 --- a/Sources/Exporters/Persistence/PersistenceExporterDecorator.swift +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -// protocol for exporters that can be decorated with `PersistenceExporterDecorator` -protocol DecoratedExporter { - associatedtype SignalType - - func export(values: [SignalType]) -> DataExportStatus -} - -// a generic decorator of `DecoratedExporter` adding filesystem persistence of batches of `[T.SignalType]`. -// `T.SignalType` must conform to `Codable`. -class PersistenceExporterDecorator - where T: DecoratedExporter, T.SignalType: Codable { - // a wrapper of `DecoratedExporter` (T) to add conformance to `DataExporter` that can be - // used with `DataExportWorker`. - private class DecoratedDataExporter: DataExporter { - private let decoratedExporter: T - - init(decoratedExporter: T) { - self.decoratedExporter = decoratedExporter - } - - func export(data: Data) -> DataExportStatus { - // decode batches of `[T.SignalType]` from the raw data. - // the data is made of batches of comma-suffixed JSON arrays, so in order to utilize - // `JSONDecoder`, add a "[" prefix and "null]" suffix making the data a valid - // JSON array of `[T.SignalType]`. - var arrayData: Data = JSONDataConstants.arrayPrefix - arrayData.append(data) - arrayData.append(JSONDataConstants.arraySuffix) - - do { - let decoder = JSONDecoder() - let exportables = try decoder.decode([[T.SignalType]?].self, - from: arrayData).compactMap { $0 }.flatMap { $0 } - - return decoratedExporter.export(values: exportables) - } catch { - return DataExportStatus(needsRetry: false) - } - } - } - - private let performancePreset: PersistencePerformancePreset - - private let fileWriter: FileWriter - - private let worker: DataExportWorkerProtocol - - public convenience init(decoratedExporter: T, - storageURL: URL, - exportCondition: @escaping () -> Bool = { true }, - performancePreset: PersistencePerformancePreset = .default) { - // orchestrate writes and reads over the folder given by `storageURL` - let filesOrchestrator = FilesOrchestrator(directory: Directory(url: storageURL), - performance: performancePreset, - dateProvider: SystemDateProvider()) - - let fileWriter = OrchestratedFileWriter( - orchestrator: filesOrchestrator - ) - - let fileReader = OrchestratedFileReader( - orchestrator: filesOrchestrator - ) - - self.init(decoratedExporter: decoratedExporter, - fileWriter: fileWriter, - workerFactory: { - DataExportWorker(fileReader: fileReader, - dataExporter: $0, - exportCondition: exportCondition, - delay: DataExportDelay(performance: performancePreset)) - }, - performancePreset: performancePreset) - } - - // internal initializer for testing that accepts a worker factory that allows mocking the worker - init(decoratedExporter: T, - fileWriter: FileWriter, - workerFactory createWorker: (DataExporter) -> DataExportWorkerProtocol, - performancePreset: PersistencePerformancePreset) { - self.performancePreset = performancePreset - - self.fileWriter = fileWriter - - worker = createWorker( - DecoratedDataExporter(decoratedExporter: decoratedExporter)) - } - - public func export(values: [T.SignalType]) throws { - let encoder = JSONEncoder() - var data = try encoder.encode(values) - data.append(JSONDataConstants.arraySeparator) - - if performancePreset.synchronousWrite { - fileWriter.writeSync(data: data) - } else { - fileWriter.write(data: data) - } - } - - public func flush() { - fileWriter.flush() - _ = worker.flush() - } -} - -// swiftlint:disable non_optional_string_data_conversion -private enum JSONDataConstants { - static let arrayPrefix = "[".data(using: .utf8)! - static let arraySuffix = "null]".data(using: .utf8)! - static let arraySeparator = ",".data(using: .utf8)! -} - -// swiftlint:enable non_optional_string_data_conversion diff --git a/Sources/Exporters/Persistence/PersistenceLogExporterDecorator.swift b/Sources/Exporters/Persistence/PersistenceLogExporterDecorator.swift deleted file mode 100644 index 20c4527b..00000000 --- a/Sources/Exporters/Persistence/PersistenceLogExporterDecorator.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import OpenTelemetrySdk - -// a persistence exporter decorator for `LogRecords`. -// specialization of `PersistenceExporterDecorator` for `LogExporter`. -public class PersistenceLogExporterDecorator: LogRecordExporter { - struct LogRecordDecoratedExporter: DecoratedExporter { - typealias SignalType = ReadableLogRecord - - private let logRecordExporter: LogRecordExporter - - init(logRecordExporter: LogRecordExporter) { - self.logRecordExporter = logRecordExporter - } - - func export(values: [ReadableLogRecord]) -> DataExportStatus { - let result = logRecordExporter.export(logRecords: values) - return DataExportStatus(needsRetry: result == .failure) - } - } - - private let logRecordExporter: LogRecordExporter - private let persistenceExporter: - PersistenceExporterDecorator - - public init(logRecordExporter: LogRecordExporter, - storageURL: URL, - exportCondition: @escaping () -> Bool = { true }, - performancePreset: PersistencePerformancePreset = .default) throws { - persistenceExporter = - PersistenceExporterDecorator(decoratedExporter: LogRecordDecoratedExporter( - logRecordExporter: logRecordExporter), - storageURL: storageURL, - exportCondition: exportCondition, - performancePreset: performancePreset) - self.logRecordExporter = logRecordExporter - } - - public func export(logRecords: [ReadableLogRecord], explicitTimeout: TimeInterval? = nil) -> ExportResult { - do { - try persistenceExporter.export(values: logRecords) - return .success - } catch { - return .failure - } - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) { - persistenceExporter.flush() - logRecordExporter.shutdown(explicitTimeout: explicitTimeout) - } - - public func forceFlush(explicitTimeout: TimeInterval? = nil) -> ExportResult { - persistenceExporter.flush() - return logRecordExporter.forceFlush(explicitTimeout: explicitTimeout) - } -} diff --git a/Sources/Exporters/Persistence/PersistenceMetricExporterDecorator.swift b/Sources/Exporters/Persistence/PersistenceMetricExporterDecorator.swift deleted file mode 100644 index 6971c988..00000000 --- a/Sources/Exporters/Persistence/PersistenceMetricExporterDecorator.swift +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -// a persistence exporter decorator for `Metric`. -// specialization of `PersistenceExporterDecorator` for `MetricExporter`. -public class PersistenceMetricExporterDecorator: MetricExporter { - struct MetricDecoratedExporter: DecoratedExporter { - typealias SignalType = MetricData - - private let metricExporter: any MetricExporter - - init(metricExporter: any MetricExporter) { - self.metricExporter = metricExporter - } - - func export(values: [MetricData]) -> DataExportStatus { - let result = metricExporter.export(metrics: values) - return DataExportStatus(needsRetry: result == .failure) - } - } - - private let metricExporter: MetricExporter - private let persistenceExporter: - PersistenceExporterDecorator - - public init(metricExporter: MetricExporter, - storageURL: URL, - exportCondition: @escaping () -> Bool = { true }, - performancePreset: PersistencePerformancePreset = .default) throws { - persistenceExporter = - PersistenceExporterDecorator(decoratedExporter: MetricDecoratedExporter( - metricExporter: metricExporter), - storageURL: storageURL, - exportCondition: exportCondition, - performancePreset: performancePreset) - self.metricExporter = metricExporter - } - - public func export(metrics: [MetricData]) - -> ExportResult { - do { - try persistenceExporter.export(values: metrics) - - return .success - } catch { - return .failure - } - } - - public func flush() -> OpenTelemetrySdk.ExportResult { - persistenceExporter.flush() - return metricExporter.flush() - } - - public func shutdown() -> OpenTelemetrySdk.ExportResult { - persistenceExporter.flush() - return metricExporter.shutdown() - } - - public func getAggregationTemporality(for instrument: OpenTelemetrySdk.InstrumentType) -> OpenTelemetrySdk.AggregationTemporality { - return metricExporter.getAggregationTemporality(for: instrument) - } -} diff --git a/Sources/Exporters/Persistence/PersistencePerformancePreset.swift b/Sources/Exporters/Persistence/PersistencePerformancePreset.swift deleted file mode 100644 index 8836b431..00000000 --- a/Sources/Exporters/Persistence/PersistencePerformancePreset.swift +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -protocol StoragePerformancePreset { - /// Maximum size of a single file (in bytes). - /// Each feature (logging, tracing, ...) serializes its objects data to that file for later export. - /// If last written file is too big to append next data, new file is created. - var maxFileSize: UInt64 { get } - /// Maximum size of data directory (in bytes). - /// Each feature uses separate directory. - /// If this size is exceeded, the oldest files are deleted until this limit is met again. - var maxDirectorySize: UInt64 { get } - /// Maximum age qualifying given file for reuse (in seconds). - /// If recently used file is younger than this, it is reused - otherwise: new file is created. - var maxFileAgeForWrite: TimeInterval { get } - /// Minimum age qualifying given file for export (in seconds). - /// If the file is older than this, it is exported (and then deleted if export succeeded). - /// It has an arbitrary offset (~0.5s) over `maxFileAgeForWrite` to ensure that no export can start for the file being currently written. - var minFileAgeForRead: TimeInterval { get } - /// Maximum age qualifying given file for export (in seconds). - /// Files older than this are considered obsolete and get deleted without exporting. - var maxFileAgeForRead: TimeInterval { get } - /// Maximum number of serialized objects written to a single file. - /// If number of objects in recently used file reaches this limit, new file is created for new data. - var maxObjectsInFile: Int { get } - /// Maximum size of serialized object data (in bytes). - /// If serialized object data exceeds this limit, it is skipped (not written to file and not exported). - var maxObjectSize: UInt64 { get } -} - -protocol ExportPerformancePreset { - /// First export delay (in seconds). - /// It is used as a base value until no more files eligible for export are found - then `defaultExportDelay` is used as a new base. - var initialExportDelay: TimeInterval { get } - /// Default exports interval (in seconds). - /// At runtime, the export interval ranges from `minExportDelay` to `maxExportDelay` depending - /// on delivery success or failure. - var defaultExportDelay: TimeInterval { get } - /// Minimum interval of data export (in seconds). - var minExportDelay: TimeInterval { get } - /// Maximum interval of data export (in seconds). - var maxExportDelay: TimeInterval { get } - /// If export succeeds or fails, current interval is changed by this rate. Should be less or equal `1.0`. - /// E.g: if rate is `0.1` then `delay` can be increased or decreased by `delay * 0.1`. - var exportDelayChangeRate: Double { get } -} - -public struct PersistencePerformancePreset: Equatable, StoragePerformancePreset, ExportPerformancePreset { - // MARK: - StoragePerformancePreset - - let maxFileSize: UInt64 - let maxDirectorySize: UInt64 - let maxFileAgeForWrite: TimeInterval - let minFileAgeForRead: TimeInterval - let maxFileAgeForRead: TimeInterval - let maxObjectsInFile: Int - let maxObjectSize: UInt64 - let synchronousWrite: Bool - - // MARK: - ExportPerformancePreset - - let initialExportDelay: TimeInterval - let defaultExportDelay: TimeInterval - let minExportDelay: TimeInterval - let maxExportDelay: TimeInterval - let exportDelayChangeRate: Double - - // MARK: - Predefined presets - - /// Default performance preset. - public static let `default` = lowRuntimeImpact - - /// Performance preset optimized for low runtime impact. - /// Minimalizes number of data requests send to the server. - public static let lowRuntimeImpact = PersistencePerformancePreset(maxFileSize: 4 * 1_024 * 1_024, // 4MB - maxDirectorySize: 512 * 1_024 * 1_024, // 512 MB - maxFileAgeForWrite: 4.75, - minFileAgeForRead: 4.75 + 0.5, // `maxFileAgeForWrite` + 0.5s margin - maxFileAgeForRead: 18 * 60 * 60, // 18h - maxObjectsInFile: 500, - maxObjectSize: 256 * 1_024, // 256KB - synchronousWrite: false, - initialExportDelay: 5, // postpone to not impact app launch time - defaultExportDelay: 5, - minExportDelay: 1, - maxExportDelay: 20, - exportDelayChangeRate: 0.1) - - /// Performance preset optimized for instant data delivery. - /// Minimalizes the time between receiving data form the user and delivering it to the server. - public static let instantDataDelivery = PersistencePerformancePreset(maxFileSize: `default`.maxFileSize, - maxDirectorySize: `default`.maxDirectorySize, - maxFileAgeForWrite: 2.75, - minFileAgeForRead: 2.75 + 0.5, // `maxFileAgeForWrite` + 0.5s margin - maxFileAgeForRead: `default`.maxFileAgeForRead, - maxObjectsInFile: `default`.maxObjectsInFile, - maxObjectSize: `default`.maxObjectSize, - synchronousWrite: true, - initialExportDelay: 0.5, // send quick to have a chance for export in short-lived app extensions - defaultExportDelay: 3, - minExportDelay: 1, - maxExportDelay: 5, - exportDelayChangeRate: 0.5 // reduce significantly for more exports in short-lived app extensions - ) -} diff --git a/Sources/Exporters/Persistence/PersistenceSpanExporterDecorator.swift b/Sources/Exporters/Persistence/PersistenceSpanExporterDecorator.swift deleted file mode 100644 index a8756d0a..00000000 --- a/Sources/Exporters/Persistence/PersistenceSpanExporterDecorator.swift +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -// a persistence exporter decorator for `SpanData`. -// specialization of `PersistenceExporterDecorator` for `SpanExporter`. -public class PersistenceSpanExporterDecorator: SpanExporter { - struct SpanDecoratedExporter: DecoratedExporter { - typealias SignalType = SpanData - - private let spanExporter: SpanExporter - - init(spanExporter: SpanExporter) { - self.spanExporter = spanExporter - } - - func export(values: [SpanData]) -> DataExportStatus { - _ = spanExporter.export(spans: values) - return DataExportStatus(needsRetry: false) - } - } - - private let spanExporter: SpanExporter - private let persistenceExporter: - PersistenceExporterDecorator - - public init(spanExporter: SpanExporter, - storageURL: URL, - exportCondition: @escaping () -> Bool = { true }, - performancePreset: PersistencePerformancePreset = .default) throws { - self.spanExporter = spanExporter - - persistenceExporter = - PersistenceExporterDecorator(decoratedExporter: SpanDecoratedExporter(spanExporter: spanExporter), - storageURL: storageURL, - exportCondition: exportCondition, - performancePreset: performancePreset) - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval?) - -> SpanExporterResultCode { - do { - try persistenceExporter.export(values: spans) - - return .success - } catch { - return .failure - } - } - - public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode { - persistenceExporter.flush() - return spanExporter.flush(explicitTimeout: explicitTimeout) - } - - public func shutdown(explicitTimeout: TimeInterval?) { - persistenceExporter.flush() - spanExporter.shutdown(explicitTimeout: explicitTimeout) - } -} diff --git a/Sources/Exporters/Persistence/README.md b/Sources/Exporters/Persistence/README.md deleted file mode 100644 index 5010b846..00000000 --- a/Sources/Exporters/Persistence/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Persistence Exporter - -The Persistence Exporter is not an actual exporter by itself, but an exporter decorator. It decorates a given exporter by persisting the exported data to the disk first, and then proceeds to forward it to the decorated exporter. The goal is to allow dealing with situations where telemetry data is generated in an environment that can't guarantee stable export. - -An example use case is mobile apps that operate while the device has no network connectivity. With the Persistence Exporter decorating the actual exporters used by the app, telemetry can be collected while the device is offline. Later - possibly after the app is terminated and relaunched - when network connectivity is back the collected telemetry data can be picked up from the disk and exported. - -The Persistence Exporter provides decorators for MetricExporter and SpanExporter. The decorators handle exported data by: - -- Asynchronously serializing and writing the exported data to the disk to a specified path. -- Asynchronously picking up persisted data, deserializing it, and forwarding it to the decorated exporter. - -### Usage - -An example of decorating a `MetricExporter`: - -```swift -let metricExporter = ... // create some MetricExporter -let persistenceMetricExporter = try PersistenceMetricExporterDecorator( - metricExporter: metricExporter, - storageURL: metricsSubdirectoryURL) -``` - -An example of decorating a `SpanExporter`: - -```swift -let spanExporter = ... // create some SpanExporter -let persistenceTraceExporter = try PersistenceSpanExporterDecorator( - spanExporter: spanExporter, - storageURL: tracesSubdirectoryURL) -``` diff --git a/Sources/Exporters/Persistence/Storage/Directory.swift b/Sources/Exporters/Persistence/Storage/Directory.swift deleted file mode 100644 index 86a36ae3..00000000 --- a/Sources/Exporters/Persistence/Storage/Directory.swift +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -/// An abstraction over file system directory where SDK stores its files. -struct Directory { - let url: URL - - /// Creates subdirectory with given path under system caches directory. - init(withSubdirectoryPath path: String) throws { - try self.init(url: createCachesSubdirectoryIfNotExists(subdirectoryPath: path)) - } - - init(url: URL) { - self.url = url - } - - /// Creates file with given name. - func createFile(named fileName: String) throws -> File { - let fileURL = url.appendingPathComponent(fileName, isDirectory: false) - guard FileManager.default.createFile(atPath: fileURL.path, contents: nil, attributes: nil) == true else { - throw StorageError.createFileError(path: fileURL) - } - return File(url: fileURL) - } - - /// Returns file with given name. - func file(named fileName: String) -> File? { - let fileURL = url.appendingPathComponent(fileName, isDirectory: false) - if FileManager.default.fileExists(atPath: fileURL.path) { - return File(url: fileURL) - } else { - return nil - } - } - - /// Returns all files of this directory. - func files() throws -> [File] { - return try FileManager.default - .contentsOfDirectory(at: url, includingPropertiesForKeys: [.isRegularFileKey, .canonicalPathKey]) - .map { url in File(url: url) } - } -} - -/// Creates subdirectory at given path in `/Library/Caches` if it does not exist. Might throw `PersistenceError` when it's not possible. -/// * `/Library/Caches` is exclduded from iTunes and iCloud backups by default. -/// * System may delete data in `/Library/Cache` to free up disk space which reduces the impact on devices working under heavy space pressure. -private func createCachesSubdirectoryIfNotExists(subdirectoryPath: String) throws -> URL { - guard let cachesDirectoryURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { - throw StorageError.obtainCacheLibraryError - } - - let subdirectoryURL = cachesDirectoryURL.appendingPathComponent(subdirectoryPath, isDirectory: true) - - do { - try FileManager.default.createDirectory(at: subdirectoryURL, withIntermediateDirectories: true, attributes: nil) - } catch { - throw StorageError.createDirectoryError(path: subdirectoryURL, error: error) - } - - return subdirectoryURL -} diff --git a/Sources/Exporters/Persistence/Storage/File.swift b/Sources/Exporters/Persistence/Storage/File.swift deleted file mode 100644 index c5307cb6..00000000 --- a/Sources/Exporters/Persistence/Storage/File.swift +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -/// Provides convenient interface for reading metadata and appending data to the file. -protocol WritableFile { - /// Name of this file. - var name: String { get } - - /// Current size of this file. - func size() throws -> UInt64 - - /// Synchronously appends given data at the end of this file. - func append(data: Data, synchronized: Bool) throws -} - -/// Provides convenient interface for reading contents and metadata of the file. -protocol ReadableFile { - /// Name of this file. - var name: String { get } - - /// Reads the available data in this file. - func read() throws -> Data - - /// Deletes this file. - func delete() throws -} - -/// An immutable `struct` designed to provide optimized and thread safe interface for file manipulation. -/// It doesn't own the file, which means the file presence is not guaranteed - the file can be deleted by OS at any time (e.g. due to memory pressure). -struct File: WritableFile, ReadableFile { - let url: URL - let name: String - - init(url: URL) { - self.url = url - name = url.lastPathComponent - } - - /// Appends given data at the end of this file. - func append(data: Data, synchronized: Bool = false) throws { - let fileHandle = try FileHandle(forWritingTo: url) - - // https://en.wikipedia.org/wiki/Xcode#11.x_series - // compiler version needs to have iOS 13.4+ as base SDK - #if compiler(>=5.2) - /** - Even though the `fileHandle.seekToEnd()` should be available since iOS 13.0: - ``` - @available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) - public func seekToEnd() throws -> UInt64 - ``` - it crashes on iOS Simulators prior to iOS 13.4: - ``` - Symbol not found: _$sSo12NSFileHandleC10FoundationE9seekToEnds6UInt64VyKF - ``` - This is fixed in iOS 14/Xcode 12 - */ - if #available(OSX 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) { - defer { - if synchronized { - try? fileHandle.synchronize() - } - try? fileHandle.close() - } - try fileHandle.seekToEnd() - try fileHandle.write(contentsOf: data) - } else { - legacyAppend(data, to: fileHandle) - } - #else - try legacyAppend(data, to: fileHandle) - #endif - } - - private func legacyAppend(_ data: Data, to fileHandle: FileHandle) { - defer { - fileHandle.closeFile() - } - fileHandle.seekToEndOfFile() - fileHandle.write(data) - } - - func read() throws -> Data { - let fileHandle = try FileHandle(forReadingFrom: url) - - // https://en.wikipedia.org/wiki/Xcode#11.x_series - // compiler version needs to have iOS 13.4+ as base SDK - #if compiler(>=5.2) - /** - Even though the `fileHandle.seekToEnd()` should be available since iOS 13.0: - ``` - @available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) - public func readToEnd() throws -> Data? - ``` - it crashes on iOS Simulators prior to iOS 13.4: - ``` - Symbol not found: _$sSo12NSFileHandleC10FoundationE9readToEndAC4DataVSgyKF - ``` - This is fixed in iOS 14/Xcode 12 - */ - if #available(OSX 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) { - defer { try? fileHandle.close() } - return try fileHandle.readToEnd() ?? Data() - } else { - return legacyRead(from: fileHandle) - } - #else - return legacyRead(from: fileHandle) - #endif - } - - private func legacyRead(from fileHandle: FileHandle) -> Data { - let data = fileHandle.readDataToEndOfFile() - fileHandle.closeFile() - return data - } - - func size() throws -> UInt64 { - let attributes = try FileManager.default.attributesOfItem(atPath: url.path) - return attributes[.size] as? UInt64 ?? 0 - } - - func delete() throws { - try FileManager.default.removeItem(at: url) - } -} diff --git a/Sources/Exporters/Persistence/Storage/FileReader.swift b/Sources/Exporters/Persistence/Storage/FileReader.swift deleted file mode 100644 index 58089937..00000000 --- a/Sources/Exporters/Persistence/Storage/FileReader.swift +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -struct Batch { - /// Data read from file - let data: Data - /// File from which `data` was read. - let file: ReadableFile -} - -protocol FileReader { - func readNextBatch() -> Batch? - - func onRemainingBatches(process: (Batch) -> Void) -> Bool - - func markBatchAsRead(_ batch: Batch) -} - -final class OrchestratedFileReader: FileReader { - /// Orchestrator producing reference to readable file. - private let orchestrator: FilesOrchestrator - - /// Files marked as read. - private var filesRead: [ReadableFile] = [] - - init(orchestrator: FilesOrchestrator) { - self.orchestrator = orchestrator - } - - // MARK: - Reading batches - - func readNextBatch() -> Batch? { - if let file = orchestrator.getReadableFile(excludingFilesNamed: Set(filesRead.map(\.name))) { - do { - let fileData = try file.read() - return Batch(data: fileData, file: file) - } catch { - return nil - } - } - - return nil - } - - /// This method gets remaining files at once, and process each file after with the block passed. - /// Currently called from flush method - func onRemainingBatches(process: (Batch) -> Void) -> Bool { - do { - try orchestrator.getAllFiles(excludingFilesNamed: Set(filesRead.map(\.name)))?.forEach { - let fileData = try $0.read() - process(Batch(data: fileData, file: $0)) - } - } catch { - return false - } - return true - } - - // MARK: - Accepting batches - - func markBatchAsRead(_ batch: Batch) { - orchestrator.delete(readableFile: batch.file) - filesRead.append(batch.file) - } -} diff --git a/Sources/Exporters/Persistence/Storage/FileWriter.swift b/Sources/Exporters/Persistence/Storage/FileWriter.swift deleted file mode 100644 index 54013279..00000000 --- a/Sources/Exporters/Persistence/Storage/FileWriter.swift +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -protocol FileWriter { - func write(data: Data) - - func writeSync(data: Data) - - func flush() -} - -final class OrchestratedFileWriter: FileWriter { - /// Orchestrator producing reference to writable file. - private let orchestrator: FilesOrchestrator - /// Queue used to synchronize files access (read / write) and perform decoding on background thread. - let queue = DispatchQueue(label: "com.otel.persistence.filewriter", target: .global(qos: .userInteractive)) - - init(orchestrator: FilesOrchestrator) { - self.orchestrator = orchestrator - } - - // MARK: - Writing data - - func write(data: Data) { - queue.async { [weak self] in - self?.synchronizedWrite(data: data) - } - } - - func writeSync(data: Data) { - queue.sync { [weak self] in - self?.synchronizedWrite(data: data, syncOnEnd: true) - } - } - - private func synchronizedWrite(data: Data, syncOnEnd: Bool = false) { - do { - let file = try orchestrator.getWritableFile(writeSize: UInt64(data.count)) - try file.append(data: data, synchronized: syncOnEnd) - } catch {} - } - - func flush() { - queue.sync(flags: .barrier) {} - } -} diff --git a/Sources/Exporters/Persistence/Storage/FilesOrchestrator.swift b/Sources/Exporters/Persistence/Storage/FilesOrchestrator.swift deleted file mode 100644 index 61c34e10..00000000 --- a/Sources/Exporters/Persistence/Storage/FilesOrchestrator.swift +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -class FilesOrchestrator { - /// Directory where files are stored. - private let directory: Directory - /// Date provider. - private let dateProvider: DateProvider - /// Performance rules for writing and reading files. - private let performance: StoragePerformancePreset - /// Name of the last file returned by `getWritableFile()`. - private var lastWritableFileName: String? - /// Tracks number of times the file at `lastWritableFileURL` was returned from `getWritableFile()`. - /// This should correspond with number of objects stored in file, assuming that majority of writes succeed (the difference is negligible). - private var lastWritableFileUsesCount: Int = 0 - - init(directory: Directory, - performance: StoragePerformancePreset, - dateProvider: DateProvider) { - self.directory = directory - self.performance = performance - self.dateProvider = dateProvider - } - - // MARK: - `WritableFile` orchestration - - func getWritableFile(writeSize: UInt64) throws -> WritableFile { - if writeSize > performance.maxObjectSize { - throw StorageError.dataExceedsMaxSizeError(dataSize: writeSize, maxSize: performance.maxObjectSize) - } - - let lastWritableFileOrNil = reuseLastWritableFileIfPossible(writeSize: writeSize) - - if let lastWritableFile = lastWritableFileOrNil { // if last writable file can be reused - lastWritableFileUsesCount += 1 - return lastWritableFile - } else { - // NOTE: As purging files directory is a memory-expensive operation, do it only when we know - // that a new file will be created. With SDK's `PerformancePreset` this gives - // the process enough time to not over-allocate internal `_FileCache` and `_NSFastEnumerationEnumerator` - // objects, resulting with a flat allocations graph in a long term. - try purgeFilesDirectoryIfNeeded() - - let newFileName = fileNameFrom(fileCreationDate: dateProvider.currentDate()) - let newFile = try directory.createFile(named: newFileName) - lastWritableFileName = newFile.name - lastWritableFileUsesCount = 1 - return newFile - } - } - - private func reuseLastWritableFileIfPossible(writeSize: UInt64) -> WritableFile? { - if let lastFileName = lastWritableFileName { - do { - guard let lastFile = directory.file(named: lastFileName) else { - return nil - } - let lastFileCreationDate = fileCreationDateFrom(fileName: lastFile.name) - let lastFileAge = dateProvider.currentDate().timeIntervalSince(lastFileCreationDate) - - let fileIsRecentEnough = lastFileAge <= performance.maxFileAgeForWrite - let fileHasRoomForMore = try (lastFile.size() + writeSize) <= performance.maxFileSize - let fileCanBeUsedMoreTimes = (lastWritableFileUsesCount + 1) <= performance.maxObjectsInFile - - if fileIsRecentEnough, fileHasRoomForMore, fileCanBeUsedMoreTimes { - return lastFile - } - } catch { - return nil - } - } - - return nil - } - - // MARK: - `ReadableFile` orchestration - - func getReadableFile(excludingFilesNamed excludedFileNames: Set = []) -> ReadableFile? { - do { - let filesWithCreationDate = try directory.files() - .map { (file: $0, creationDate: fileCreationDateFrom(fileName: $0.name)) } - .compactMap { try deleteFileIfItsObsolete(file: $0.file, fileCreationDate: $0.creationDate) } - - guard let (oldestFile, creationDate) = filesWithCreationDate - .filter({ excludedFileNames.contains($0.file.name) == false }) - .sorted(by: { $0.creationDate < $1.creationDate }) - .first - else { - return nil - } - - let oldestFileAge = dateProvider.currentDate().timeIntervalSince(creationDate) - let fileIsOldEnough = oldestFileAge >= performance.minFileAgeForRead - - return fileIsOldEnough ? oldestFile : nil - } catch { - return nil - } - } - - func getAllFiles(excludingFilesNamed excludedFileNames: Set = []) -> [ReadableFile]? { - do { - return try directory.files() - .filter { excludedFileNames.contains($0.name) == false } - } catch { - return nil - } - } - - func delete(readableFile: ReadableFile) { - do { - try readableFile.delete() - } catch {} - } - - // MARK: - Directory size management - - /// Removes oldest files from the directory if it becomes too big. - private func purgeFilesDirectoryIfNeeded() throws { - let filesSortedByCreationDate = try directory.files() - .map { (file: $0, creationDate: fileCreationDateFrom(fileName: $0.name)) } - .sorted { $0.creationDate < $1.creationDate } - - var filesWithSizeSortedByCreationDate = try filesSortedByCreationDate - .map { try (file: $0.file, size: $0.file.size()) } - - let accumulatedFilesSize = filesWithSizeSortedByCreationDate.map(\.size).reduce(0, +) - - if accumulatedFilesSize > performance.maxDirectorySize { - let sizeToFree = accumulatedFilesSize - performance.maxDirectorySize - var sizeFreed: UInt64 = 0 - - while sizeFreed < sizeToFree, !filesWithSizeSortedByCreationDate.isEmpty { - let fileWithSize = filesWithSizeSortedByCreationDate.removeFirst() - try fileWithSize.file.delete() - sizeFreed += fileWithSize.size - } - } - } - - private func deleteFileIfItsObsolete(file: File, fileCreationDate: Date) throws -> (file: File, creationDate: Date)? { - let fileAge = dateProvider.currentDate().timeIntervalSince(fileCreationDate) - - if fileAge > performance.maxFileAgeForRead { - try file.delete() - return nil - } else { - return (file: file, creationDate: fileCreationDate) - } - } -} - -/// File creation date is used as file name - timestamp in milliseconds is used for date representation. -/// This function converts file creation date into file name. -func fileNameFrom(fileCreationDate: Date) -> String { - let milliseconds = fileCreationDate.timeIntervalSinceReferenceDate * 1_000 - let converted = (try? UInt64(withReportingOverflow: milliseconds)) ?? 0 - return String(converted) -} - -/// File creation date is used as file name - timestamp in milliseconds is used for date representation. -/// This function converts file name into file creation date. -func fileCreationDateFrom(fileName: String) -> Date { - let millisecondsSinceReferenceDate = TimeInterval(UInt64(fileName) ?? 0) / 1_000 - return Date(timeIntervalSinceReferenceDate: TimeInterval(millisecondsSinceReferenceDate)) -} - -private enum FixedWidthIntegerError: Error { - case overflow(overflowingValue: T) -} - -private extension FixedWidthInteger { - /* - Self(:) is commonly used for conversion, however it fatalError() in case of conversion failure - Self(exactly:) does the exact same thing internally yet it returns nil instead of fatalError() - It is not trivial to guess if the conversion would fail or succeed, therefore we use Self(exactly:) - so that we don't need to guess in order to save the app from crashing - - IMPORTANT: If you pass floatingPoint to Self(exactly:) without rounded(), it may return nil - */ - init(withReportingOverflow floatingPoint: T) throws { - guard let converted = Self(exactly: floatingPoint.rounded()) else { - throw FixedWidthIntegerError.overflow(overflowingValue: floatingPoint) - } - self = converted - } -} diff --git a/Sources/Exporters/Persistence/Storage/StorageError.swift b/Sources/Exporters/Persistence/Storage/StorageError.swift deleted file mode 100644 index c781994e..00000000 --- a/Sources/Exporters/Persistence/Storage/StorageError.swift +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -enum StorageError: Error { - case createFileError(path: URL) - case createDirectoryError(path: URL, error: Error) - case obtainCacheLibraryError - case dataExceedsMaxSizeError(dataSize: UInt64, maxSize: UInt64) -} diff --git a/Sources/Exporters/Persistence/Utils/DateProvider.swift b/Sources/Exporters/Persistence/Utils/DateProvider.swift deleted file mode 100644 index fa6d66ae..00000000 --- a/Sources/Exporters/Persistence/Utils/DateProvider.swift +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -/// Interface for date provider used for files orchestration. -protocol DateProvider { - func currentDate() -> Date -} - -struct SystemDateProvider: DateProvider { - @inlinable - func currentDate() -> Date { return Date() } -} diff --git a/Sources/Exporters/Prometheus/PrometheusExporter.swift b/Sources/Exporters/Prometheus/PrometheusExporter.swift deleted file mode 100644 index 36fc3f23..00000000 --- a/Sources/Exporters/Prometheus/PrometheusExporter.swift +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import NIOConcurrencyHelpers -import OpenTelemetrySdk - -public class PrometheusExporter: MetricExporter { - var aggregationTemporalitySelector: AggregationTemporalitySelector - - public func getAggregationTemporality(for instrument: OpenTelemetrySdk.InstrumentType) -> OpenTelemetrySdk.AggregationTemporality { - return aggregationTemporalitySelector.getAggregationTemporality(for: instrument) - } - - public func flush() -> OpenTelemetrySdk.ExportResult { - // noop - return .success - } - - public func shutdown() -> OpenTelemetrySdk.ExportResult { - // noop - return .success - } - - fileprivate let metricsLock = NIOLock() - let options: PrometheusExporterOptions - private var metrics = [MetricData]() - - public init(options: PrometheusExporterOptions, aggregationTemoralitySelector: AggregationTemporalitySelector = AggregationTemporality.alwaysCumulative()) { - self.options = options - aggregationTemporalitySelector = aggregationTemoralitySelector - } - - public func export(metrics: [MetricData]) -> ExportResult { - metricsLock.withLockVoid { - self.metrics = metrics - } - return .success - } - - public func getMetrics() -> [MetricData] { - defer { - metricsLock.unlock() - } - metricsLock.lock() - return metrics - } -} - -public struct PrometheusExporterOptions { - var url: String - - public init(url: String) { - self.url = url - } -} diff --git a/Sources/Exporters/Prometheus/PrometheusExporterExtensions.swift b/Sources/Exporters/Prometheus/PrometheusExporterExtensions.swift deleted file mode 100644 index cded7f61..00000000 --- a/Sources/Exporters/Prometheus/PrometheusExporterExtensions.swift +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -public enum PrometheusExporterExtensions { - static let prometheusCounterType = "counter" - static let prometheusGaugeType = "gauge" - static let prometheusSummaryType = "summary" - static let prometheusSummarySumPostFix = "_sum" - static let prometheusSummaryCountPostFix = "_count" - static let prometheusSummaryQuantileLabelName = "quantile" - static let prometheusSummaryQuantileLabelValueForMin = "0" - static let prometheusSummaryQuantileLabelValueForMax = "1" - static let prometheusHistogramType = "histogram" - static let prometheusHistogramSumPostFix = "_sum" - static let prometheusHistogramCountPostFix = "_count" - static let prometheusHistogramBucketPostFix = "_bucket" - static let prometheusHistogramLeLabelName = "le" - - public static func writeMetricsCollection(exporter: PrometheusExporter) -> String { - var output = "" - let metrics = exporter.getMetrics() - let now = String(Int64((Date().timeIntervalSince1970 * 1000.0).rounded())) - - metrics.forEach { metric in - let prometheusMetric = PrometheusMetric(name: metric.name, description: metric.description) - metric.data.points.forEach { metricData in - let labels = metricData.attributes - switch metric.type { - case .DoubleSum: - guard let sum = metricData as? DoublePointData else { - break - } - output += PrometheusExporterExtensions - .writeSum( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - doubleValue: sum.value - ) - case .LongSum: - guard let sum = metricData as? LongPointData else { - break - } - output += PrometheusExporterExtensions - .writeSum( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - doubleValue: Double(sum.value) - ) - case .DoubleGauge: - guard let gauge = metricData as? DoublePointData else { break } - output += PrometheusExporterExtensions - .writeGauge( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - doubleValue: gauge.value - ) - case .LongGauge: - guard let gauge = metricData as? LongPointData else { break } - output += PrometheusExporterExtensions - .writeGauge( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - doubleValue: Double(gauge.value) - ) - case .Histogram: - guard let histogram = metricData as? HistogramPointData else { break } - let count = histogram.count - let sum = histogram.sum - let bucketsBoundaries = histogram.boundaries - let bucketsCounts = histogram.counts - output += PrometheusExporterExtensions - .writeHistogram( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - metricName: metric.name, - sum: Double(sum), - count: Int(count), - bucketsBoundaries: bucketsBoundaries, - bucketsCounts: bucketsCounts - ) - case .ExponentialHistogram: - guard let histogram = metricData as? HistogramPointData else { break } - let count = histogram.count - let sum = histogram.sum - let bucketsBoundaries = histogram.boundaries - let bucketsCounts = histogram.counts - output += PrometheusExporterExtensions - .writeHistogram( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - metricName: metric.name, - sum: Double(sum), - count: Int(count), - bucketsBoundaries: bucketsBoundaries, - bucketsCounts: bucketsCounts - ) - case .Summary: - guard let summary = metricData as? SummaryPointData else { break } - let count = summary.count - let sum = summary.sum - let min = summary.values.max(by: { a, b in - a.value < b.value - })?.value ?? 0.0 - let max = summary.values.max { a, b in - a.value > b.value - }?.value ?? 0.0 - output += PrometheusExporterExtensions - .writeSummary( - prometheusMetric: prometheusMetric, - timeStamp: now, - labels: labels.mapValues { value in - value.description - }, - metricName: metric.name, - sum: Double(sum), - count: Int(count), - min: Double(min), - max: Double(max) - ) - } - } - } - - return output - } - - private static func writeSum(prometheusMetric: PrometheusMetric, timeStamp: String, labels: [String: String], doubleValue: Double) -> String { - var prometheusMetric = prometheusMetric - prometheusMetric.type = prometheusCounterType - let metricValue = PrometheusValue(labels: labels, value: doubleValue) - prometheusMetric.values.append(metricValue) - return prometheusMetric.write(timeStamp: timeStamp) - } - - private static func writeGauge(prometheusMetric: PrometheusMetric, timeStamp: String, labels: [String: String], doubleValue: Double) -> String { - var prometheusMetric = prometheusMetric - prometheusMetric.type = prometheusGaugeType - let metricValue = PrometheusValue(labels: labels, value: doubleValue) - prometheusMetric.values.append(metricValue) - return prometheusMetric.write(timeStamp: timeStamp) - } - - private static func writeSummary(prometheusMetric: PrometheusMetric, timeStamp: String, labels: [String: String], metricName: String, sum: Double, count: Int, min: Double, max: Double) -> String { - var prometheusMetric = prometheusMetric - prometheusMetric.type = prometheusSummaryType - labels.forEach { - prometheusMetric.values.append(PrometheusValue(name: metricName + prometheusSummarySumPostFix, labels: [$0.key: $0.value], value: sum)) - prometheusMetric.values.append(PrometheusValue(name: metricName + prometheusSummaryCountPostFix, labels: [$0.key: $0.value], value: Double(count))) - prometheusMetric.values.append(PrometheusValue(name: metricName, - labels: [$0.key: $0.value, - prometheusSummaryQuantileLabelName: prometheusSummaryQuantileLabelValueForMin], - value: min)) - prometheusMetric.values.append(PrometheusValue(name: metricName, - labels: [$0.key: $0.value, - prometheusSummaryQuantileLabelName: prometheusSummaryQuantileLabelValueForMax], - value: max)) - } - return prometheusMetric.write(timeStamp: timeStamp) - } - - private static func writeHistogram(prometheusMetric: PrometheusMetric, timeStamp: String, labels: [String: String], metricName: String, sum: Double, count: Int, bucketsBoundaries: [Double], bucketsCounts: [Int]) -> String { - var prometheusMetric = prometheusMetric - prometheusMetric.type = prometheusHistogramType - labels.forEach { - prometheusMetric.values.append(PrometheusValue(name: metricName + prometheusHistogramSumPostFix, labels: [$0.key: $0.value], value: sum)) - prometheusMetric.values.append(PrometheusValue(name: metricName + prometheusHistogramCountPostFix, labels: [$0.key: $0.value], value: Double(count))) - for i in 0 ..< bucketsBoundaries.count { - prometheusMetric.values.append(PrometheusValue(name: metricName, - labels: [$0.key: $0.value, - prometheusHistogramLeLabelName: String(format: "%f", bucketsBoundaries[i])], - value: Double(bucketsCounts[i]))) - } - prometheusMetric.values.append(PrometheusValue(name: metricName, - labels: [$0.key: $0.value, - prometheusHistogramLeLabelName: "+Inf"], - value: Double(bucketsCounts[bucketsBoundaries.count]))) - } - return prometheusMetric.write(timeStamp: timeStamp) - } -} diff --git a/Sources/Exporters/Prometheus/PrometheusExporterHttpServer.swift b/Sources/Exporters/Prometheus/PrometheusExporterHttpServer.swift deleted file mode 100644 index 3dd0f3c6..00000000 --- a/Sources/Exporters/Prometheus/PrometheusExporterHttpServer.swift +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import NIO -import NIOHTTP1 - -public class PrometheusExporterHttpServer { - private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - private var host: String - private var port: Int - var exporter: PrometheusExporter - - public init(exporter: PrometheusExporter) { - self.exporter = exporter - - let url = URL(string: exporter.options.url) - host = url?.host ?? "localhost" - port = url?.port ?? 9184 - } - - public func start() throws { - do { - let channel = try serverBootstrap.bind(host: host, port: port).wait() - print("Listening on \(String(describing: channel.localAddress))...") - try channel.closeFuture.wait() - } catch { - throw error - } - } - - public func stop() { - do { - try group.syncShutdownGracefully() - } catch { - print("Error shutting down \(error.localizedDescription)") - exit(0) - } - print("Client connection closed") - } - - private var serverBootstrap: ServerBootstrap { - return ServerBootstrap(group: group) - // Specify backlog and enable SO_REUSEADDR for the server itself - .serverChannelOption(ChannelOptions.backlog, value: 256) - .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) - // Set the handlers that are appled to the accepted Channels - .childChannelInitializer { channel in - // Ensure we don't read faster than we can write by adding the BackPressureHandler into the pipeline. - channel.pipeline.configureHTTPServerPipeline(withErrorHandling: true).flatMap { - channel.pipeline.addHandler(PrometheusHTTPHandler(exporter: self.exporter)) - } - } - - // Enable SO_REUSEADDR for the accepted Channels - .childChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) - .childChannelOption(ChannelOptions.maxMessagesPerRead, value: 1) - } - - private final class PrometheusHTTPHandler: ChannelInboundHandler { - public typealias InboundIn = HTTPServerRequestPart - public typealias OutboundOut = HTTPServerResponsePart - - var exporter: PrometheusExporter - - init(exporter: PrometheusExporter) { - self.exporter = exporter - } - - public func channelRead(context: ChannelHandlerContext, data: NIOAny) { - let reqPart = unwrapInboundIn(data) - - switch reqPart { - case let .head(request): - - if request.uri.unicodeScalars.starts(with: "/metrics".unicodeScalars) { - let channel = context.channel - - let head = HTTPResponseHead(version: request.version, - status: .ok) - let part = HTTPServerResponsePart.head(head) - _ = channel.write(part) - - let metrics = PrometheusExporterExtensions.writeMetricsCollection(exporter: exporter) - var buffer = channel.allocator.buffer(capacity: metrics.count) - buffer.writeString(metrics) - let bodypart = HTTPServerResponsePart.body(.byteBuffer(buffer)) - _ = channel.write(bodypart) - - let endpart = HTTPServerResponsePart.end(nil) - _ = channel.writeAndFlush(endpart).flatMap { - channel.close() - } - } - - case .body: - break - - case .end: break - } - } - - // Flush it out. This can make use of gathering writes if multiple buffers are pending - public func channelReadComplete(context: ChannelHandlerContext) { - context.flush() - } - - public func errorCaught(context: ChannelHandlerContext, error: Error) { - print("error: ", error) - - // As we are not really interested getting notified on success or failure we just pass nil as promise to - // reduce allocations. - context.close(promise: nil) - } - } -} diff --git a/Sources/Exporters/Prometheus/PrometheusMetric.swift b/Sources/Exporters/Prometheus/PrometheusMetric.swift deleted file mode 100644 index ff41dada..00000000 --- a/Sources/Exporters/Prometheus/PrometheusMetric.swift +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -struct PrometheusMetric { - let contentType = "text/plain; version = 0.0.4" - - static let firstCharacterNameCharset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_:") - static let nameCharset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:") - static let firstCharacterLabelCharset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_") - static let labelCharset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") - - var values = [PrometheusValue]() - var name: String - var description: String - var type: String = "" - - func write(timeStamp: String) -> String { - var output = "" - - let name = PrometheusMetric.getSafeMetricName(name: name) - - if !description.isEmpty { - output += "# HELP " - output += name - output += PrometheusMetric.getSafeMetricDescription(description: description) - output += "\n" - } - - if !type.isEmpty { - output += "# TYPE " - output += name - output += " " - output += type - output += "\n" - } - - values.forEach { value in - output += value.name != nil ? PrometheusMetric.getSafeMetricName(name: value.name!) : name - - if value.labels.count > 0 { - output += "{" - output += value.labels.map { "\(PrometheusMetric.getSafeLabelName(name: $0))=\"\(PrometheusMetric.getSafeLabelValue(value: $1))\"" }.joined(separator: ",") - output += "}" - } - - output += " " - output += String(value.value) - output += " " - - output += timeStamp - output += "\n" - } - - return output - } - - private static func getSafeMetricName(name: String) -> String { - return getSafeName(name: name, firstCharNameCharset: firstCharacterNameCharset, charNameCharset: nameCharset) - } - - private static func getSafeLabelName(name: String) -> String { - return getSafeName(name: name, firstCharNameCharset: firstCharacterLabelCharset, charNameCharset: labelCharset) - } - - private static func getSafeName(name: String, firstCharNameCharset: CharacterSet, charNameCharset: CharacterSet) -> String { - var output = name.replaceCharactersFromSet(characterSet: charNameCharset.inverted, replacementString: "_") - - if let first = output.unicodeScalars.first, - !firstCharNameCharset.contains(first) { - output = "_" + output.dropFirst() - } - return output - } - - private static func getSafeLabelValue(value: String) -> String { - var result = value.replacingOccurrences(of: "\\", with: "\\\\") - result = result.replacingOccurrences(of: "\n", with: "\\n") - result = result.replacingOccurrences(of: "\"", with: "\\\"") - return result - } - - private static func getSafeMetricDescription(description: String) -> String { - var result = description.replacingOccurrences(of: "\\", with: "\\\\") - result = result.replacingOccurrences(of: "\n", with: "\\n") - return result - } -} - -struct PrometheusValue { - var name: String? - var labels = [String: String]() - var value: Double -} - -extension String { - func replaceCharactersFromSet(characterSet: CharacterSet, replacementString: String = "") -> String { - return components(separatedBy: characterSet).joined(separator: replacementString) - } -} diff --git a/Sources/Exporters/Zipkin/Implementation/ZipkinAnnotation.swift b/Sources/Exporters/Zipkin/Implementation/ZipkinAnnotation.swift deleted file mode 100644 index 26970fc6..00000000 --- a/Sources/Exporters/Zipkin/Implementation/ZipkinAnnotation.swift +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -struct ZipkinAnnotation: Encodable { - var timestamp: UInt64 - var value: String -} diff --git a/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift b/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift deleted file mode 100644 index 1b19b4d6..00000000 --- a/Sources/Exporters/Zipkin/Implementation/ZipkinConversionExtension.swift +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -enum ZipkinConversionExtension { - static let statusCode = "otel.status_code" - static let statusErrorDescription = "error" - - static let remoteEndpointServiceNameKeyResolution = ["peer.service": 0, - "net.peer.name": 1, - "peer.hostname": 2, - "peer.address": 2, - "http.host": 3, - "db.instance": 4] - - static var localEndpointCache = [String: ZipkinEndpoint]() - static var remoteEndpointCache = [String: ZipkinEndpoint]() - - static let defaultServiceName = "unknown_service:" + ProcessInfo.processInfo.processName - - struct AttributeEnumerationState { - var tags = [String: String]() - var RemoteEndpointServiceName: String? - var remoteEndpointServiceNamePriority: Int? - var serviceName: String? - var serviceNamespace: String? - } - - static func toZipkinSpan(otelSpan: SpanData, defaultLocalEndpoint: ZipkinEndpoint, useShortTraceIds: Bool = false) -> ZipkinSpan { - let parentId = otelSpan.parentSpanId?.hexString ?? SpanId.invalid.hexString - - var attributeEnumerationState = AttributeEnumerationState() - - otelSpan.attributes.forEach { - processAttributes(state: &attributeEnumerationState, key: $0.key, value: $0.value) - } - - otelSpan.resource.attributes.forEach { - processResources(state: &attributeEnumerationState, key: $0.key, value: $0.value) - } - - var localEndpoint = defaultLocalEndpoint - - if let serviceName = attributeEnumerationState.serviceName, !serviceName.isEmpty, defaultServiceName != serviceName { - if localEndpointCache[serviceName] == nil { - localEndpointCache[serviceName] = defaultLocalEndpoint.clone(serviceName: serviceName) - } - localEndpoint = localEndpointCache[serviceName] ?? localEndpoint - } - - if let serviceNamespace = attributeEnumerationState.serviceNamespace, !serviceNamespace.isEmpty { - attributeEnumerationState.tags["service.namespace"] = serviceNamespace - } - - var remoteEndpoint: ZipkinEndpoint? - if otelSpan.kind == .client || otelSpan.kind == .producer, attributeEnumerationState.RemoteEndpointServiceName != nil { - remoteEndpoint = remoteEndpointCache[attributeEnumerationState.RemoteEndpointServiceName!] - if remoteEndpoint == nil { - remoteEndpoint = ZipkinEndpoint(serviceName: attributeEnumerationState.RemoteEndpointServiceName!) - remoteEndpointCache[attributeEnumerationState.RemoteEndpointServiceName!] = remoteEndpoint! - } - } - - let status = otelSpan.status - if status != .unset { - attributeEnumerationState.tags[statusCode] = "\(status.name)".uppercased() - } - if case let Status.error(description) = status { - attributeEnumerationState.tags[statusErrorDescription] = description - } - - let annotations = otelSpan.events.map { processEvents(event: $0) } - - return ZipkinSpan(traceId: ZipkinConversionExtension.EncodeTraceId(traceId: otelSpan.traceId, useShortTraceIds: useShortTraceIds), - parentId: parentId, - id: ZipkinConversionExtension.EncodeSpanId(spanId: otelSpan.spanId), - kind: ZipkinConversionExtension.toSpanKind(otelSpan: otelSpan), - name: otelSpan.name, - timestamp: otelSpan.startTime.timeIntervalSince1970.toMicroseconds, - duration: otelSpan.endTime.timeIntervalSince(otelSpan.startTime).toMicroseconds, - localEndpoint: localEndpoint, - remoteEndpoint: remoteEndpoint, - annotations: annotations, - tags: attributeEnumerationState.tags, - debug: nil, - shared: nil) - } - - static func EncodeSpanId(spanId: SpanId) -> String { - return spanId.hexString - } - - private static func EncodeTraceId(traceId: TraceId, useShortTraceIds: Bool) -> String { - if useShortTraceIds { - return String(format: "%016llx", traceId.rawLowerLong) - } else { - return traceId.hexString - } - } - - private static func toSpanKind(otelSpan: SpanData) -> String? { - switch otelSpan.kind { - case .client: - return "CLIENT" - case .server: - return "SERVER" - case .producer: - return "PRODUCER" - case .consumer: - return "CONSUMER" - default: - return nil - } - } - - private static func processEvents(event: SpanData.Event) -> ZipkinAnnotation { - return ZipkinAnnotation(timestamp: event.timestamp.timeIntervalSince1970.toMicroseconds, value: event.name) - } - - private static func processAttributes(state: inout AttributeEnumerationState, key: String, value: AttributeValue) { - if case let .string(val) = value, let priority = remoteEndpointServiceNameKeyResolution[key] { - if state.RemoteEndpointServiceName == nil || priority < state.remoteEndpointServiceNamePriority ?? 5 { - state.RemoteEndpointServiceName = val - state.remoteEndpointServiceNamePriority = priority - } - state.tags[key] = val - } else { - state.tags[key] = value.description - } - } - - private static func processResources(state: inout AttributeEnumerationState, key: String, value: AttributeValue) { - if case let .string(val) = value { - if key == ResourceAttributes.serviceName { - state.serviceName = val - } else if key == ResourceAttributes.serviceNamespace { - state.serviceNamespace = val - } else { - state.tags[key] = val - } - } else { - state.tags[key] = value.description - } - } -} diff --git a/Sources/Exporters/Zipkin/Implementation/ZipkinEndpoint.swift b/Sources/Exporters/Zipkin/Implementation/ZipkinEndpoint.swift deleted file mode 100644 index e133b492..00000000 --- a/Sources/Exporters/Zipkin/Implementation/ZipkinEndpoint.swift +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -class ZipkinEndpoint: Encodable { - var serviceName: String - var ipv4: String? - var ipv6: String? - var port: Int? - - public init(serviceName: String, ipv4: String? = nil, ipv6: String? = nil, port: Int? = nil) { - self.serviceName = serviceName - self.ipv4 = ipv4 - self.ipv6 = ipv6 - self.port = port - } - - public func clone(serviceName: String) -> ZipkinEndpoint { - return ZipkinEndpoint(serviceName: serviceName, ipv4: ipv4, ipv6: ipv6, port: port) - } - - public func write() -> [String: Any] { - var output = [String: Any]() - - output["serviceName"] = serviceName - output["ipv4"] = ipv4 - output["ipv6"] = ipv6 - output["port"] = port - - return output - } -} diff --git a/Sources/Exporters/Zipkin/Implementation/ZipkinSpan.swift b/Sources/Exporters/Zipkin/Implementation/ZipkinSpan.swift deleted file mode 100644 index b663b52b..00000000 --- a/Sources/Exporters/Zipkin/Implementation/ZipkinSpan.swift +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -struct ZipkinSpan: Encodable { - var traceId: String - var parentId: String? - var id: String - var kind: String? - var name: String - var timestamp: UInt64? - var duration: UInt64? - var localEndpoint: ZipkinEndpoint? - var remoteEndpoint: ZipkinEndpoint? - var annotations: [ZipkinAnnotation] - var tags: [String: String] - var debug: Bool? - var shared: Bool? - - init(traceId: String, parentId: String?, id: String, kind: String?, name: String, timestamp: UInt64?, duration: UInt64?, localEndpoint: ZipkinEndpoint, remoteEndpoint: ZipkinEndpoint?, annotations: [ZipkinAnnotation], tags: [String: String], debug: Bool?, shared: Bool?) { - self.traceId = traceId - self.parentId = parentId - self.id = id - self.kind = kind - self.name = name - self.timestamp = timestamp - self.duration = duration - self.localEndpoint = localEndpoint - self.remoteEndpoint = remoteEndpoint - self.annotations = annotations - self.tags = tags - self.debug = debug - self.shared = shared - } - - public func write() -> [String: Any] { - var output = [String: Any]() - - output["traceId"] = traceId - output["name"] = name - output["parentId"] = parentId - output["id"] = id - output["kind"] = kind - output["timestamp"] = timestamp - output["duration"] = duration - output["debug"] = debug - output["shared"] = shared - - if localEndpoint != nil { - output["localEndpoint"] = localEndpoint!.write() - } - - if remoteEndpoint != nil { - output["localEndpoint"] = remoteEndpoint!.write() - } - - if annotations.count > 0 { - let annotationsArray: [Any] = annotations.map { - var object = [String: Any]() - object["timestamp"] = $0.timestamp - object["value"] = $0.value - return object - } - - output["annotations"] = annotationsArray - } - - if tags.count > 0 { - output["tags"] = tags - } - - return output - } -} diff --git a/Sources/Exporters/Zipkin/Utils/NetworkUtils.swift b/Sources/Exporters/Zipkin/Utils/NetworkUtils.swift deleted file mode 100644 index 52cab66d..00000000 --- a/Sources/Exporters/Zipkin/Utils/NetworkUtils.swift +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -enum NetworkUtils { - static func isValidIpv4Address(_ ipToValidate: String) -> Bool { - var sin = sockaddr_in() - if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 { - return true - } - return false - } - - static func isValidIpv6Address(_ ipToValidate: String) -> Bool { - var sin6 = sockaddr_in6() - - if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 { - // IPv6 peer. - return true - } - return false - } -} diff --git a/Sources/Exporters/Zipkin/ZipkinTraceExporter.swift b/Sources/Exporters/Zipkin/ZipkinTraceExporter.swift deleted file mode 100644 index cc3cf851..00000000 --- a/Sources/Exporters/Zipkin/ZipkinTraceExporter.swift +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -public class ZipkinTraceExporter: SpanExporter { - public var options: ZipkinTraceExporterOptions - var localEndPoint: ZipkinEndpoint - - public init(options: ZipkinTraceExporterOptions) { - self.options = options - localEndPoint = ZipkinTraceExporter.getLocalZipkinEndpoint(name: options.serviceName) - } - - public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - guard let url = URL(string: options.endpoint) else { return .failure } - - var request = URLRequest(url: url) - request.timeoutInterval = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, options.timeoutSeconds) - request.httpMethod = "POST" - request.addValue("application/json", forHTTPHeaderField: "Content-Type") - options.additionalHeaders.forEach { - request.addValue($0.value, forHTTPHeaderField: $0.key) - } - - let spans = encodeSpans(spans: spans) - do { - request.httpBody = try JSONEncoder().encode(spans) - } catch { - return .failure - } - - var status: SpanExporterResultCode = .failure - - let sem = DispatchSemaphore(value: 0) - - let task = URLSession.shared.dataTask(with: request) { _, _, error in - if error != nil { - status = .failure - } else { - status = .success - } - sem.signal() - } - task.resume() - sem.wait() - - return status - } - - public func flush(explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode { - return .success - } - - public func shutdown(explicitTimeout: TimeInterval? = nil) {} - - func encodeSpans(spans: [SpanData]) -> [ZipkinSpan] { - return spans.map { ZipkinConversionExtension.toZipkinSpan(otelSpan: $0, defaultLocalEndpoint: localEndPoint) } - } - - static func getLocalZipkinEndpoint(name: String? = nil) -> ZipkinEndpoint { - let hostname = name ?? ProcessInfo.processInfo.hostName - #if os(OSX) - let ipv4 = Host.current().addresses.filter { NetworkUtils.isValidIpv4Address($0) }.sorted().first - let ipv6 = Host.current().addresses.filter { NetworkUtils.isValidIpv6Address($0) }.sorted().first - return ZipkinEndpoint(serviceName: hostname, ipv4: ipv4, ipv6: ipv6, port: nil) - #else - return ZipkinEndpoint(serviceName: hostname) - #endif - } -} diff --git a/Sources/Exporters/Zipkin/ZipkinTraceExporterOptions.swift b/Sources/Exporters/Zipkin/ZipkinTraceExporterOptions.swift deleted file mode 100644 index d4d03836..00000000 --- a/Sources/Exporters/Zipkin/ZipkinTraceExporterOptions.swift +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public struct ZipkinTraceExporterOptions { - let endpoint: String - let timeoutSeconds: TimeInterval - let serviceName: String - let useShortTraceIds: Bool - let additionalHeaders: [String: String] - - public init(endpoint: String = "http://localhost:9411/api/v2/spans", - serviceName: String = "Open Telemetry Exporter", - timeoutSeconds: TimeInterval = 10.0, - useShortTraceIds: Bool = false, - additionalHeaders: [String: String] = [String: String]()) { - self.endpoint = endpoint - self.serviceName = serviceName - self.timeoutSeconds = timeoutSeconds - self.useShortTraceIds = useShortTraceIds - self.additionalHeaders = additionalHeaders - } -} diff --git a/Sources/Importers/OpenTracingShim/BaseShimProtocol.swift b/Sources/Importers/OpenTracingShim/BaseShimProtocol.swift deleted file mode 100644 index 12f1b813..00000000 --- a/Sources/Importers/OpenTracingShim/BaseShimProtocol.swift +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -protocol BaseShimProtocol { - var telemetryInfo: TelemetryInfo { get } -} - -extension BaseShimProtocol { - var tracer: Tracer { - return telemetryInfo.tracer - } - - var spanContextTable: SpanContextShimTable { - return telemetryInfo.spanContextTable - } - - var baggageManager: BaggageManager { - return telemetryInfo.baggageManager - } - - var propagators: ContextPropagators { - return telemetryInfo.propagators - } -} diff --git a/Sources/Importers/OpenTracingShim/Locks.swift b/Sources/Importers/OpenTracingShim/Locks.swift deleted file mode 100644 index 772cf2e3..00000000 --- a/Sources/Importers/OpenTracingShim/Locks.swift +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -// ===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Metrics API open source project -// -// Copyright (c) 2018-2019 Apple Inc. and the Swift Metrics API project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Metrics API project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -// ===----------------------------------------------------------------------===// - -// ===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftNIO project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -// ===----------------------------------------------------------------------===// - -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) - import Darwin -#elseif canImport(Glibc) - import Glibc -#elseif canImport(Musl) - import Musl -#else - #error("Unsupported platform") -#endif - -/// A threading lock based on `libpthread` instead of `libdispatch`. -/// -/// This object provides a lock on top of a single `pthread_mutex_t`. This kind -/// of lock is safe to use with `libpthread`-based threading models, such as the -/// one used by NIO. -final class Lock { - private let mutex: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: 1) - - /// Create a new lock. - public init() { - let err = pthread_mutex_init(mutex, nil) - precondition(err == 0, "pthread_mutex_init failed with error \(err)") - } - - deinit { - let err = pthread_mutex_destroy(self.mutex) - precondition(err == 0, "pthread_mutex_destroy failed with error \(err)") - self.mutex.deallocate() - } - - /// Acquire the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lock() { - let err = pthread_mutex_lock(mutex) - precondition(err == 0, "pthread_mutex_lock failed with error \(err)") - } - - /// Release the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `lock`, to simplify lock handling. - public func unlock() { - let err = pthread_mutex_unlock(mutex) - precondition(err == 0, "pthread_mutex_unlock failed with error \(err)") - } -} - -extension Lock { - /// Acquire the lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withLock(_ body: () throws -> T) rethrows -> T { - lock() - defer { - self.unlock() - } - return try body() - } - - // specialise Void return (for performance) - @inlinable - func withLockVoid(_ body: () throws -> Void) rethrows { - try withLock(body) - } -} - -/// A threading lock based on `libpthread` instead of `libdispatch`. -/// -/// This object provides a lock on top of a single `pthread_mutex_t`. This kind -/// of lock is safe to use with `libpthread`-based threading models, such as the -/// one used by NIO. -final class ReadWriteLock { - private let rwlock: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: 1) - - /// Create a new lock. - public init() { - let err = pthread_rwlock_init(rwlock, nil) - precondition(err == 0, "pthread_rwlock_init failed with error \(err)") - } - - deinit { - let err = pthread_rwlock_destroy(self.rwlock) - precondition(err == 0, "pthread_rwlock_destroy failed with error \(err)") - self.rwlock.deallocate() - } - - /// Acquire a reader lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lockRead() { - let err = pthread_rwlock_rdlock(rwlock) - precondition(err == 0, "pthread_rwlock_rdlock failed with error \(err)") - } - - /// Acquire a writer lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lockWrite() { - let err = pthread_rwlock_wrlock(rwlock) - precondition(err == 0, "pthread_rwlock_wrlock failed with error \(err)") - } - - /// Release the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `lock`, to simplify lock handling. - public func unlock() { - let err = pthread_rwlock_unlock(rwlock) - precondition(err == 0, "pthread_rwlock_unlock failed with error \(err)") - } -} - -extension ReadWriteLock { - /// Acquire the reader lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withReaderLock(_ body: () throws -> T) rethrows -> T { - lockRead() - defer { - self.unlock() - } - return try body() - } - - /// Acquire the writer lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withWriterLock(_ body: () throws -> T) rethrows -> T { - lockWrite() - defer { - self.unlock() - } - return try body() - } - - // specialise Void return (for performance) - @inlinable - func withReaderLockVoid(_ body: () throws -> Void) rethrows { - try withReaderLock(body) - } - - // specialise Void return (for performance) - @inlinable - func withWriterLockVoid(_ body: () throws -> Void) rethrows { - try withWriterLock(body) - } -} diff --git a/Sources/Importers/OpenTracingShim/Propagation.swift b/Sources/Importers/OpenTracingShim/Propagation.swift deleted file mode 100644 index 9a3c433e..00000000 --- a/Sources/Importers/OpenTracingShim/Propagation.swift +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -public class Propagation: BaseShimProtocol { - var telemetryInfo: TelemetryInfo - - init(telemetryInfo: TelemetryInfo) { - self.telemetryInfo = telemetryInfo - } - - public func injectTextFormat(contextShim: SpanContextShim, carrier: NSMutableDictionary) { - var newEntries = [String: String]() - propagators.textMapPropagator.inject(spanContext: contextShim.context, carrier: &newEntries, setter: TextMapSetter()) - carrier.addEntries(from: newEntries) - } - - public func extractTextFormat(carrier: [String: String]) -> SpanContextShim? { - guard let currentBaggage = OpenTelemetry.instance.contextProvider.activeBaggage else { return nil } - let context = propagators.textMapPropagator.extract(carrier: carrier, getter: TextMapGetter()) - if !(context?.isValid ?? false) { - return nil - } - return SpanContextShim(telemetryInfo: telemetryInfo, context: context!, baggage: currentBaggage) - } -} - -struct TextMapSetter: Setter { - func set(carrier: inout [String: String], key: String, value: String) { - carrier[key] = value - } -} - -struct TextMapGetter: Getter { - func get(carrier: [String: String], key: String) -> [String]? { - if let value = carrier[key] { - return [value] - } - return nil - } -} diff --git a/Sources/Importers/OpenTracingShim/README.md b/Sources/Importers/OpenTracingShim/README.md deleted file mode 100644 index e8e8f830..00000000 --- a/Sources/Importers/OpenTracingShim/README.md +++ /dev/null @@ -1,4 +0,0 @@ -### OpenTracingShim - -An OpenTracing implementation that delegates to the OpenTelemetry SDK. Use OpenTracingShim to create tracers using this implementation. - diff --git a/Sources/Importers/OpenTracingShim/SpanContextShim.swift b/Sources/Importers/OpenTracingShim/SpanContextShim.swift deleted file mode 100644 index 3e6dcf34..00000000 --- a/Sources/Importers/OpenTracingShim/SpanContextShim.swift +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import Opentracing - -public class SpanContextShim: OTSpanContext, BaseShimProtocol { - var telemetryInfo: TelemetryInfo - public private(set) var context: SpanContext - public private(set) var baggage: Baggage? - - init(telemetryInfo: TelemetryInfo, context: SpanContext, baggage: Baggage?) { - self.telemetryInfo = telemetryInfo - self.context = context - self.baggage = baggage - } - - convenience init(spanShim: SpanShim) { - self.init(telemetryInfo: spanShim.telemetryInfo, context: spanShim.span.context, baggage: spanShim.telemetryInfo.emptyBaggage) - } - - convenience init(telemetryInfo: TelemetryInfo, context: SpanContext) { - self.init(telemetryInfo: telemetryInfo, context: context, baggage: telemetryInfo.emptyBaggage) - } - - func newWith(key: String, value: String) -> SpanContextShim { - let baggageBuilder = baggageManager.baggageBuilder() - baggageBuilder.setParent(baggage) - baggageBuilder.put(key: EntryKey(name: key)!, value: EntryValue(string: value)!, metadata: nil) - - return SpanContextShim(telemetryInfo: telemetryInfo, context: context, baggage: baggageBuilder.build()) - } - - func getBaggageItem(key: String) -> String? { - guard let key = EntryKey(name: key) else { return nil } - let value = baggage?.getEntryValue(key: key) - return value?.string - } - - public func forEachBaggageItem(_ callback: @escaping (String, String) -> Bool) { - let entries = baggage?.getEntries() - entries?.forEach { - if !callback($0.key.name, $0.value.string) { - return - } - } - } -} - -extension SpanContextShim: Equatable { - public static func == (lhs: SpanContextShim, rhs: SpanContextShim) -> Bool { - if let lbaggage = lhs.baggage, let rbaggage = rhs.baggage { - return lbaggage == rbaggage && lhs.context == rhs.context - } else { - return lhs.baggage == nil && rhs.baggage == nil && lhs.context == rhs.context - } - } -} diff --git a/Sources/Importers/OpenTracingShim/SpanContextShimTable.swift b/Sources/Importers/OpenTracingShim/SpanContextShimTable.swift deleted file mode 100644 index 1875af98..00000000 --- a/Sources/Importers/OpenTracingShim/SpanContextShimTable.swift +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -public class SpanContextShimTable { - private let lock = ReadWriteLock() - private var shimsMap = [SpanContext: SpanContextShim]() - - public func setBaggageItem(spanShim: SpanShim, key: String, value: String) { - lock.withWriterLockVoid { - var contextShim = shimsMap[spanShim.span.context] - if contextShim == nil { - contextShim = SpanContextShim(spanShim: spanShim) - } - - contextShim = contextShim?.newWith(key: key, value: value) - shimsMap[spanShim.span.context] = contextShim - } - } - - public func getBaggageItem(spanShim: SpanShim, key: String) -> String? { - lock.withReaderLock { - let contextShim = shimsMap[spanShim.span.context] - return contextShim?.getBaggageItem(key: key) - } - } - - public func get(spanShim: SpanShim) -> SpanContextShim? { - lock.withReaderLock { - shimsMap[spanShim.span.context] - } - } - - public func create(spanShim: SpanShim) -> SpanContextShim { - return create(spanShim: spanShim, distContext: spanShim.telemetryInfo.emptyBaggage) - } - - @discardableResult public func create(spanShim: SpanShim, distContext: Baggage?) -> SpanContextShim { - lock.withWriterLock { - var contextShim = shimsMap[spanShim.span.context] - if contextShim != nil { - return contextShim! - } - - contextShim = SpanContextShim(telemetryInfo: spanShim.telemetryInfo, context: spanShim.span.context, baggage: distContext) - shimsMap[spanShim.span.context] = contextShim - return contextShim! - } - } -} diff --git a/Sources/Importers/OpenTracingShim/SpanShim.swift b/Sources/Importers/OpenTracingShim/SpanShim.swift deleted file mode 100644 index 5d3aab8f..00000000 --- a/Sources/Importers/OpenTracingShim/SpanShim.swift +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import Opentracing - -public class SpanShim: OTSpan, BaseShimProtocol { - static let defaultEventName = "log" - - static let OpenTracingErrorTag = "error" - static let OpenTracingEventField = "event" - - public private(set) var span: Span - var telemetryInfo: TelemetryInfo - - init(telemetryInfo: TelemetryInfo, span: Span) { - self.telemetryInfo = telemetryInfo - self.span = span - } - - public func context() -> OTSpanContext { - var contextShim = spanContextTable.get(spanShim: self) - if contextShim == nil { - contextShim = spanContextTable.create(spanShim: self) - } - return contextShim! - } - - public func tracer() -> OTTracer { - return TraceShim.instance.otTracer - } - - public func setOperationName(_ operationName: String) { - span.name = operationName - } - - public func setTag(_ key: String, value: String) { - if key == SpanShim.OpenTracingErrorTag { - let error = Bool(value) ?? false - span.status = error ? .error(description: "error") : .ok - } else { - span.setAttribute(key: key, value: value) - } - } - - public func setTag(_ key: String, numberValue value: NSNumber) { - let numberType = CFNumberGetType(value) - - switch numberType { - case .charType: - span.setAttribute(key: key, value: value.boolValue) - case .sInt8Type, .sInt16Type, .sInt32Type, .sInt64Type, .shortType, .intType, .longType, .longLongType, .cfIndexType, .nsIntegerType: - span.setAttribute(key: key, value: value.intValue) - case .float32Type, .float64Type, .floatType, .doubleType, .cgFloatType: - span.setAttribute(key: key, value: value.doubleValue) - @unknown default: - span.setAttribute(key: key, value: value.doubleValue) - } - } - - public func setTag(_ key: String, boolValue value: Bool) { - if key == SpanShim.OpenTracingErrorTag { - span.status = value ? .error(description: "error") : .ok - } else { - span.setAttribute(key: key, value: value) - } - } - - public func log(_ fields: [String: NSObject]) { - span.addEvent(name: SpanShim.getEventNameFrom(fields: fields), attributes: SpanShim.convertToAttributes(fields: fields)) - } - - public func log(_ fields: [String: NSObject], timestamp: Date?) { - span.addEvent(name: SpanShim.getEventNameFrom(fields: fields), attributes: SpanShim.convertToAttributes(fields: fields), timestamp: timestamp ?? Date()) - } - - public func logEvent(_ eventName: String) { - span.addEvent(name: eventName) - } - - public func logEvent(_ eventName: String, payload: NSObject?) { - if let object = payload { - span.addEvent(name: eventName, attributes: SpanShim.convertToAttributes(fields: [eventName: object])) - } else { - span.addEvent(name: eventName) - } - } - - public func log(_ eventName: String, timestamp: Date?, payload: NSObject?) { - if let object = payload { - span.addEvent(name: eventName, attributes: SpanShim.convertToAttributes(fields: [eventName: object]), timestamp: timestamp ?? Date()) - } else { - span.addEvent(name: eventName, timestamp: timestamp ?? Date()) - } - } - - public func setBaggageItem(_ key: String, value: String) -> OTSpan { - spanContextTable.setBaggageItem(spanShim: self, key: key, value: value) - return self - } - - public func getBaggageItem(_ key: String) -> String? { - return spanContextTable.getBaggageItem(spanShim: self, key: key) - } - - public func finish() { - span.end() - } - - public func finish(withTime finishTime: Date?) { - if let finishTime { - span.end(time: finishTime) - } else { - span.end() - } - } - - static func getEventNameFrom(fields: [String: NSObject]) -> String { - return fields[OpenTracingEventField]?.description ?? defaultEventName - } - - static func convertToAttributes(fields: [String: NSObject]) -> [String: AttributeValue] { - let attributes: [String: AttributeValue] = fields.mapValues { value in - if (value as? NSString) != nil { - return AttributeValue.string(value as! String) - } else if (value as? NSNumber) != nil { - let number = value as! NSNumber - let numberType = CFNumberGetType(number) - - switch numberType { - case .charType: - return AttributeValue.bool(number.boolValue) - case .sInt8Type, .sInt16Type, .sInt32Type, .sInt64Type, .shortType, .intType, .longType, .longLongType, .cfIndexType, .nsIntegerType: - return AttributeValue.int(number.intValue) - case .float32Type, .float64Type, .floatType, .doubleType, .cgFloatType: - return AttributeValue.double(number.doubleValue) - @unknown default: - return AttributeValue.double(number.doubleValue) - } - } else { - return AttributeValue.string("") - } - } - return attributes - } -} diff --git a/Sources/Importers/OpenTracingShim/TelemetryInfo.swift b/Sources/Importers/OpenTracingShim/TelemetryInfo.swift deleted file mode 100644 index f5313ef0..00000000 --- a/Sources/Importers/OpenTracingShim/TelemetryInfo.swift +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi - -struct TelemetryInfo { - var tracer: Tracer - var baggageManager: BaggageManager - var propagators: ContextPropagators - var emptyBaggage: Baggage? - var spanContextTable: SpanContextShimTable - - init(tracer: Tracer, baggageManager: BaggageManager, propagators: ContextPropagators) { - self.tracer = tracer - self.baggageManager = baggageManager - self.propagators = propagators - emptyBaggage = baggageManager.baggageBuilder().build() - spanContextTable = SpanContextShimTable() - } -} diff --git a/Sources/Importers/OpenTracingShim/TraceShim.swift b/Sources/Importers/OpenTracingShim/TraceShim.swift deleted file mode 100644 index 6855dffc..00000000 --- a/Sources/Importers/OpenTracingShim/TraceShim.swift +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import Opentracing - -public class TraceShim { - public static var instance = TraceShim() - - public private(set) var otTracer: OTTracer - - private init() { - otTracer = TraceShim.createTracerShim() - } - - public static func createTracerShim() -> OTTracer { - return TracerShim(telemetryInfo: TelemetryInfo(tracer: TraceShim.getTracer(tracerProvider: OpenTelemetry.instance.tracerProvider), - baggageManager: OpenTelemetry.instance.baggageManager, - propagators: OpenTelemetry.instance.propagators)) - } - - public static func createTracerShim(tracerProvider: TracerProvider, baggageManager: BaggageManager) -> OTTracer { - return TracerShim(telemetryInfo: TelemetryInfo(tracer: TraceShim.getTracer(tracerProvider: tracerProvider), - baggageManager: baggageManager, - propagators: OpenTelemetry.instance.propagators)) - } - - private static func getTracer(tracerProvider: TracerProvider) -> Tracer { - tracerProvider.get(instrumentationName: "opentracingshim") - } -} diff --git a/Sources/Importers/OpenTracingShim/TracerShim.swift b/Sources/Importers/OpenTracingShim/TracerShim.swift deleted file mode 100644 index 702746be..00000000 --- a/Sources/Importers/OpenTracingShim/TracerShim.swift +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import Opentracing - -public class TracerShim: OTTracer, BaseShimProtocol { - public static let OTReferenceChildOf = "child_of" - public static let OTReferenceFollowsFrom = "follows_from" - - enum InjectError: Error { - case injectError - case extractError - } - - var telemetryInfo: TelemetryInfo - let propagation: Propagation - - init(telemetryInfo: TelemetryInfo) { - self.telemetryInfo = telemetryInfo - propagation = Propagation(telemetryInfo: telemetryInfo) - } - - public func startSpan(_ operationName: String) -> OTSpan { - return startSpan(operationName, tags: nil) - } - - public func startSpan(_ operationName: String, tags: [AnyHashable: Any]?) -> OTSpan { - return startSpan(operationName, childOf: nil, tags: tags) - } - - public func startSpan(_ operationName: String, childOf parent: OTSpanContext?) -> OTSpan { - return startSpan(operationName, childOf: parent, tags: nil) - } - - public func startSpan(_ operationName: String, childOf parent: OTSpanContext?, tags: [AnyHashable: Any]?) -> OTSpan { - return startSpan(operationName, childOf: parent, tags: tags, startTime: nil) - } - - public func startSpan(_ operationName: String, childOf parent: OTSpanContext?, tags: [AnyHashable: Any]?, startTime: Date?) -> OTSpan { - var baggage: Baggage? - let builder = tracer.spanBuilder(spanName: operationName) - if let parent = parent as? SpanContextShim { - builder.setParent(parent.context) - baggage = parent.baggage - } - - if let tags = tags as? [String: NSObject] { - let attributes = SpanShim.convertToAttributes(fields: tags) - attributes.forEach { - builder.setAttribute(key: $0.key, value: $0.value) - } - } - - if let startTime { - builder.setStartTime(time: startTime) - } - - let span = builder.setActive(true).startSpan() - let spanShim = SpanShim(telemetryInfo: telemetryInfo, span: span) - if let baggage { - spanContextTable.create(spanShim: spanShim, distContext: baggage) - } - return spanShim - } - - public func startSpan(_ operationName: String, references: [Any]?, tags: [AnyHashable: Any]?, startTime: Date?) -> OTSpan { - var parent: OTSpanContext? - if references != nil { - for object in references! { - if let ref = object as? OTReference, - ref.type == TracerShim.OTReferenceChildOf || ref.type == TracerShim.OTReferenceFollowsFrom { - parent = ref.referencedContext - } - } - } - return startSpan(operationName, childOf: parent, tags: tags, startTime: nil) - } - - public func inject(_ spanContext: OTSpanContext, format: String, carrier: Any) -> Bool { - if let contextShim = spanContext as? SpanContextShim, - let dict = carrier as? NSMutableDictionary, - format == OTFormatTextMap || format == OTFormatBinary { - propagation.injectTextFormat(contextShim: contextShim, carrier: dict) - return true - } else { - return false - } - } - - public func extract(withFormat format: String, carrier: Any) -> OTSpanContext? { - if format == OTFormatTextMap || format == OTFormatBinary, - let carrier = carrier as? [String: String] { - return propagation.extractTextFormat(carrier: carrier) - } else { - return nil - } - } - - public func inject(spanContext: OTSpanContext, format: String, carrier: Any) throws { - if let contextShim = spanContext as? SpanContextShim, - let dict = carrier as? NSMutableDictionary, - format == OTFormatTextMap || format == OTFormatBinary { - propagation.injectTextFormat(contextShim: contextShim, carrier: dict) - } else { - throw InjectError.injectError - } - } - - public func extractWithFormat(format: String, carrier: Any) throws -> OTSpanContext { - if format == OTFormatTextMap || format == OTFormatBinary, - let carrier = carrier as? [String: String], - let context = propagation.extractTextFormat(carrier: carrier) { - return context - } else { - throw InjectError.extractError - } - } -} diff --git a/Sources/Importers/SwiftMetricsShim/Extensions.swift b/Sources/Importers/SwiftMetricsShim/Extensions.swift deleted file mode 100644 index 788c2b5d..00000000 --- a/Sources/Importers/SwiftMetricsShim/Extensions.swift +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import CoreMetrics - -extension [(String, String)] { - var dictionary: [String: String] { - Dictionary(self, uniquingKeysWith: { lhs, _ in lhs }) - } -} diff --git a/Sources/Importers/SwiftMetricsShim/Locks.swift b/Sources/Importers/SwiftMetricsShim/Locks.swift deleted file mode 100644 index a170c23b..00000000 --- a/Sources/Importers/SwiftMetricsShim/Locks.swift +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -// ===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Metrics API open source project -// -// Copyright (c) 2018-2019 Apple Inc. and the Swift Metrics API project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Metrics API project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -// ===----------------------------------------------------------------------===// - -// ===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftNIO project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -// ===----------------------------------------------------------------------===// - -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) - import Darwin -#elseif canImport(Glibc) - import Glibc -#elseif canImport(Musl) - import Musl -#else - #error("Unsupported platform") -#endif - -/// A threading lock based on `libpthread` instead of `libdispatch`. -/// -/// This object provides a lock on top of a single `pthread_mutex_t`. This kind -/// of lock is safe to use with `libpthread`-based threading models, such as the -/// one used by NIO. -final class Lock { - private let mutex: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: 1) - - /// Create a new lock. - public init() { - let err = pthread_mutex_init(mutex, nil) - precondition(err == 0, "pthread_mutex_init failed with error \(err)") - } - - deinit { - let err = pthread_mutex_destroy(self.mutex) - precondition(err == 0, "pthread_mutex_destroy failed with error \(err)") - self.mutex.deallocate() - } - - /// Acquire the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lock() { - let err = pthread_mutex_lock(mutex) - precondition(err == 0, "pthread_mutex_lock failed with error \(err)") - } - - /// Release the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `lock`, to simplify lock handling. - public func unlock() { - let err = pthread_mutex_unlock(mutex) - precondition(err == 0, "pthread_mutex_unlock failed with error \(err)") - } -} - -extension Lock { - /// Acquire the lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withLock(_ body: () throws -> T) rethrows -> T { - lock() - defer { - self.unlock() - } - return try body() - } - - // specialise Void return (for performance) - @inlinable - func withLockVoid(_ body: () throws -> Void) rethrows { - try withLock(body) - } -} - -/// A threading lock based on `libpthread` instead of `libdispatch`. -/// -/// This object provides a lock on top of a single `pthread_mutex_t`. This kind -/// of lock is safe to use with `libpthread`-based threading models, such as the -/// one used by NIO. -final class ReadWriteLock { - private let rwlock: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: 1) - - /// Create a new lock. - public init() { - let err = pthread_rwlock_init(rwlock, nil) - precondition(err == 0, "pthread_rwlock_init failed with error \(err)") - } - - deinit { - let err = pthread_rwlock_destroy(self.rwlock) - precondition(err == 0, "pthread_rwlock_destroy failed with error \(err)") - self.rwlock.deallocate() - } - - /// Acquire a reader lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lockRead() { - let err = pthread_rwlock_rdlock(rwlock) - precondition(err == 0, "pthread_rwlock_rdlock failed with error \(err)") - } - - /// Acquire a writer lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `unlock`, to simplify lock handling. - public func lockWrite() { - let err = pthread_rwlock_wrlock(rwlock) - precondition(err == 0, "pthread_rwlock_wrlock failed with error \(err)") - } - - /// Release the lock. - /// - /// Whenever possible, consider using `withLock` instead of this method and - /// `lock`, to simplify lock handling. - public func unlock() { - let err = pthread_rwlock_unlock(rwlock) - precondition(err == 0, "pthread_rwlock_unlock failed with error \(err)") - } -} - -extension ReadWriteLock { - /// Acquire the reader lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withReaderLock(_ body: () throws -> T) rethrows -> T { - lockRead() - defer { - self.unlock() - } - return try body() - } - - /// Acquire the writer lock for the duration of the given block. - /// - /// This convenience method should be preferred to `lock` and `unlock` in - /// most situations, as it ensures that the lock will be released regardless - /// of how `body` exits. - /// - /// - Parameter body: The block to execute while holding the lock. - /// - Returns: The value returned by the block. - @inlinable - func withWriterLock(_ body: () throws -> T) rethrows -> T { - lockWrite() - defer { - self.unlock() - } - return try body() - } - - // specialise Void return (for performance) - @inlinable - func withReaderLockVoid(_ body: () throws -> Void) rethrows { - try withReaderLock(body) - } - - // specialise Void return (for performance) - @inlinable - func withWriterLockVoid(_ body: () throws -> Void) rethrows { - try withWriterLock(body) - } -} - -public final class Locked : @unchecked Sendable { - - private var internalValue: Value - - private let lock = Lock() - - public var protectedValue: Value { - get { - lock.withLock { internalValue } - } - _modify { - lock.lock() - defer { lock.unlock() } - yield &internalValue - } - } - - public init(initialValue: Value) { - self.internalValue = initialValue - } - - public func locking(_ block: (inout Value) throws -> T) rethrows -> T { - try lock.withLock { try block(&internalValue) } - } -} diff --git a/Sources/Importers/SwiftMetricsShim/MetricHandlers.swift b/Sources/Importers/SwiftMetricsShim/MetricHandlers.swift deleted file mode 100644 index fa2997d6..00000000 --- a/Sources/Importers/SwiftMetricsShim/MetricHandlers.swift +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import CoreMetrics -import OpenTelemetryApi - -class SwiftCounterMetric: CounterHandler, SwiftMetric { - let metricName: String - let metricType: MetricType = .counter - let counter: Locked - let labels: [String: AttributeValue] - - required init(name: String, - labels: [String: String], - meter: any OpenTelemetryApi.Meter) { - metricName = name - counter = .init(initialValue: meter.counterBuilder(name: name).build()) - self.labels = labels.mapValues { value in - return AttributeValue.string(value) - } - } - - func increment(by: Int64) { - counter.protectedValue.add(value: Int(by), attributes: labels) - } - - func reset() {} -} - -class SwiftGaugeMetric: RecorderHandler, SwiftMetric { - let metricName: String - let metricType: MetricType = .gauge - var counter: DoubleGauge - let labels: [String: AttributeValue] - - required init(name: String, - labels: [String: String], - meter: any OpenTelemetryApi.Meter) { - metricName = name - counter = meter.gaugeBuilder(name: name).build() - self.labels = labels.mapValues { value in - return AttributeValue.string(value) - } - } - - func record(_ value: Int64) { - counter.record(value: Double(value), attributes: labels) - } - - func record(_ value: Double) { - counter.record(value: value, attributes: labels) - } -} - -class SwiftHistogramMetric: RecorderHandler, SwiftMetric { - let metricName: String - let metricType: MetricType = .histogram - var measure: DoubleHistogram - let labels: [String: AttributeValue] - - required init(name: String, labels: [String: String], meter: any OpenTelemetryApi.Meter) { - metricName = name - measure = meter.histogramBuilder(name: name).build() - self.labels = labels.mapValues { value in - return AttributeValue.string(value) - } - } - - func record(_ value: Int64) { - measure.record(value: Double(value), attributes: labels) - } - - func record(_ value: Double) { - measure.record(value: value, attributes: labels) - } -} - -class SwiftSummaryMetric: TimerHandler, SwiftMetric { - let metricName: String - let metricType: MetricType = .summary - var measure: DoubleCounter - let labels: [String: AttributeValue] - - required init(name: String, labels: [String: String], meter: any OpenTelemetryApi.Meter) { - metricName = name - measure = meter.counterBuilder(name: name).ofDoubles().build() - self.labels = labels.mapValues { value in - return AttributeValue.string(value) - } - } - - func recordNanoseconds(_ duration: Int64) { - measure.add(value: Double(duration), attributes: labels) - } -} - -protocol SwiftMetric { - var metricName: String { get } - var metricType: MetricType { get } - init(name: String, labels: [String: String], meter: any OpenTelemetryApi.Meter) -} - -enum MetricType: String { - case counter - case histogram - case gauge - case summary -} - -struct MetricKey: Hashable { - let name: String - let type: MetricType -} diff --git a/Sources/Importers/SwiftMetricsShim/README.md b/Sources/Importers/SwiftMetricsShim/README.md deleted file mode 100644 index a2d50cb6..00000000 --- a/Sources/Importers/SwiftMetricsShim/README.md +++ /dev/null @@ -1,11 +0,0 @@ -### SwiftMetricsShim - -Apple have created their own metrics API which has been adopted by a number of other packages including, but not limited to, Vapor - a prominent Server Side Swift platform. - -This shim essentially redirects the data to the OpenTelemetry API functions. - - ``` -let meter: Meter = // ... Your existing code to create a meter -let metrics = OpenTelemetrySwiftMetrics(meter: meter) -MetricsSystem.bootstrap(metrics) -``` diff --git a/Sources/Importers/SwiftMetricsShim/SwiftMetricsShim.swift b/Sources/Importers/SwiftMetricsShim/SwiftMetricsShim.swift deleted file mode 100644 index 4702e8c6..00000000 --- a/Sources/Importers/SwiftMetricsShim/SwiftMetricsShim.swift +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import CoreMetrics -import OpenTelemetryApi - -public class OpenTelemetrySwiftMetrics: MetricsFactory { - let meter: any OpenTelemetryApi.Meter - var metrics = [MetricKey: SwiftMetric]() - let lock = Lock() - - public init(meter: any OpenTelemetryApi.Meter) { - self.meter = meter - } - - // MARK: - Make - - /// Counter: A counter is a cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on - /// restart. For example, you can use a counter to represent the number of requests served, tasks completed, or errors. - public func makeCounter(label: String, dimensions: [(String, String)]) -> CounterHandler { - lock.withLock { - if let existing = metrics[.init(name: label, type: .counter)] { - return existing as! CounterHandler - } - - let metric = SwiftCounterMetric(name: label, labels: dimensions.dictionary, meter: meter) - - storeMetric(metric) - return metric - } - } - - /// Recorder: A recorder collects observations within a time window (usually things like response sizes) and can provide aggregated information about the - /// data sample, for example count, sum, min, max and various quantiles. - /// - /// Gauge: A Gauge is a metric that represents a single numerical value that can arbitrarily go up and down. Gauges are typically used for measured values - /// like temperatures or current memory usage, but also "counts" that can go up and down, like the number of active threads. Gauges are modeled as a - /// Recorder with a sample size of 1 that does not perform any aggregation. - public func makeRecorder(label: String, dimensions: [(String, String)], aggregate: Bool) -> RecorderHandler { - lock.withLock { - if let existing = metrics[.init(name: label, type: .histogram)] { - return existing as! RecorderHandler - } - - if let existing = metrics[.init(name: label, type: .gauge)] { - return existing as! RecorderHandler - } - - let metric: SwiftMetric & RecorderHandler = aggregate ? - SwiftHistogramMetric(name: label, labels: dimensions.dictionary, meter: meter) : - SwiftGaugeMetric(name: label, labels: dimensions.dictionary, meter: meter) - - storeMetric(metric) - return metric - } - } - - /// Timer: A timer collects observations within a time window (usually things like request duration) and provides aggregated information about the data sample, - /// for example min, max and various quantiles. It is similar to a Recorder but specialized for values that represent durations. - public func makeTimer(label: String, dimensions: [(String, String)]) -> TimerHandler { - lock.withLock { - if let existing = metrics[.init(name: label, type: .summary)] { - return existing as! TimerHandler - } - - let metric = SwiftSummaryMetric(name: label, labels: dimensions.dictionary, meter: meter) - - storeMetric(metric) - return metric - } - } - - private func storeMetric(_ metric: SwiftMetric) { - metrics[.init(name: metric.metricName, type: metric.metricType)] = metric - } - - // MARK: - Destroy - - public func destroyCounter(_ handler: CounterHandler) { - destroyMetric(handler as? SwiftMetric) - } - - public func destroyRecorder(_ handler: RecorderHandler) { - destroyMetric(handler as? SwiftMetric) - } - - public func destroyTimer(_ handler: TimerHandler) { - destroyMetric(handler as? SwiftMetric) - } - - private func destroyMetric(_ metric: SwiftMetric?) { - lock.withLock { - if let name = metric?.metricName, let type = metric?.metricType { - metrics.removeValue(forKey: .init(name: name, type: type)) - } - } - } -} diff --git a/Sources/Instrumentation/NetworkStatus/NetworkMonitor.swift b/Sources/Instrumentation/NetworkStatus/NetworkMonitor.swift deleted file mode 100644 index 1f19cf4d..00000000 --- a/Sources/Instrumentation/NetworkStatus/NetworkMonitor.swift +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if !os(watchOS) - - import Foundation - - import Network - - public class NetworkMonitor: NetworkMonitorProtocol { - let monitor = NWPathMonitor() - var connection: Connection = .unavailable - let monitorQueue = DispatchQueue(label: "OTel-Network-Monitor") - let lock = NSLock() - - deinit { - monitor.cancel() - } - - public init() throws { - let pathHandler = { (path: NWPath) in - let availableInterfaces = path.availableInterfaces - let wifiInterface = self.getWifiInterface(interfaces: availableInterfaces) - let cellInterface = self.getCellInterface(interfaces: availableInterfaces) - var availableInterface: Connection = .unavailable - if cellInterface != nil { - availableInterface = .cellular - } - if wifiInterface != nil { - availableInterface = .wifi - } - self.lock.lock() - switch path.status { - case .requiresConnection, .satisfied: - self.connection = availableInterface - case .unsatisfied: - self.connection = .unavailable - @unknown default: - fatalError() - } - self.lock.unlock() - } - monitor.pathUpdateHandler = pathHandler - monitor.start(queue: monitorQueue) - } - - public func getConnection() -> Connection { - lock.lock() - defer { - lock.unlock() - } - return connection - } - - func getCellInterface(interfaces: [NWInterface]) -> NWInterface? { - var foundInterface: NWInterface? - interfaces.forEach { interface in - if interface.type == .cellular { - foundInterface = interface - } - } - return foundInterface - } - - func getWifiInterface(interfaces: [NWInterface]) -> NWInterface? { - var foundInterface: NWInterface? - interfaces.forEach { interface in - if interface.type == .wifi { - foundInterface = interface - } - } - return foundInterface - } - } - -#endif diff --git a/Sources/Instrumentation/NetworkStatus/NetworkMonitorProtocol.swift b/Sources/Instrumentation/NetworkStatus/NetworkMonitorProtocol.swift deleted file mode 100644 index 52e1bbe3..00000000 --- a/Sources/Instrumentation/NetworkStatus/NetworkMonitorProtocol.swift +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public enum Connection { - case unavailable, wifi, cellular -} - -public protocol NetworkMonitorProtocol { - func getConnection() -> Connection -} diff --git a/Sources/Instrumentation/NetworkStatus/NetworkStatus.swift b/Sources/Instrumentation/NetworkStatus/NetworkStatus.swift deleted file mode 100644 index a471b778..00000000 --- a/Sources/Instrumentation/NetworkStatus/NetworkStatus.swift +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(iOS) && !targetEnvironment(macCatalyst) - import CoreTelephony - import Foundation - import Network - - public class NetworkStatus { - public private(set) var networkInfo: CTTelephonyNetworkInfo - public private(set) var networkMonitor: NetworkMonitorProtocol - public convenience init() throws { - try self.init(with: NetworkMonitor()) - } - - public init(with monitor: NetworkMonitorProtocol, info: CTTelephonyNetworkInfo = CTTelephonyNetworkInfo()) { - networkMonitor = monitor - networkInfo = info - } - - public func status() -> (String, String?, CTCarrier?) { - switch networkMonitor.getConnection() { - case .wifi: - return ("wifi", nil, nil) - case .cellular: - if #available(iOS 13.0, *) { - if let serviceId = networkInfo.dataServiceIdentifier, let value = networkInfo.serviceCurrentRadioAccessTechnology?[serviceId] { - return ("cell", simpleConnectionName(connectionType: value), networkInfo.serviceSubscriberCellularProviders?[networkInfo.dataServiceIdentifier!]) - } - } else { - if let radioType = networkInfo.currentRadioAccessTechnology { - return ("cell", simpleConnectionName(connectionType: radioType), networkInfo.subscriberCellularProvider) - } - } - return ("cell", "unknown", nil) - case .unavailable: - return ("unavailable", nil, nil) - } - } - - func simpleConnectionName(connectionType: String) -> String { - switch connectionType { - case "CTRadioAccessTechnologyEdge": - return "EDGE" - case "CTRadioAccessTechnologyCDMA1x": - return "CDMA" - case "CTRadioAccessTechnologyGPRS": - return "GPRS" - case "CTRadioAccessTechnologyWCDMA": - return "WCDMA" - case "CTRadioAccessTechnologyHSDPA": - return "HSDPA" - case "CTRadioAccessTechnologyHSUPA": - return "HSUPA" - case "CTRadioAccessTechnologyCDMAEVDORev0": - return "EVDO_0" - case "CTRadioAccessTechnologyCDMAEVDORevA": - return "EVDO_A" - case "CTRadioAccessTechnologyCDMAEVDORevB": - return "EVDO_B" - case "CTRadioAccessTechnologyeHRPD": - return "HRPD" - case "CTRadioAccessTechnologyLTE": - return "LTE" - case "CTRadioAccessTechnologyNRNSA": - return "NRNSA" - case "CTRadioAccessTechnologyNR": - return "NR" - default: - return "unknown" - } - } - } - -#endif // os(iOS) && !targetEnvironment(macCatalyst) diff --git a/Sources/Instrumentation/NetworkStatus/NetworkStatusInjector.swift b/Sources/Instrumentation/NetworkStatus/NetworkStatusInjector.swift deleted file mode 100644 index 23549ca1..00000000 --- a/Sources/Instrumentation/NetworkStatus/NetworkStatusInjector.swift +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(iOS) && !targetEnvironment(macCatalyst) - - import CoreTelephony - import Foundation - import Network - import OpenTelemetryApi - - public class NetworkStatusInjector { - private var netstat: NetworkStatus - - public init(netstat: NetworkStatus) { - self.netstat = netstat - } - - public func inject(span: Span) { - let (type, subtype, carrier) = netstat.status() - span.setAttribute(key: SemanticAttributes.networkConnectionType.rawValue, value: AttributeValue.string(type)) - - if let subtype: String = subtype { - span.setAttribute(key: SemanticAttributes.networkConnectionSubtype.rawValue, value: AttributeValue.string(subtype)) - } - - if let carrierInfo: CTCarrier = carrier { - if let carrierName = carrierInfo.carrierName { - span.setAttribute(key: SemanticAttributes.networkCarrierName.rawValue, value: AttributeValue.string(carrierName)) - } - - if let isoCountryCode = carrierInfo.isoCountryCode { - span.setAttribute(key: SemanticAttributes.networkCarrierIcc.rawValue, value: AttributeValue.string(isoCountryCode)) - } - - if let mobileCountryCode = carrierInfo.mobileCountryCode { - span.setAttribute(key: SemanticAttributes.networkCarrierMcc.rawValue, value: AttributeValue.string(mobileCountryCode)) - } - - if let mobileNetworkCode = carrierInfo.mobileNetworkCode { - span.setAttribute(key: SemanticAttributes.networkCarrierMnc.rawValue, value: AttributeValue.string(mobileNetworkCode)) - } - } - } - } - -#endif // os(iOS) && !targetEnvironment(macCatalyst) diff --git a/Sources/Instrumentation/NetworkStatus/NetworkStatusProtocol.swift b/Sources/Instrumentation/NetworkStatus/NetworkStatusProtocol.swift deleted file mode 100644 index 5855859c..00000000 --- a/Sources/Instrumentation/NetworkStatus/NetworkStatusProtocol.swift +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(iOS) && !targetEnvironment(macCatalyst) - - import CoreTelephony - import Foundation - - public protocol NetworkStatusProtocol { - var networkMonitor: NetworkMonitorProtocol { get } - func getStatus() -> (String, CTCarrier?) - } -#endif // os(iOS) && !targetEnvironment(macCatalyst) diff --git a/Sources/Instrumentation/SDKResourceExtension/ApplicationResourceProvider.swift b/Sources/Instrumentation/SDKResourceExtension/ApplicationResourceProvider.swift deleted file mode 100644 index f8d9812e..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/ApplicationResourceProvider.swift +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public class ApplicationResourceProvider: ResourceProvider { - let applicationDataSource: IApplicationDataSource - - public init(source: IApplicationDataSource) { - applicationDataSource = source - } - - override public var attributes: [String: AttributeValue] { - var attributes = [String: AttributeValue]() - - if let bundleName = applicationDataSource.name { - attributes[ResourceAttributes.serviceName.rawValue] = AttributeValue.string(bundleName) - } - - if let version = applicationVersion() { - attributes[ResourceAttributes.serviceVersion.rawValue] = AttributeValue.string(version) - } - - return attributes - } - - func applicationVersion() -> String? { - if let build = applicationDataSource.build { - if let version = applicationDataSource.version { - return "\(version) (\(build))" - } - return build - } else { - return applicationDataSource.version - } - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/ApplicationDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/ApplicationDataSource.swift deleted file mode 100644 index 7ba4316f..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/ApplicationDataSource.swift +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public class ApplicationDataSource: IApplicationDataSource { - public init() {} - - public var name: String? { - Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String - } - - public var identifier: String? { - Bundle.main.infoDictionary?[kCFBundleIdentifierKey as String] as? String - } - - public var version: String? { - Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String - } - - public var build: String? { - Bundle.main.infoDictionary?[kCFBundleVersionKey as String] as? String - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/DeviceDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/DeviceDataSource.swift deleted file mode 100644 index 218459d2..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/DeviceDataSource.swift +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -#if os(watchOS) - import WatchKit -#elseif os(macOS) - import AppKit -#else - import UIKit -#endif -public class DeviceDataSource: IDeviceDataSource { - public init() {} - - public var model: String? { - #if os(watchOS) - return WKInterfaceDevice.current().localizedModel - #else - let hwName = UnsafeMutablePointer.allocate(capacity: 2) - hwName[0] = CTL_HW - #if os(macOS) - hwName[1] = HW_MODEL - #else - hwName[1] = HW_MACHINE - #endif - - // Returned 'error #12: Optional("Cannot allocate memory")' because len was not initialized properly. - - let desiredLen = UnsafeMutablePointer.allocate(capacity: 1) - - sysctl(hwName, 2, nil, desiredLen, nil, 0) - - let machine = UnsafeMutablePointer.allocate(capacity: desiredLen[0]) - let len: UnsafeMutablePointer! = UnsafeMutablePointer.allocate(capacity: 1) - - defer { - hwName.deallocate() - desiredLen.deallocate() - machine.deallocate() - len.deallocate() - } - - len[0] = desiredLen[0] - - let modelRequestError = sysctl(hwName, 2, machine, len, nil, 0) - if modelRequestError != 0 { - // TODO: better error log - print("error #\(errno): \(String(describing: String(utf8String: strerror(errno))))") - - return nil - } - let machineName = String(cString: machine) - return machineName - #endif - } - - public var identifier: String? { - #if os(watchOS) - if #available(watchOS 6.3, *) { - return WKInterfaceDevice.current().identifierForVendor?.uuidString - } else { - return nil - } - #elseif os(macOS) - return nil - #else - return UIDevice.current.identifierForVendor?.uuidString - - #endif - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/IApplicationDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/IApplicationDataSource.swift deleted file mode 100644 index f9b2eac2..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/IApplicationDataSource.swift +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public protocol IApplicationDataSource { - var name: String? { get } - var identifier: String? { get } - var version: String? { get } - var build: String? { get } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/IDeviceDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/IDeviceDataSource.swift deleted file mode 100644 index 9a49317a..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/IDeviceDataSource.swift +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public protocol IDeviceDataSource { - var identifier: String? { get } - var model: String? { get } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/IOperatingSystemDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/IOperatingSystemDataSource.swift deleted file mode 100644 index db5af780..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/IOperatingSystemDataSource.swift +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public protocol IOperatingSystemDataSource { - var type: String { get } - var description: String { get } - var name: String { get } - var version: String { get } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/ITelemetryDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/ITelemetryDataSource.swift deleted file mode 100644 index bb5535bc..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/ITelemetryDataSource.swift +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -public protocol ITelemetryDataSource { - var version: String? { get } - var name: String { get } - var language: String { get } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/OperatingSystemDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/OperatingSystemDataSource.swift deleted file mode 100644 index 2344608f..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/OperatingSystemDataSource.swift +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ -#if os(watchOS) - import WatchKit -#elseif os(macOS) -#else - import UIKit -#endif - -import Foundation -import OpenTelemetrySdk - -public class OperatingSystemDataSource: IOperatingSystemDataSource { - public init() {} - public var description: String { - name + " " + ProcessInfo.processInfo.operatingSystemVersionString - } - - public var type: String { - ResourceAttributes.OsTypeValues.darwin.description - } - - public var name: String { - #if os(watchOS) - return "watchOS" - #elseif os(macOS) - return "macOS" - #else - return UIDevice.current.systemName - #endif - } - - public var version: String { - let version = ProcessInfo.processInfo.operatingSystemVersion - return "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)" - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DataSource/TelemetryDataSource.swift b/Sources/Instrumentation/SDKResourceExtension/DataSource/TelemetryDataSource.swift deleted file mode 100644 index d855d07a..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DataSource/TelemetryDataSource.swift +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -public class TelemetryDataSource: ITelemetryDataSource { - public init() {} - public var language: String { - ResourceAttributes.TelemetrySdkLanguageValues.swift.description - } - - public var name: String { - "opentelemetry" - } - - public var version: String? { - Resource.OTEL_SWIFT_SDK_VERSION - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DefaultResources.swift b/Sources/Instrumentation/SDKResourceExtension/DefaultResources.swift deleted file mode 100644 index a275fc1f..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DefaultResources.swift +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetrySdk - -public class DefaultResources { - // add new resource providers here - let application = ApplicationResourceProvider(source: ApplicationDataSource()) - let device = DeviceResourceProvider(source: DeviceDataSource()) - let os = OSResourceProvider(source: OperatingSystemDataSource()) - - let telemetry = TelemetryResourceProvider(source: TelemetryDataSource()) - - public init() {} - - public func get() -> Resource { - var resource = Resource() - let mirror = Mirror(reflecting: self) - for children in mirror.children { - if let provider = children.value as? ResourceProvider { - resource.merge(other: provider.create()) - } - } - return resource - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/DeviceResourceProvider.swift b/Sources/Instrumentation/SDKResourceExtension/DeviceResourceProvider.swift deleted file mode 100644 index d8c842b7..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/DeviceResourceProvider.swift +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -import OpenTelemetryApi -import OpenTelemetrySdk - -public class DeviceResourceProvider: ResourceProvider { - let deviceSource: IDeviceDataSource - - public init(source: IDeviceDataSource) { - deviceSource = source - } - - override public var attributes: [String: AttributeValue] { - var attributes = [String: AttributeValue]() - - if let deviceModel = deviceSource.model { - attributes[ResourceAttributes.deviceModelIdentifier.rawValue] = AttributeValue.string(deviceModel) - } - - if let deviceId = deviceSource.identifier { - attributes[ResourceAttributes.deviceId.rawValue] = AttributeValue.string(deviceId) - } - - return attributes - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/OSResourceProvider.swift b/Sources/Instrumentation/SDKResourceExtension/OSResourceProvider.swift deleted file mode 100644 index eca90949..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/OSResourceProvider.swift +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public class OSResourceProvider: ResourceProvider { - let osDataSource: IOperatingSystemDataSource - - public init(source: IOperatingSystemDataSource) { - osDataSource = source - } - - override public var attributes: [String: AttributeValue] { - var attributes = [String: AttributeValue]() - - attributes[ResourceAttributes.osType.rawValue] = .string(osDataSource.type) - attributes[ResourceAttributes.osName.rawValue] = .string(osDataSource.name) - attributes[ResourceAttributes.osDescription.rawValue] = .string(osDataSource.description) - attributes[ResourceAttributes.osVersion.rawValue] = .string(osDataSource.version) - - return attributes - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/README.md b/Sources/Instrumentation/SDKResourceExtension/README.md deleted file mode 100644 index 8bab6088..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# SDK Resource extension - -This package captures a number of key data points of an application and generates a Resource object that can be passed to a `TracerProvider` - - -## Usage - -Use `DefaultResource.get()` to generate an all-in-one resource object. - - diff --git a/Sources/Instrumentation/SDKResourceExtension/ResourceProvider.swift b/Sources/Instrumentation/SDKResourceExtension/ResourceProvider.swift deleted file mode 100644 index 1cde8330..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/ResourceProvider.swift +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public class ResourceProvider { - public var attributes: [String: AttributeValue] { - [String: AttributeValue]() - } - - public func create() -> Resource { - Resource(attributes: attributes) - } -} diff --git a/Sources/Instrumentation/SDKResourceExtension/TelemetryResourceProvider.swift b/Sources/Instrumentation/SDKResourceExtension/TelemetryResourceProvider.swift deleted file mode 100644 index 9ae63498..00000000 --- a/Sources/Instrumentation/SDKResourceExtension/TelemetryResourceProvider.swift +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -public class TelemetryResourceProvider: ResourceProvider { - let telemetrySource: ITelemetryDataSource - - public init(source: ITelemetryDataSource) { - telemetrySource = source - } - - override public var attributes: [String: AttributeValue] { - var attributes = [String: AttributeValue]() - - attributes[ResourceAttributes.telemetrySdkName.rawValue] = AttributeValue.string(telemetrySource.name) - - attributes[ResourceAttributes.telemetrySdkLanguage.rawValue] = AttributeValue.string(telemetrySource.language) - - if let frameworkVersion = telemetrySource.version { - attributes[ResourceAttributes.telemetrySdkVersion.rawValue] = AttributeValue.string(frameworkVersion) - } - - return attributes - } -} diff --git a/Sources/Instrumentation/SignPostIntegration/OSSignposterIntegration.swift b/Sources/Instrumentation/SignPostIntegration/OSSignposterIntegration.swift deleted file mode 100644 index bee1af9c..00000000 --- a/Sources/Instrumentation/SignPostIntegration/OSSignposterIntegration.swift +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import os -import OpenTelemetryApi -import OpenTelemetrySdk - -/// A span processor that decorates spans with the origin attribute -@available(iOS 15.0, macOS 12, tvOS 15.0, watchOS 8.0, *) -public class OSSignposterIntegration: SpanProcessor { - - public let isStartRequired = true - public let isEndRequired = true - public let osSignposter = OSSignposter(subsystem: "OpenTelemetry", category: .pointsOfInterest) - public let ossignposterQueue = DispatchQueue(label: "org.opentelemetry.ossignposterIntegration") - private var spanIdToStateMap: [String: OSSignpostIntervalState] = [:] - - public init() {} - - public func onStart(parentContext: SpanContext?, span: ReadableSpan) { - let state = osSignposter.beginInterval("Span", id: .exclusive, "\(span.name, privacy: .public)") - ossignposterQueue.sync { - spanIdToStateMap[span.context.spanId.hexString] = state - } - } - - public func onEnd(span: ReadableSpan) { - let state = ossignposterQueue.sync { - spanIdToStateMap.removeValue(forKey: span.context.spanId.hexString) - } - if let state { - osSignposter.endInterval("Span", state) - } - } - - public func forceFlush(timeout: TimeInterval? = nil) {} - public func shutdown(explicitTimeout: TimeInterval?) {} - -} diff --git a/Sources/Instrumentation/SignPostIntegration/README.md b/Sources/Instrumentation/SignPostIntegration/README.md deleted file mode 100644 index d7749484..00000000 --- a/Sources/Instrumentation/SignPostIntegration/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# SignPost Integration - -This package creates `os_signpost` `begin` and `end` calls when spans are started or ended. It allows automatic integration of applications -instrumented with opentelemetry to show their spans in a profiling app like `Instruments`. It also exports the `OSLog` it uses for posting so the user can add extra signpost events. This functionality is shown in `Simple Exporter` example - -## Version Notice - -- **iOS 15+, macOS 12+, tvOS 15+, watchOS 8+**: - Use **`OSSignposterIntegration`**, which utilizes the modern `OSSignposter` API for improved efficiency and compatibility. -- **Older systems**: - Use **`SignPostIntegration`**, which relies on the traditional `os_signpost` API. - -## Usage - -Add the appropriate span processor based on your deployment target: - -### For iOS 15+, macOS 12+, tvOS 15+, watchOS 8+: - -```swift -OpenTelemetry.instance.tracerProvider.addSpanProcessor(OSSignposterIntegration()) -``` - -### For older systems - -```swift -OpenTelemetry.instance.tracerProvider.addSpanProcessor(SignPostIntegration()) -``` - -### Or, to select automatically at runtime: - -```swift -if #available(iOS 15, macOS 12, tvOS 15, watchOS 8, *) { - OpenTelemetry.instance.tracerProvider.addSpanProcessor(OSSignposterIntegration()) -} else { - OpenTelemetry.instance.tracerProvider.addSpanProcessor(SignPostIntegration()) -} -``` diff --git a/Sources/Instrumentation/SignPostIntegration/SignPostIntegration.swift b/Sources/Instrumentation/SignPostIntegration/SignPostIntegration.swift deleted file mode 100644 index 7f38c7ba..00000000 --- a/Sources/Instrumentation/SignPostIntegration/SignPostIntegration.swift +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - import os - import OpenTelemetryApi - import OpenTelemetrySdk - - /// A span processor that decorates spans with the origin attribute - @available(macOS 10.14, iOS 12.0, tvOS 12.0, *) - public class SignPostIntegration: SpanProcessor { - public let isStartRequired = true - public let isEndRequired = true - public let osLog = OSLog(subsystem: "OpenTelemetry", category: .pointsOfInterest) - - public init() {} - - public func onStart(parentContext: SpanContext?, span: ReadableSpan) { - let signpostID = OSSignpostID(log: osLog, object: self) - os_signpost(.begin, log: osLog, name: "Span", signpostID: signpostID, "%{public}@", span.name) - } - - public func onEnd(span: ReadableSpan) { - let signpostID = OSSignpostID(log: osLog, object: self) - os_signpost(.end, log: osLog, name: "Span", signpostID: signpostID) - } - - public func forceFlush(timeout: TimeInterval? = nil) {} - public func shutdown(explicitTimeout: TimeInterval?) {} - } - -#endif diff --git a/Sources/Instrumentation/URLSession/InstrumentationUtils.swift b/Sources/Instrumentation/URLSession/InstrumentationUtils.swift deleted file mode 100644 index 1094e1f0..00000000 --- a/Sources/Instrumentation/URLSession/InstrumentationUtils.swift +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -#if canImport(os.log) - import os.log -#endif - -#if os(iOS) || os(tvOS) -import UIKit -#elseif os(watchOS) -import WatchKit -#endif - -enum InstrumentationUtils { - static func objc_getClassList() -> [AnyClass] { - let expectedClassCount = ObjectiveC.objc_getClassList(nil, 0) - let allClasses = UnsafeMutablePointer.allocate(capacity: Int(expectedClassCount)) - let autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer(allClasses) - let actualClassCount: Int32 = ObjectiveC.objc_getClassList(autoreleasingAllClasses, expectedClassCount) - - var classes = [AnyClass]() - for i in 0 ..< actualClassCount { - classes.append(allClasses[Int(i)]) - } - allClasses.deallocate() - return classes - } - - static func objc_getSafeClassList(ignoredPrefixes: [String]? = nil) -> [AnyClass] { - let allClasses = objc_getClassList() - var safeClasses: [AnyClass] = [] - - for cls in allClasses { - let className = NSStringFromClass(cls) - if let ignoredPrefixes = ignoredPrefixes { - if ignoredPrefixes.contains(where: { className.hasPrefix($0) }) { - continue - } - } - safeClasses.append(cls) - } - - if #available(iOS 14, macOS 11, tvOS 14, *) { - os_log(.info, "failed to initialize network connection status: %@", safeClasses.count) - } - return safeClasses - } - - static func instanceRespondsAndImplements(cls: AnyClass, selector: Selector) -> Bool { - var implements = false - if cls.instancesRespond(to: selector) { - var methodCount: UInt32 = 0 - guard let methodList = class_copyMethodList(cls, &methodCount) else { - return implements - } - defer { free(methodList) } - if methodCount > 0 { - enumerateCArray(array: methodList, count: methodCount) { _, m in - let sel = method_getName(m) - if sel == selector { - implements = true - return - } - } - } - } - return implements - } - - private static func enumerateCArray(array: UnsafePointer, count: UInt32, f: (UInt32, T) -> Void) { - var ptr = array - for i in 0 ..< count { - f(i, ptr.pointee) - ptr = ptr.successor() - } - } -} diff --git a/Sources/Instrumentation/URLSession/README.md b/Sources/Instrumentation/URLSession/README.md deleted file mode 100644 index 7bca6998..00000000 --- a/Sources/Instrumentation/URLSession/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# URL Session instrumentation - -This package captures the network calls produced by URLSession. - -This instrumentation relies on the global tracer provider in the `OpenTelemetry` object. Custom global tracer providers must be initialized and set prior to initializing this instrumentation. - -## Usage - -Initialize the class with `URLSessionInstrumentation(configuration: URLSessionInstrumentationConfiguration())` to automatically capture all network calls. - -This behaviour can be modified or augmented by using the optional callbacks defined in `URLSessionInstrumentationConfiguration` : - -`shouldInstrument: ((URLRequest) -> (Bool)?)?` : Filter which requests you want to instrument, all by default - -`shouldRecordPayload: ((URLSession) -> (Bool)?)?`: Implement if you want the session to record payload data, false by default. - -`shouldInjectTracingHeaders: ((URLRequest) -> (Bool)?)?`: Allows filtering which requests you want to inject headers to follow the trace, true by default. You must also return true if you want to inject custom headers. - -`injectCustomHeaders: ((inout URLRequest, Span?) -> Void)?`: Implement this callback to inject custom headers or modify the request in any other way - -`nameSpan: ((URLRequest) -> (String)?)?` - Modifies the name for the given request instead of stantard Opentelemetry name - -`spanCustomization: ((URLRequest, SpanBuilder) -> Void)?` - Customizes the span while it's being built, such as by adding a parent, a link, attributes, etc. - -`createdRequest: ((URLRequest, Span) -> Void)?` - Called after request is created, it allows to add extra information to the Span - -`receivedResponse: ((URLResponse, DataOrFile?, Span) -> Void)?`- Called after response is received, it allows to add extra information to the Span - -`receivedError: ((Error, DataOrFile?, HTTPStatus, Span) -> Void)?` - Called after an error is received, it allows to add extra information to the Span - -`baggageProvider: ((inout URLRequest, Span) -> (Baggage)?)?`: Provides baggage instance for instrumented requests that is merged with active baggage. The callback receives URLRequest and Span parameters to create dynamic baggage based on request context. The resulting baggage is injected into request headers using the configured propagator. - diff --git a/Sources/Instrumentation/URLSession/URLSessionInstrumentation.swift b/Sources/Instrumentation/URLSession/URLSessionInstrumentation.swift deleted file mode 100644 index 8b0c489e..00000000 --- a/Sources/Instrumentation/URLSession/URLSessionInstrumentation.swift +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk - -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -struct NetworkRequestState { - var request: URLRequest? - var dataProcessed: Data? - - mutating func setRequest(_ request: URLRequest) { - self.request = request - } - - mutating func setData(_ data: URLRequest) { - request = data - } -} - -private var idKey: Void? - -public class URLSessionInstrumentation { - private var requestMap = [String: NetworkRequestState]() - - private var _configuration: URLSessionInstrumentationConfiguration - public var configuration: URLSessionInstrumentationConfiguration { - configurationQueue.sync { _configuration } - } - - private let queue = DispatchQueue( - label: "io.opentelemetry.ddnetworkinstrumentation") - private let configurationQueue = DispatchQueue( - label: "io.opentelemetry.configuration") - - static var instrumentedKey = "io.opentelemetry.instrumentedCall" - - static let excludeList: [String] = [ - "__NSCFURLProxySessionConnection" - ] - - static let AVTaskClassList: [AnyClass] = [ - "__NSCFBackgroundAVAggregateAssetDownloadTask", - "__NSCFBackgroundAVAssetDownloadTask", - "__NSCFBackgroundAVAggregateAssetDownloadTaskNoChildTask" - ] - .compactMap { NSClassFromString($0) } - - public var startedRequestSpans: [Span] { - var spans = [Span]() - URLSessionLogger.runningSpansQueue.sync { - spans = Array(URLSessionLogger.runningSpans.values) - } - return spans - } - - public init(configuration: URLSessionInstrumentationConfiguration) { - self._configuration = configuration - injectInNSURLClasses() - } - - private func injectInNSURLClasses() { - let selectors = [ - #selector(URLSessionDataDelegate.urlSession(_:dataTask:didReceive:)), - #selector( - URLSessionDataDelegate.urlSession( - _:dataTask:didReceive:completionHandler:)), - #selector( - URLSessionDataDelegate.urlSession(_:task:didCompleteWithError:)), - #selector( - URLSessionDataDelegate.urlSession(_:dataTask:didBecome:) - as (URLSessionDataDelegate) -> ( - (URLSession, URLSessionDataTask, URLSessionDownloadTask) -> Void - )?), - #selector( - URLSessionDataDelegate.urlSession(_:dataTask:didBecome:) - as (URLSessionDataDelegate) -> ( - (URLSession, URLSessionDataTask, URLSessionStreamTask) -> Void - )?) - ] - let classes = - configuration.delegateClassesToInstrument - ?? InstrumentationUtils.objc_getClassList() - let selectorsCount = selectors.count - DispatchQueue.concurrentPerform(iterations: classes.count) { iteration in - let theClass: AnyClass = classes[iteration] - guard theClass != Self.self else { return } - var selectorFound = false - var methodCount: UInt32 = 0 - guard let methodList = class_copyMethodList(theClass, &methodCount) else { - return - } - defer { free(methodList) } - - var foundClasses: [AnyClass] = [] - for j in 0 ..< selectorsCount { - for i in 0 ..< Int(methodCount) - where method_getName(methodList[i]) == selectors[j] { - selectorFound = true - foundClasses.append(theClass) - } - if selectorFound { - break - } - } - - foundClasses.removeAll { cls in - Self.excludeList.contains(NSStringFromClass(cls)) - } - - foundClasses.forEach { cls in - injectIntoDelegateClass(cls: cls) - } - } - - if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { - injectIntoNSURLSessionCreateTaskMethods() - } - injectIntoNSURLSessionCreateTaskWithParameterMethods() - injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods() - injectIntoNSURLSessionAsyncUploadTaskMethods() - injectIntoNSURLSessionTaskResume() - } - - private func injectIntoDelegateClass(cls: AnyClass) { - // Sessions - injectTaskDidReceiveDataIntoDelegateClass(cls: cls) - injectTaskDidReceiveResponseIntoDelegateClass(cls: cls) - injectTaskDidCompleteWithErrorIntoDelegateClass(cls: cls) - injectRespondsToSelectorIntoDelegateClass(cls: cls) - // For future use - if #available(OSX 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - injectTaskDidFinishCollectingMetricsIntoDelegateClass(cls: cls) - } - - // Data tasks - injectDataTaskDidBecomeDownloadTaskIntoDelegateClass(cls: cls) - } - - private func injectIntoNSURLSessionCreateTaskMethods() { - let cls = URLSession.self - [ - #selector( - URLSession.dataTask(with:) - as (URLSession) -> (URLRequest) -> URLSessionDataTask), - #selector( - URLSession.dataTask(with:) - as (URLSession) -> (URL) -> URLSessionDataTask), - #selector(URLSession.uploadTask(withStreamedRequest:)), - #selector( - URLSession.downloadTask(with:) - as (URLSession) -> (URLRequest) -> URLSessionDownloadTask), - #selector( - URLSession.downloadTask(with:) - as (URLSession) -> (URL) -> URLSessionDownloadTask), - #selector(URLSession.downloadTask(withResumeData:)) - ].forEach { - let selector = $0 - guard let original = class_getInstanceMethod(cls, selector) else { - print("injectInto \(selector.description) failed") - return - } - var originalIMP: IMP? - - let block: @convention(block) (URLSession, AnyObject) -> URLSessionTask = { session, argument in - if let url = argument as? URL { - let request = URLRequest(url: url) - if self.configuration.shouldInjectTracingHeaders?(request) ?? true { - if selector == #selector( - URLSession.dataTask(with:) - as (URLSession) -> (URL) -> URLSessionDataTask) { - return session.dataTask(with: request) - } else { - return session.downloadTask(with: request) - } - } - } - - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (URLSession, Selector, Any) -> - URLSessionDataTask).self) - var task: URLSessionTask - let sessionTaskId = UUID().uuidString - - if let request = argument as? URLRequest, - objc_getAssociatedObject(argument, &idKey) == nil { - let instrumentedRequest = URLSessionLogger.processAndLogRequest(request, sessionTaskId: sessionTaskId, instrumentation: self, - shouldInjectHeaders: true) - task = castedIMP(session, selector, instrumentedRequest ?? request) - } else { - task = castedIMP(session, selector, argument) - if objc_getAssociatedObject(argument, &idKey) == nil, - let currentRequest = task.currentRequest { - URLSessionLogger.processAndLogRequest(currentRequest, sessionTaskId: sessionTaskId, - instrumentation: self, shouldInjectHeaders: false) - } - } - self.setIdKey(value: sessionTaskId, for: task) - - // We want to identify background tasks - if session.configuration.identifier == nil { - objc_setAssociatedObject(task, "IsBackground", true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - return task - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - } - - private func injectIntoNSURLSessionCreateTaskWithParameterMethods() { - typealias UploadWithDataIMP = @convention(c) (URLSession, Selector, URLRequest, Data?) -> URLSessionTask - typealias UploadWithFileIMP = @convention(c) (URLSession, Selector, URLRequest, URL) -> URLSessionTask - - let cls = URLSession.self - - // MARK: Swizzle `uploadTask(with:from:)` - if let method = class_getInstanceMethod(cls, #selector(URLSession.uploadTask(with:from:))) { - let originalIMP = method_getImplementation(method) - let imp = unsafeBitCast(originalIMP, to: UploadWithDataIMP.self) - - let block: @convention(block) (URLSession, URLRequest, Data?) -> URLSessionTask = { [weak self] session, request, data in - guard let instrumentation = self else { - return imp(session, #selector(URLSession.uploadTask(with:from:)), request, data) - } - - let sessionTaskId = UUID().uuidString - let instrumentedRequest = URLSessionLogger.processAndLogRequest( - request, - sessionTaskId: sessionTaskId, - instrumentation: instrumentation, - shouldInjectHeaders: true - ) - - let task = imp(session, #selector(URLSession.uploadTask(with:from:)), instrumentedRequest ?? request, data) - instrumentation.setIdKey(value: sessionTaskId, for: task) - return task - } - let swizzledIMP = imp_implementationWithBlock(block) - method_setImplementation(method, swizzledIMP) - } - - // MARK: Swizzle `uploadTask(with:fromFile:)` - if let method = class_getInstanceMethod(cls, #selector(URLSession.uploadTask(with:fromFile:))) { - let originalIMP = method_getImplementation(method) - let imp = unsafeBitCast(originalIMP, to: UploadWithFileIMP.self) - - let block: @convention(block) (URLSession, URLRequest, URL) -> URLSessionTask = { [weak self] session, request, fileURL in - guard let instrumentation = self else { - return imp(session, #selector(URLSession.uploadTask(with:fromFile:)), request, fileURL) - } - - let sessionTaskId = UUID().uuidString - let instrumentedRequest = URLSessionLogger.processAndLogRequest( - request, - sessionTaskId: sessionTaskId, - instrumentation: instrumentation, - shouldInjectHeaders: true - ) - - let task = imp(session, #selector(URLSession.uploadTask(with:fromFile:)), instrumentedRequest ?? request, fileURL) - instrumentation.setIdKey(value: sessionTaskId, for: task) - return task - } - let swizzledIMP = imp_implementationWithBlock(block) - method_setImplementation(method, swizzledIMP) - } - } - - private func injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods() { - let cls = URLSession.self - [ - #selector( - URLSession.dataTask(with:completionHandler:) - as (URLSession) -> (URLRequest, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask), - #selector( - URLSession.dataTask(with:completionHandler:) - as (URLSession) -> (URL, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask), - #selector( - URLSession.downloadTask(with:completionHandler:) - as (URLSession) -> (URLRequest, @escaping (URL?, URLResponse?, Error?) -> Void) -> URLSessionDownloadTask), - #selector( - URLSession.downloadTask(with:completionHandler:) - as (URLSession) -> (URL, @escaping (URL?, URLResponse?, Error?) -> Void) -> URLSessionDownloadTask), - #selector(URLSession.downloadTask(withResumeData:completionHandler:)) - ].forEach { - let selector = $0 - guard let original = class_getInstanceMethod(cls, selector) else { - print("injectInto \(selector.description) failed") - return - } - var originalIMP: IMP? - - let block: - @convention(block) (URLSession, AnyObject, ((Any?, URLResponse?, Error?) -> Void)?) -> URLSessionTask = { session, argument, completion in - - if let url = argument as? URL { - let request = URLRequest(url: url) - - if self.configuration.shouldInjectTracingHeaders?(request) ?? true { - if selector == #selector( - URLSession.dataTask(with:completionHandler:) - as (URLSession) -> (URL, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask) { - if let completion { - return session.dataTask(with: request, completionHandler: completion) - } else { - return session.dataTask(with: request) - } - } else { - if let completion { - return session.downloadTask(with: request, completionHandler: completion) - } else { - return session.downloadTask(with: request) - } - } - } - } - - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (URLSession, Selector, Any, ((Any?, URLResponse?, Error?) -> Void)?) -> URLSessionDataTask).self) - var task: URLSessionTask! - let sessionTaskId = UUID().uuidString - - var completionBlock = completion - - if completionBlock != nil { - if objc_getAssociatedObject(argument, &idKey) == nil { - let completionWrapper: (Any?, URLResponse?, Error?) -> Void = { object, response, error in - if error != nil { - let status = (response as? HTTPURLResponse)?.statusCode ?? 0 - URLSessionLogger.logError(error!, dataOrFile: object, statusCode: status, - instrumentation: self, sessionTaskId: sessionTaskId) - } else { - if let response { - URLSessionLogger.logResponse(response, dataOrFile: object, instrumentation: self, - sessionTaskId: sessionTaskId) - } - } - if let completion { - completion(object, response, error) - } else { - (session.delegate as? URLSessionTaskDelegate)?.urlSession?(session, task: task, didCompleteWithError: error) - } - } - completionBlock = completionWrapper - } - } - - if let request = argument as? URLRequest, - objc_getAssociatedObject(argument, &idKey) == nil { - let instrumentedRequest = URLSessionLogger.processAndLogRequest(request, sessionTaskId: sessionTaskId, instrumentation: self, - shouldInjectHeaders: true) - task = castedIMP(session, selector, instrumentedRequest ?? request, completionBlock) - } else { - task = castedIMP(session, selector, argument, completionBlock) - if objc_getAssociatedObject(argument, &idKey) == nil, - let currentRequest = task.currentRequest { - URLSessionLogger.processAndLogRequest(currentRequest, sessionTaskId: sessionTaskId, - instrumentation: self, shouldInjectHeaders: false) - } - } - self.setIdKey(value: sessionTaskId, for: task) - return task - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - } - - private func injectIntoNSURLSessionAsyncUploadTaskMethods() { - let cls = URLSession.self - [ - #selector(URLSession.uploadTask(with:from:completionHandler:)), - #selector(URLSession.uploadTask(with:fromFile:completionHandler:)) - ].forEach { - let selector = $0 - guard let original = class_getInstanceMethod(cls, selector) else { - print("injectInto \(selector.description) failed") - return - } - var originalIMP: IMP? - - let block: - @convention(block) (URLSession, URLRequest, AnyObject, - ((Any?, URLResponse?, Error?) -> Void)?) -> URLSessionTask = { session, request, argument, completion in - - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (URLSession, Selector, URLRequest, AnyObject, - ((Any?, URLResponse?, Error?) -> Void)?) -> URLSessionDataTask).self) - - var task: URLSessionTask! - let sessionTaskId = UUID().uuidString - - var completionBlock = completion - if objc_getAssociatedObject(argument, &idKey) == nil { - let completionWrapper: (Any?, URLResponse?, Error?) -> Void = { object, response, error in - if error != nil { - let status = (response as? HTTPURLResponse)?.statusCode ?? 0 - URLSessionLogger.logError(error!, dataOrFile: object, statusCode: status, - instrumentation: self, sessionTaskId: sessionTaskId) - } else { - if let response { - URLSessionLogger.logResponse(response, dataOrFile: object, instrumentation: self, - sessionTaskId: sessionTaskId) - } - } - if let completion { - completion(object, response, error) - } else { - (session.delegate as? URLSessionTaskDelegate)?.urlSession?(session, task: task, didCompleteWithError: error) - } - } - completionBlock = completionWrapper - } - - let processedRequest = URLSessionLogger.processAndLogRequest(request, sessionTaskId: sessionTaskId, instrumentation: self, - shouldInjectHeaders: true) - task = castedIMP(session, selector, processedRequest ?? request, argument, - completionBlock) - - self.setIdKey(value: sessionTaskId, for: task) - return task - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - } - - private func injectIntoNSURLSessionTaskResume() { - var methodsToSwizzle = [Method]() - - if let method = class_getInstanceMethod(URLSessionTask.self, #selector(URLSessionTask.resume)) { - methodsToSwizzle.append(method) - } - - if let cfURLSession = NSClassFromString("__NSCFURLSessionTask"), - let method = class_getInstanceMethod(cfURLSession, NSSelectorFromString("resume")) { - methodsToSwizzle.append(method) - } - - if NSClassFromString("AFURLSessionManager") != nil { - let classes = InstrumentationUtils.objc_getSafeClassList( - ignoredPrefixes: configuration.ignoredClassPrefixes - ) - classes.forEach { - if let method = class_getInstanceMethod($0, NSSelectorFromString("af_resume")) { - methodsToSwizzle.append(method) - } - } - } - - methodsToSwizzle.forEach { - let theMethod = $0 - - var originalIMP: IMP? - let block: @convention(block) (URLSessionTask) -> Void = { anyTask in - self.urlSessionTaskWillResume(anyTask) - guard anyTask.currentRequest != nil else { return } - let key = String(theMethod.hashValue) - objc_setAssociatedObject(anyTask, key, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - let castedIMP = unsafeBitCast(originalIMP, to: (@convention(c) (Any) -> Void).self) - castedIMP(anyTask) - objc_setAssociatedObject(anyTask, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(theMethod, swizzledIMP) - } - } - - // Delegate methods - private func injectTaskDidReceiveDataIntoDelegateClass(cls: AnyClass) { - let selector = #selector( - URLSessionDataDelegate.urlSession(_:dataTask:didReceive:)) - guard let original = class_getInstanceMethod(cls, selector) else { - return - } - var originalIMP: IMP? - let block: - @convention(block) (Any, URLSession, URLSessionDataTask, Data) -> Void = { object, session, dataTask, data in - if objc_getAssociatedObject(session, &idKey) == nil { - self.urlSession(session, dataTask: dataTask, didReceive: data) - } - let key = String(selector.hashValue) - objc_setAssociatedObject(session, key, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (Any, Selector, URLSession, URLSessionDataTask, Data) -> Void).self) - castedIMP(object, selector, session, dataTask, data) - objc_setAssociatedObject(session, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - - private func injectTaskDidReceiveResponseIntoDelegateClass(cls: AnyClass) { - let selector = #selector( - URLSessionDataDelegate.urlSession( - _:dataTask:didReceive:completionHandler:)) - guard let original = class_getInstanceMethod(cls, selector) else { - return - } - var originalIMP: IMP? - let block: - @convention(block) (Any, URLSession, URLSessionDataTask, URLResponse, - @escaping (URLSession.ResponseDisposition) -> Void) -> Void = { object, session, dataTask, response, completion in - if objc_getAssociatedObject(session, &idKey) == nil { - self.urlSession(session, dataTask: dataTask, didReceive: response, - completionHandler: completion) - } - let key = String(selector.hashValue) - objc_setAssociatedObject(session, key, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (Any, Selector, URLSession, URLSessionDataTask, URLResponse, - @escaping (URLSession.ResponseDisposition) -> Void) -> Void).self) - castedIMP(object, selector, session, dataTask, response, completion) - objc_setAssociatedObject(session, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - - private func injectTaskDidCompleteWithErrorIntoDelegateClass(cls: AnyClass) { - let selector = #selector( - URLSessionDataDelegate.urlSession(_:task:didCompleteWithError:)) - guard let original = class_getInstanceMethod(cls, selector) else { - return - } - var originalIMP: IMP? - let block: - @convention(block) (Any, URLSession, URLSessionTask, Error?) -> Void = { object, session, task, error in - if objc_getAssociatedObject(session, &idKey) == nil { - self.urlSession(session, task: task, didCompleteWithError: error) - } - let key = String(selector.hashValue) - objc_setAssociatedObject(session, key, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (Any, Selector, URLSession, URLSessionTask, Error?) -> Void).self) - castedIMP(object, selector, session, task, error) - objc_setAssociatedObject(session, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - - private func injectTaskDidFinishCollectingMetricsIntoDelegateClass( - cls: AnyClass - ) { - let selector = #selector( - URLSessionTaskDelegate.urlSession(_:task:didFinishCollecting:)) - guard let original = class_getInstanceMethod(cls, selector) else { - let block: - @convention(block) (Any, URLSession, URLSessionTask, URLSessionTaskMetrics) -> Void = { _, session, task, metrics in - self.urlSession(session, task: task, didFinishCollecting: metrics) - } - let imp = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - class_addMethod(cls, selector, imp, "@@@") - return - } - var originalIMP: IMP? - let block: - @convention(block) (Any, URLSession, URLSessionTask, URLSessionTaskMetrics) -> Void = { object, session, task, metrics in - if objc_getAssociatedObject(session, &idKey) == nil { - self.urlSession(session, task: task, didFinishCollecting: metrics) - } - let key = String(selector.hashValue) - objc_setAssociatedObject(session, key, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (Any, Selector, URLSession, URLSessionTask, URLSessionTaskMetrics) -> Void).self) - castedIMP(object, selector, session, task, metrics) - objc_setAssociatedObject(session, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - - func injectRespondsToSelectorIntoDelegateClass(cls: AnyClass) { - let selector = #selector(NSObject.responds(to:)) - guard let original = class_getInstanceMethod(cls, selector), - InstrumentationUtils.instanceRespondsAndImplements(cls: cls, selector: selector) - else { - return - } - - var originalIMP: IMP? - let block: @convention(block) (Any, Selector) -> Bool = { object, respondsTo in - if respondsTo == #selector( - URLSessionDataDelegate.urlSession( - _:dataTask:didReceive:completionHandler:)) { - return true - } - let castedIMP = unsafeBitCast(originalIMP, to: (@convention(c) (Any, Selector, Selector) -> Bool).self) - return castedIMP(object, selector, respondsTo) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - - private func injectDataTaskDidBecomeDownloadTaskIntoDelegateClass( - cls: AnyClass - ) { - let selector = #selector( - URLSessionDataDelegate.urlSession(_:dataTask:didBecome:) - as (URLSessionDataDelegate) -> ( - (URLSession, URLSessionDataTask, URLSessionDownloadTask) -> Void - )?) - guard let original = class_getInstanceMethod(cls, selector) else { - return - } - var originalIMP: IMP? - let block: - @convention(block) (Any, URLSession, URLSessionDataTask, URLSessionDownloadTask) -> Void = { object, session, dataTask, downloadTask in - if objc_getAssociatedObject(session, &idKey) == nil { - self.urlSession(session, dataTask: dataTask, didBecome: downloadTask) - } - let key = String(selector.hashValue) - objc_setAssociatedObject(session, key, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - let castedIMP = unsafeBitCast(originalIMP, - to: (@convention(c) (Any, Selector, URLSession, URLSessionDataTask, - URLSessionDownloadTask) -> Void).self) - castedIMP(object, selector, session, dataTask, downloadTask) - objc_setAssociatedObject(session, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - let swizzledIMP = imp_implementationWithBlock( - unsafeBitCast(block, to: AnyObject.self)) - originalIMP = method_setImplementation(original, swizzledIMP) - } - - // URLSessionTask methods - private func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { - guard configuration.shouldRecordPayload?(session) ?? false else { return } - guard let taskId = objc_getAssociatedObject(dataTask, &idKey) as? String - else { - return - } - let dataCopy = data - queue.sync { - if (requestMap[taskId]?.request) != nil { - createRequestState(for: taskId) - if requestMap[taskId]?.dataProcessed == nil { - requestMap[taskId]?.dataProcessed = Data() - } - requestMap[taskId]?.dataProcessed?.append(dataCopy) - } - } - } - - private func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, - didReceive response: URLResponse, - completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { - guard configuration.shouldRecordPayload?(session) ?? false else { return } - guard let taskId = objc_getAssociatedObject(dataTask, &idKey) as? String - else { - return - } - queue.sync { - if (requestMap[taskId]?.request) != nil { - createRequestState(for: taskId) - if response.expectedContentLength < 0 { - requestMap[taskId]?.dataProcessed = Data() - } else { - requestMap[taskId]?.dataProcessed = Data( - capacity: Int(response.expectedContentLength)) - } - } - } - } - - private func urlSession(_ session: URLSession, task: URLSessionTask, - didCompleteWithError error: Error?) { - guard let taskId = objc_getAssociatedObject(task, &idKey) as? String else { - return - } - var requestState: NetworkRequestState? - queue.sync { - requestState = requestMap[taskId] - if requestState != nil { - requestMap[taskId] = nil - } - } - if let error { - let status = (task.response as? HTTPURLResponse)?.statusCode ?? 0 - URLSessionLogger.logError(error, dataOrFile: requestState?.dataProcessed, statusCode: status, - instrumentation: self, sessionTaskId: taskId) - } else if let response = task.response { - URLSessionLogger.logResponse(response, dataOrFile: requestState?.dataProcessed, - instrumentation: self, sessionTaskId: taskId) - } - } - - private func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, - didBecome downloadTask: URLSessionDownloadTask) { - guard let taskId = objc_getAssociatedObject(dataTask, &idKey) as? String - else { - return - } - setIdKey(value: taskId, for: downloadTask) - } - - private func urlSession(_ session: URLSession, task: URLSessionTask, - didFinishCollecting metrics: URLSessionTaskMetrics) { - guard let taskId = objc_getAssociatedObject(task, &idKey) as? String else { - return - } - var requestState: NetworkRequestState? - queue.sync { - requestState = requestMap[taskId] - - if requestState?.request != nil { - requestMap[taskId] = nil - } - } - - guard requestState?.request != nil else { - return - } - - /// Code for instrumenting collection should be written here - if let error = task.error { - let status = (task.response as? HTTPURLResponse)?.statusCode ?? 0 - URLSessionLogger.logError(error, dataOrFile: requestState?.dataProcessed, statusCode: status, - instrumentation: self, sessionTaskId: taskId) - } else if let response = task.response { - URLSessionLogger.logResponse(response, dataOrFile: requestState?.dataProcessed, - instrumentation: self, sessionTaskId: taskId) - } - } - - private func urlSessionTaskWillResume(_ task: URLSessionTask) { - // AV Asset Tasks cannot be auto instrumented, they dont include request attributes, skip them - guard !Self.AVTaskClassList.contains(where: { task.isKind(of: $0) }) else { - return - } - - // We cannot instrument async background tasks because they crash if you assign a delegate - if #available(OSX 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - if objc_getAssociatedObject(task, "IsBackground") is Bool { - guard Task.basePriority == nil else { - return - } - } - } - - let taskId = idKeyForTask(task) - if let request = task.currentRequest { - queue.sync { - if requestMap[taskId] == nil { - requestMap[taskId] = NetworkRequestState() - } - requestMap[taskId]?.setRequest(request) - } - - // For iOS 15+/macOS 12+, handle async/await methods differently - if #available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) { - // Check if we can determine if this is an async/await call - // For iOS 15/macOS 12, we can't use Task.basePriority, so we check other indicators - var isAsyncContext = false - - if #available(OSX 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - isAsyncContext = Task.basePriority != nil - } else { - // For iOS 15/macOS 12, check if the task has no delegate and no session delegate - // This is a heuristic that works for async/await methods - isAsyncContext = task.delegate == nil && - (task.value(forKey: "session") as? URLSession)?.delegate == nil && - task.state != .running - } - - if isAsyncContext { - // This is likely an async/await call - let instrumentedRequest = URLSessionLogger.processAndLogRequest(request, - sessionTaskId: taskId, - instrumentation: self, - shouldInjectHeaders: true) - if let instrumentedRequest { - task.setValue(instrumentedRequest, forKey: "currentRequest") - } - self.setIdKey(value: taskId, for: task) - - // For async/await methods, we need to ensure the delegate is set - // to capture the completion, but only if there's no existing delegate - // AND no session delegate (session delegates are called for async/await too) - if task.delegate == nil, - task.state != .running, - (task.value(forKey: "session") as? URLSession)?.delegate == nil { - task.delegate = AsyncTaskDelegate(instrumentation: self, sessionTaskId: taskId) - } - return - } - } - - if #available(OSX 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - guard Task.basePriority != nil else { - // If not inside a Task basePriority is nil - return - } - - let instrumentedRequest = URLSessionLogger.processAndLogRequest(request, - sessionTaskId: taskId, - instrumentation: self, - shouldInjectHeaders: true) - if let instrumentedRequest { - task.setValue(instrumentedRequest, forKey: "currentRequest") - } - self.setIdKey(value: taskId, for: task) - - if task.delegate == nil, task.state != .running, (task.value(forKey: "session") as? URLSession)?.delegate == nil { - task.delegate = FakeDelegate() - } - } - } - } - - // Helpers - private func idKeyForTask(_ task: URLSessionTask) -> String { - var id = objc_getAssociatedObject(task, &idKey) as? String - if id == nil { - id = UUID().uuidString - objc_setAssociatedObject(task, &idKey, id, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - return id! - } - - private func setIdKey(value: String, for task: URLSessionTask) { - objc_setAssociatedObject(task, &idKey, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - - private func createRequestState(for id: String) { - var state = requestMap[id] - if requestMap[id] == nil { - state = NetworkRequestState() - requestMap[id] = state - } - } -} - -class FakeDelegate: NSObject, URLSessionTaskDelegate { - func urlSession(_ session: URLSession, task: URLSessionTask, - didCompleteWithError error: Error?) {} -} - -@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) -class AsyncTaskDelegate: NSObject, URLSessionTaskDelegate { - private weak var instrumentation: URLSessionInstrumentation? - private let sessionTaskId: String - - init(instrumentation: URLSessionInstrumentation, sessionTaskId: String) { - self.instrumentation = instrumentation - self.sessionTaskId = sessionTaskId - super.init() - } - - func urlSession(_ session: URLSession, task: URLSessionTask, - didCompleteWithError error: Error?) { - guard let instrumentation = instrumentation else { return } - - // Get the task ID that was set when the task was created - let taskId = sessionTaskId - - if let error = error { - let status = (task.response as? HTTPURLResponse)?.statusCode ?? 0 - URLSessionLogger.logError(error, dataOrFile: nil, statusCode: status, - instrumentation: instrumentation, sessionTaskId: taskId) - } else if let response = task.response { - URLSessionLogger.logResponse(response, dataOrFile: nil, - instrumentation: instrumentation, sessionTaskId: taskId) - } - } -} diff --git a/Sources/Instrumentation/URLSession/URLSessionInstrumentationConfiguration.swift b/Sources/Instrumentation/URLSession/URLSessionInstrumentationConfiguration.swift deleted file mode 100644 index 362f2221..00000000 --- a/Sources/Instrumentation/URLSession/URLSessionInstrumentationConfiguration.swift +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -public typealias DataOrFile = Any -public typealias SessionTaskId = String -public typealias HTTPStatus = Int - -public struct URLSessionInstrumentationConfiguration { - public init(shouldRecordPayload: ((URLSession) -> (Bool)?)? = nil, - shouldInstrument: ((URLRequest) -> (Bool)?)? = nil, - nameSpan: ((URLRequest) -> (String)?)? = nil, - spanCustomization: ((URLRequest, SpanBuilder) -> Void)? = nil, - shouldInjectTracingHeaders: ((URLRequest) -> (Bool)?)? = nil, - injectCustomHeaders: ((inout URLRequest, Span?) -> Void)? = nil, - createdRequest: ((URLRequest, Span) -> Void)? = nil, - receivedResponse: ((URLResponse, DataOrFile?, Span) -> Void)? = nil, - receivedError: ((Error, DataOrFile?, HTTPStatus, Span) -> Void)? = nil, - delegateClassesToInstrument: [AnyClass]? = nil, - baggageProvider: ((inout URLRequest, Span?) -> (Baggage)?)? = nil, - tracer: Tracer? = nil, - ignoredClassPrefixes: [String]? = nil) { - self.shouldRecordPayload = shouldRecordPayload - self.shouldInstrument = shouldInstrument - self.shouldInjectTracingHeaders = shouldInjectTracingHeaders - self.injectCustomHeaders = injectCustomHeaders - self.nameSpan = nameSpan - self.spanCustomization = spanCustomization - self.createdRequest = createdRequest - self.receivedResponse = receivedResponse - self.receivedError = receivedError - self.delegateClassesToInstrument = delegateClassesToInstrument - self.baggageProvider = baggageProvider - self.tracer = tracer ?? - OpenTelemetry.instance.tracerProvider.get(instrumentationName: "NSURLSession", instrumentationVersion: "0.0.1") - self.ignoredClassPrefixes = ignoredClassPrefixes - } - - public var tracer: Tracer - - // Instrumentation Callbacks - - /// Implement this callback to filter which requests you want to instrument, all by default - public var shouldInstrument: ((URLRequest) -> (Bool)?)? - - /// Implement this callback if you want the session to record payload data, false by default. - /// This callback is only necessary when using session delegate - public var shouldRecordPayload: ((URLSession) -> (Bool)?)? - - /// Implement this callback to filter which requests you want to inject headers to follow the trace, - /// also must implement it if you want to inject custom headers - /// Instruments all requests by default - public var shouldInjectTracingHeaders: ((URLRequest) -> (Bool)?)? - - /// Implement this callback to inject custom headers or modify the request in any other way - public var injectCustomHeaders: ((inout URLRequest, Span?) -> Void)? - - /// Implement this callback to override the default span name for a given request, return nil to use default. - /// default name: `HTTP {method}` e.g. `HTTP PUT` - public var nameSpan: ((URLRequest) -> (String)?)? - - /// Implement this callback to customize the span, such as by adding a parent, a link, attributes, etc - public var spanCustomization: ((URLRequest, SpanBuilder) -> Void)? - - /// Called before the span is created, it allows to add extra information to the Span - public var createdRequest: ((URLRequest, Span) -> Void)? - - /// Called before the span is ended, it allows to add extra information to the Span - public var receivedResponse: ((URLResponse, DataOrFile?, Span) -> Void)? - - /// Called before the span is ended, it allows to add extra information to the Span - public var receivedError: ((Error, DataOrFile?, HTTPStatus, Span) -> Void)? - - /// The array of URLSession delegate classes that will be instrumented by the library, will autodetect if nil is passed. - public var delegateClassesToInstrument: [AnyClass]? - - /// Provides a baggage instance for instrumented requests that is merged with active baggage (if any). - /// The callback can be used to define static baggage for all requests or create dynamic baggage - /// based on the provided URLRequest and Span parameters. - /// - /// The resulting baggage is injected into request headers using the configured `TextMapBaggagePropagator`, - /// ensuring consistent propagation across requests, regardless of the active context. - /// - /// Note: The injected baggage depends on the propagator in use (e.g., W3C or custom). - /// Returns: A `Baggage` instance or `nil` if no baggage is needed. - public let baggageProvider: ((inout URLRequest, Span?) -> (Baggage)?)? - - /// The Array of Prefixes you can avoid in swizzle process - public let ignoredClassPrefixes: [String]? -} diff --git a/Sources/Instrumentation/URLSession/URLSessionLogger.swift b/Sources/Instrumentation/URLSession/URLSessionLogger.swift deleted file mode 100644 index e5f87dfa..00000000 --- a/Sources/Instrumentation/URLSession/URLSessionLogger.swift +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -import os.log -#if os(iOS) && !targetEnvironment(macCatalyst) - import NetworkStatus -#endif // os(iOS) && !targetEnvironment(macCatalyst) - -class URLSessionLogger { - static var runningSpans = [String: Span]() - static var runningSpansQueue = DispatchQueue(label: "io.opentelemetry.URLSessionLogger") - #if os(iOS) && !targetEnvironment(macCatalyst) - - static var netstatInjector: NetworkStatusInjector? = { () -> NetworkStatusInjector? in - do { - let netstats = try NetworkStatus() - return NetworkStatusInjector(netstat: netstats) - } catch { - if #available(iOS 14, macOS 11, tvOS 14, *) { - os_log(.error, "failed to initialize network connection status: %@", error.localizedDescription) - } else { - NSLog("failed to initialize network connection status: %@", error.localizedDescription) - } - - return nil - } - }() - #endif // os(iOS) && !targetEnvironment(macCatalyst) - - /// This methods creates a Span for a request, and optionally injects tracing headers, returns a new request if it was needed to create a new one to add the tracing headers - @discardableResult static func processAndLogRequest(_ request: URLRequest, sessionTaskId: String, instrumentation: URLSessionInstrumentation, shouldInjectHeaders: Bool) -> URLRequest? { - guard instrumentation.configuration.shouldInstrument?(request) ?? true else { - return nil - } - - var attributes = [String: AttributeValue]() - - attributes[SemanticAttributes.httpMethod.rawValue] = AttributeValue.string(request.httpMethod ?? "unknown_method") - - if let requestURL = request.url { - attributes[SemanticAttributes.httpUrl.rawValue] = AttributeValue.string(requestURL.absoluteString) - } - - if let requestURLPath = request.url?.path { - attributes[SemanticAttributes.httpTarget.rawValue] = AttributeValue.string(requestURLPath) - } - - if let host = request.url?.host { - attributes[SemanticAttributes.netPeerName.rawValue] = AttributeValue.string(host) - } - - if let requestScheme = request.url?.scheme { - attributes[SemanticAttributes.httpScheme.rawValue] = AttributeValue.string(requestScheme) - } - - if let port = request.url?.port { - attributes[SemanticAttributes.netPeerPort.rawValue] = AttributeValue.int(port) - } - - if let bodySize = request.httpBody?.count { - attributes[SemanticAttributes.httpRequestBodySize.rawValue] = AttributeValue.int(bodySize) - } - - var spanName = "HTTP " + (request.httpMethod ?? "") - if let customSpanName = instrumentation.configuration.nameSpan?(request) { - spanName = customSpanName - } - let spanBuilder = instrumentation.configuration.tracer.spanBuilder(spanName: spanName) - spanBuilder.setSpanKind(spanKind: .client) - attributes.forEach { - spanBuilder.setAttribute(key: $0.key, value: $0.value) - } - instrumentation.configuration.spanCustomization?(request, spanBuilder) - - let span = spanBuilder.startSpan() - runningSpansQueue.sync { - runningSpans[sessionTaskId] = span - } - - var returnRequest: URLRequest? - if shouldInjectHeaders, instrumentation.configuration.shouldInjectTracingHeaders?(request) ?? true { - returnRequest = instrumentedRequest(for: request, span: span, instrumentation: instrumentation) - } - - #if os(iOS) && !targetEnvironment(macCatalyst) - if let injector = netstatInjector { - injector.inject(span: span) - } - #endif - - instrumentation.configuration.createdRequest?(returnRequest ?? request, span) - - return returnRequest - } - - /// This methods ends a Span when a response arrives - static func logResponse(_ response: URLResponse, dataOrFile: Any?, instrumentation: URLSessionInstrumentation, sessionTaskId: String) { - var span: Span! - runningSpansQueue.sync { - span = runningSpans.removeValue(forKey: sessionTaskId) - } - guard span != nil, - let httpResponse = response as? HTTPURLResponse - else { - return - } - - let statusCode = httpResponse.statusCode - span.setAttribute(key: SemanticAttributes.httpStatusCode.rawValue, - value: AttributeValue.int(statusCode)) - span.status = statusForStatusCode(code: statusCode) - - if let contentLengthHeader = httpResponse.allHeaderFields["Content-Length"] as? String, - let contentLength = Int(contentLengthHeader) { - span.setAttribute(key: SemanticAttributes.httpResponseBodySize.rawValue, - value: AttributeValue.int(contentLength)) - } - - instrumentation.configuration.receivedResponse?(response, dataOrFile, span) - span.end() - } - - /// This methods ends a Span when a error arrives - static func logError(_ error: Error, dataOrFile: Any?, statusCode: Int, instrumentation: URLSessionInstrumentation, sessionTaskId: String) { - var span: Span! - runningSpansQueue.sync { - span = runningSpans.removeValue(forKey: sessionTaskId) - } - guard span != nil else { - return - } - span.setAttribute(key: SemanticAttributes.httpStatusCode.rawValue, value: AttributeValue.int(statusCode)) - span.status = URLSessionLogger.statusForStatusCode(code: statusCode) - instrumentation.configuration.receivedError?(error, dataOrFile, statusCode, span) - - span.end() - } - - private static func statusForStatusCode(code: Int) -> Status { - switch code { - case 100 ... 399: - return .unset - default: - return .error(description: String(code)) - } - } - - private static func instrumentedRequest(for request: URLRequest, span: Span?, instrumentation: URLSessionInstrumentation) -> URLRequest? { - var request = request - guard instrumentation.configuration.shouldInjectTracingHeaders?(request) ?? true - else { - return nil - } - instrumentation.configuration.injectCustomHeaders?(&request, span) - let customBaggage = instrumentation.configuration.baggageProvider?(&request, span) - - var instrumentedRequest = request - objc_setAssociatedObject(instrumentedRequest, URLSessionInstrumentation.instrumentedKey, true, .OBJC_ASSOCIATION_COPY_NONATOMIC) - let propagators = OpenTelemetry.instance.propagators - - var traceHeaders = tracePropagationHTTPHeaders(span: span, - customBaggage: customBaggage, - textMapPropagator: propagators.textMapPropagator, - textMapBaggagePropagator: propagators.textMapBaggagePropagator) - - if let originalHeaders = request.allHTTPHeaderFields { - traceHeaders.merge(originalHeaders) { _, new in new } - } - instrumentedRequest.allHTTPHeaderFields = traceHeaders - return instrumentedRequest - } - - private static func tracePropagationHTTPHeaders(span: Span?, customBaggage: Baggage?, textMapPropagator: TextMapPropagator, textMapBaggagePropagator: TextMapBaggagePropagator) -> [String: String] { - var headers = [String: String]() - - struct HeaderSetter: Setter { - func set(carrier: inout [String: String], key: String, value: String) { - carrier[key] = value - } - } - - guard let currentSpan = span ?? OpenTelemetry.instance.contextProvider.activeSpan else { - return headers - } - textMapPropagator.inject(spanContext: currentSpan.context, carrier: &headers, setter: HeaderSetter()) - - let baggageBuilder = OpenTelemetry.instance.baggageManager.baggageBuilder() - - if let activeBaggage = OpenTelemetry.instance.contextProvider.activeBaggage { - activeBaggage.getEntries().forEach { baggageBuilder.put(key: $0.key, value: $0.value, metadata: $0.metadata) } - } - - if let customBaggage { - customBaggage.getEntries().forEach { baggageBuilder.put(key: $0.key, value: $0.value, metadata: $0.metadata) } - } - - let combinedBaggage = baggageBuilder.build() - textMapBaggagePropagator.inject(baggage: combinedBaggage, carrier: &headers, setter: HeaderSetter()) - - return headers - } -} diff --git a/Tests/BridgesTests/OTelSwiftLog/LogHandlerTests.swift b/Tests/BridgesTests/OTelSwiftLog/LogHandlerTests.swift deleted file mode 100644 index f590b676..00000000 --- a/Tests/BridgesTests/OTelSwiftLog/LogHandlerTests.swift +++ /dev/null @@ -1,64 +0,0 @@ -import XCTest -import Logging -import OpenTelemetryApi - -@testable import OTelSwiftLog - -final class OTelLogHandlerTests: XCTestCase { - // TODO: Test log level for permissive and restrictive case - - func testLogHandlerMetadata() { - // TODO: Test different combination - var logHandler = OTelLogHandler() - logHandler.metadata = ["key": "value"] - XCTAssertEqual(logHandler.metadata["key"], "value") - logHandler[metadataKey: "anotherKey"] = "anotherValue" - XCTAssertEqual(logHandler.metadata["anotherKey"], "anotherValue") - } - - func testConvertToAttributeValue() { - // string test - let attributeValueString = convertToAttributeValue(Logging.Logger.Metadata.Value(stringLiteral: "HelloWorld")) - XCTAssertEqual(attributeValueString, AttributeValue.string("HelloWorld")) - - let attributeValueInt = convertToAttributeValue(Logging.Logger.Metadata.Value.stringConvertible(100)) - XCTAssertEqual(attributeValueInt, AttributeValue.string("100")) - - let attributeValueDictionary = convertToAttributeValue(Logger.Metadata.Value.dictionary(["myAttributes": Logger.Metadata.Value.dictionary([:])])) - XCTAssertEqual(attributeValueDictionary, AttributeValue.set(AttributeSet(labels: ["myAttributes": AttributeValue.set(AttributeSet(labels: [:]))]))) - - let attributeValueEmptyArray = - convertToAttributeValue(Logger.Metadata.Value.array([])) - XCTAssertEqual(attributeValueEmptyArray, AttributeValue.array(AttributeArray.empty)) - - let attributeValueArray = - convertToAttributeValue(Logger.Metadata.Value.array([Logger.Metadata.Value.stringConvertible(100), - Logger.Metadata.Value.string("string"), - Logger.Metadata.Value.array(["index0"]), - Logger.Metadata.Value.dictionary(["key": "value"])])) - - // is this the expected behavior? - XCTAssertEqual(attributeValueArray, - AttributeValue.array(AttributeArray(values: [.string("100"), - .string("string"), - .array(AttributeArray(values: [.string("index0")])), - .set(AttributeSet(labels: ["key": .string("value")]))]))) - - let attributeValueStringArray = convertToAttributeValue(Logger.Metadata.Value.array( - [Logger.Metadata.Value.stringConvertible(100), - Logger.Metadata.Value.string("string"), - Logger.Metadata.Value.stringConvertible(true)])) - - XCTAssertEqual(attributeValueStringArray, AttributeValue.array(AttributeArray(values: [AttributeValue.string("100"), AttributeValue.string("string"), AttributeValue.string("true")]))) - } - - func testConvertSeverity() { - XCTAssertEqual(convertSeverity(level: .trace), OpenTelemetryApi.Severity.trace) - XCTAssertEqual(convertSeverity(level: .debug), OpenTelemetryApi.Severity.debug) - XCTAssertEqual(convertSeverity(level: .info), OpenTelemetryApi.Severity.info) - XCTAssertEqual(convertSeverity(level: .notice), OpenTelemetryApi.Severity.info2) - XCTAssertEqual(convertSeverity(level: .warning), OpenTelemetryApi.Severity.warn) - XCTAssertEqual(convertSeverity(level: .error), OpenTelemetryApi.Severity.error) - XCTAssertEqual(convertSeverity(level: .critical), OpenTelemetryApi.Severity.error2) - } -} diff --git a/Tests/ContribTests/Processors/BaggagePropagationProcessorTests.swift b/Tests/ContribTests/Processors/BaggagePropagationProcessorTests.swift deleted file mode 100644 index 18594dc5..00000000 --- a/Tests/ContribTests/Processors/BaggagePropagationProcessorTests.swift +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import InMemoryExporter -import OpenTelemetryApi -import OpenTelemetrySdk -import BaggagePropagationProcessor -import XCTest - -class BaggagePropagationProcessorTests: XCTestCase { - func testProcessor() { - guard let key = EntryKey(name: "test-key") else { - XCTFail() - return - } - - guard let keep = EntryKey(name: "keepme") else { - XCTFail("cannot create entry key") - return - } - - guard let value = EntryValue(string: "test-value") else { - XCTFail() - return - } - - // create two baggage items, one we will keep and one will - // be filtered out by the processor - let b = DefaultBaggageManager.instance.baggageBuilder() - .put(key: key, value: value, metadata: nil) - .put(key: keep, value: value, metadata: nil) - .build() - - var processor = BaggagePropagationProcessor(filter: { $0.key.name == "keepme" }) - processor.activeBaggage = { b } - let exporter = InMemoryExporter() - let simple = SimpleSpanProcessor(spanExporter: exporter) - let tp = TracerProviderBuilder().add(spanProcessor: processor).add(spanProcessor: simple).build() - let tracer = tp.get(instrumentationName: "test", - instrumentationVersion: "1.0.0") - - let parent = tracer.spanBuilder(spanName: "parent").startSpan() - - let child = tracer.spanBuilder(spanName: "child").startSpan() - - child.end() - parent.end() - - simple.forceFlush() - - let spans = exporter.getFinishedSpanItems() - XCTAssertEqual(spans.count, 2) - - guard let pChild = spans.first(where: { $0.name == "child" }) else { - XCTFail("failed to find child span") - return - } - - XCTAssertTrue(spans.contains(where: { $0.name == "parent" })) - - XCTAssertEqual(pChild.attributes.count, 1) - - guard let attr = pChild.attributes.first else { - XCTFail("failed to get span attributes") - return - } - - XCTAssertEqual(attr.key, "keepme") - XCTAssertEqual(attr.value.description, "test-value") - } -} diff --git a/Tests/ExportersTests/InMemory/InMemoryExporterTests.swift b/Tests/ExportersTests/InMemory/InMemoryExporterTests.swift deleted file mode 100644 index 89225053..00000000 --- a/Tests/ExportersTests/InMemory/InMemoryExporterTests.swift +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -@testable import InMemoryExporter -@testable import OpenTelemetryApi -@testable import OpenTelemetrySdk -import XCTest - -final class InMemoryExporterTests: XCTestCase { - private var tracerSdkFactory = TracerProviderSdk() - private var spanProcessor: SpanProcessor! - private var tracer: Tracer! - private var exporter: InMemoryExporter! - - override func setUp() { - exporter = InMemoryExporter() - spanProcessor = SimpleSpanProcessor(spanExporter: exporter) - tracerSdkFactory.addSpanProcessor(spanProcessor) - tracer = tracerSdkFactory.get(instrumentationName: "InMemoryExporterTests") - } - - func testGetFinishedSpanItems() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - let spans = exporter.getFinishedSpanItems() - XCTAssertEqual(spans.count, 3) - XCTAssertEqual(spans[0].name, "one") - XCTAssertEqual(spans[1].name, "two") - XCTAssertEqual(spans[2].name, "three") - } - - func testResetClearsFinishedSpans() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - var spans = exporter.getFinishedSpanItems() - XCTAssertEqual(spans.count, 3) - - exporter.reset() - spans = exporter.getFinishedSpanItems() - XCTAssertEqual(spans.count, 0) - } - - func testResetDoesNotRestartAfterShutdown() { - tracer.spanBuilder(spanName: "one").startSpan().end() - spanProcessor.forceFlush() - - exporter.shutdown() - exporter.reset() - - XCTAssertEqual(exporter.export(spans: []), .failure) - } - - func testShutdownClearsFinishedSpans() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - exporter.shutdown() - - let spans = exporter.getFinishedSpanItems() - XCTAssertEqual(spans.count, 0) - } - - func testShutdownStopsFurtherExports() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - exporter.shutdown() - tracer.spanBuilder(spanName: "four").startSpan().end() - - let spans = exporter.getFinishedSpanItems() - XCTAssertEqual(spans.count, 0) - } - - func testExportReturnsSuccessWhenStarted() { - XCTAssertEqual(exporter.export(spans: []), .success) - } - - func testExportReturnsFailureWhenStopped() { - exporter.shutdown() - XCTAssertEqual(exporter.export(spans: []), .failure) - } - - func testFlushReturnsSuccessWhenRunning() { - XCTAssertEqual(exporter.flush(), .success) - } - - func testFlushReturnsFailiureWhenStopped() { - exporter.shutdown() - XCTAssertEqual(exporter.flush(), .failure) - } -} diff --git a/Tests/ExportersTests/Jaeger/AdapterTests.swift b/Tests/ExportersTests/Jaeger/AdapterTests.swift deleted file mode 100644 index d28700b1..00000000 --- a/Tests/ExportersTests/Jaeger/AdapterTests.swift +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if !os(watchOS) && !os(visionOS) - - import Foundation - - @testable import JaegerExporter - @testable import OpenTelemetryApi - @testable import OpenTelemetrySdk - import Thrift - import XCTest - - class AdapterTests: XCTestCase { - static let linkTraceId = "00000000000000000000000000cba123" - static let linkSpanId = "0000000000fed456" - static let traceId = "00000000000000000000000000abc123" - static let spanId = "0000000000def456" - static let parentSpanId = "0000000000aef789" - - let microsecondsInSecond: Double = 1000000 - - func testProtoSpans() { - let duration = 900 // microseconds - let startMicroseconds = UInt64(Date().timeIntervalSince1970 * microsecondsInSecond) - let endMicroseconds = startMicroseconds + UInt64(duration) - - let span = getSpanData(startMicroseconds: startMicroseconds, endMicroseconds: endMicroseconds) - let spans = [span] - - let jaegerSpans = Adapter.toJaeger(spans: spans) - - // the span contents are checked somewhere else - XCTAssertEqual(jaegerSpans.count, 1) - } - - func testProtoSpan() { - let duration = 900 // microseconds - let startMicroseconds = UInt64(Date().timeIntervalSince1970 * microsecondsInSecond) - let endMicroseconds = startMicroseconds + UInt64(duration) - - let span = getSpanData(startMicroseconds: startMicroseconds, endMicroseconds: endMicroseconds) - - // test - let jaegerSpan = Adapter.toJaeger(span: span) - - XCTAssertEqual(span.traceId.hexString, String(format: "%016llx", jaegerSpan.traceIdHigh) + String(format: "%016llx", jaegerSpan.traceIdLow)) - XCTAssertEqual(span.spanId.hexString, String(format: "%016llx", jaegerSpan.spanId)) - XCTAssertEqual("GET /api/endpoint", jaegerSpan.operationName) - XCTAssertEqual(Int64(startMicroseconds), jaegerSpan.startTime) - XCTAssertEqual(duration, Int(jaegerSpan.duration)) - - XCTAssertEqual(jaegerSpan.tags?.count, 4) - var tag = getTag(tagsList: jaegerSpan.tags, key: Adapter.keySpanKind) - XCTAssertNotNil(tag) - XCTAssertEqual(tag?.vStr, "SERVER") - tag = getTag(tagsList: jaegerSpan.tags, key: Adapter.keySpanStatusCode) - XCTAssertNotNil(tag) - XCTAssertEqual(tag?.vLong, 0) - tag = getTag(tagsList: jaegerSpan.tags, key: Adapter.keySpanStatusMessage) - XCTAssertNotNil(tag) - XCTAssertEqual(tag?.vStr, "") - - XCTAssertEqual(jaegerSpan.logs?.count, 1) - let log = jaegerSpan.logs?.first - tag = getTag(tagsList: log?.fields, key: Adapter.keyLogMessage) - XCTAssertNotNil(tag) - XCTAssertEqual(tag?.vStr, "the log message") - tag = getTag(tagsList: log?.fields, key: "foo") - XCTAssertNotNil(tag) - XCTAssertEqual(tag?.vStr, "bar") - - XCTAssertEqual(jaegerSpan.references?.count, 2) - - AdapterTests.assertHasFollowsFrom(jaegerSpan: jaegerSpan) - AdapterTests.assertHasParent(jaegerSpan: jaegerSpan) - } - - func testJaegerLogs() { - // prepare - let event = getTimedEvent() - - // test - let logs = Adapter.toJaegerLogs(events: [event]) - - // verify - XCTAssertEqual(logs.count, 1) - } - - func testJaegerLog() { - // prepare - let event = getTimedEvent() - - // test - let log = Adapter.toJaegerLog(event: event) - - // verify - XCTAssertEqual(log.fields.count, 2) - - var tag = getTag(tagsList: log.fields, key: Adapter.keyLogMessage) - XCTAssertNotNil(tag) - XCTAssertEqual("the log message", tag?.vStr) - tag = getTag(tagsList: log.fields, key: "foo") - XCTAssertNotNil(tag) - XCTAssertEqual("bar", tag?.vStr) - } - - func testTags() { - // prepare - let valueB = AttributeValue.bool(true) - - // test - let tags = Adapter.toJaegerTags(attributes: ["valueB": valueB]) - - // verify - // the actual content is checked in some other test - XCTAssertEqual(1, tags.count) - } - - func testKeyValue() { - // prepare - let valueB = AttributeValue.bool(true) - let valueD = AttributeValue.double(1.0) - let valueI = AttributeValue.int(2) - let valueS = AttributeValue.string("foobar") - let valueArrayB = AttributeValue([true, false]) - let valueArrayD = AttributeValue([1.2, 4.5]) - let valueArrayI = AttributeValue([12345, 67890]) - let valueArrayS = AttributeValue(["foobar", "barfoo"]) - - // test - let kvB = Adapter.toJaegerTag(key: "valueB", attrib: valueB) - let kvD = Adapter.toJaegerTag(key: "valueD", attrib: valueD) - let kvI = Adapter.toJaegerTag(key: "valueI", attrib: valueI) - let kvS = Adapter.toJaegerTag(key: "valueS", attrib: valueS) - let kvArrayB = Adapter.toJaegerTag(key: "valueArrayB", attrib: valueArrayB) - let kvArrayD = Adapter.toJaegerTag(key: "valueArrayD", attrib: valueArrayD) - let kvArrayI = Adapter.toJaegerTag(key: "valueArrayI", attrib: valueArrayI) - let kvArrayS = Adapter.toJaegerTag(key: "valueArrayS", attrib: valueArrayS) - - // verify - XCTAssertTrue(kvB.vBool ?? false) - XCTAssertEqual(TagType.bool, kvB.vType) - XCTAssertEqual(kvD.vDouble, 1.0) - XCTAssertEqual(TagType.double, kvD.vType) - XCTAssertEqual(kvI.vLong, 2) - XCTAssertEqual(TagType.long, kvI.vType) - XCTAssertEqual("foobar", kvS.vStr) - XCTAssertEqual(TagType.string, kvS.vType) - XCTAssertEqual("[true, false]", kvArrayB.vStr) - XCTAssertEqual(TagType.string, kvArrayB.vType) - XCTAssertEqual("[1.2, 4.5]", kvArrayD.vStr) - XCTAssertEqual(TagType.string, kvArrayD.vType) - XCTAssertEqual("[12345, 67890]", kvArrayI.vStr) - XCTAssertEqual(TagType.string, kvArrayI.vType) - XCTAssertEqual("[\"foobar\", \"barfoo\"]", kvArrayS.vStr) - XCTAssertEqual(TagType.string, kvArrayS.vType) - } - - func testSpanRefs() { - // prepare - let link = SpanData.Link(context: createSpanContext(traceId: "00000000000000000000000000cba123", spanId: "0000000000fed456")) - - // test - let spanRefs = Adapter.toSpanRefs(links: [link]) - - // verify - XCTAssertEqual(1, spanRefs.count) // the actual span ref is tested in another test - } - - func testSpanRef() { - // prepare - let link = SpanData.Link(context: createSpanContext(traceId: AdapterTests.traceId, spanId: AdapterTests.spanId)) - - // test - let spanRef = Adapter.toSpanRef(link: link) - - // verify - - XCTAssertEqual(AdapterTests.traceId, String(format: "%016llx", spanRef.traceIdHigh) + String(format: "%016llx", spanRef.traceIdLow)) - XCTAssertEqual(AdapterTests.spanId, String(format: "%016llx", spanRef.spanId)) - XCTAssertEqual(spanRef.refType, SpanRefType.follows_from) - } - - func testStatusNotOk() { - let startMicroseconds = UInt64(Date().timeIntervalSince1970 * microsecondsInSecond) - let endMicroseconds = startMicroseconds + 900 - - let span = SpanData(traceId: TraceId(fromHexString: AdapterTests.traceId), - spanId: SpanId(fromHexString: AdapterTests.spanId), - traceFlags: TraceFlags(), - traceState: TraceState(), - resource: Resource(), - instrumentationScope: InstrumentationScopeInfo(), - name: "GET /api/endpoint", - kind: .server, - startTime: Date(timeIntervalSince1970: Double(startMicroseconds) / microsecondsInSecond), - status: .error(description: "GenericError"), - endTime: Date(timeIntervalSince1970: Double(endMicroseconds) / microsecondsInSecond), - hasRemoteParent: false) - - XCTAssertNotNil(Adapter.toJaeger(span: span)) - } - - func testSpanError() { - let attributes = ["error.type": AttributeValue.string(name), - "error.message": AttributeValue.string("server error")] - let startMicroseconds = UInt64(Date().timeIntervalSince1970 * microsecondsInSecond) - let endMicroseconds = startMicroseconds + 900 - - var span = SpanData(traceId: TraceId(fromHexString: AdapterTests.traceId), - spanId: SpanId(fromHexString: AdapterTests.spanId), - name: "GET /api/endpoint", - kind: .server, - startTime: Date(timeIntervalSince1970: Double(startMicroseconds) / microsecondsInSecond), - endTime: Date(timeIntervalSince1970: Double(endMicroseconds) / microsecondsInSecond)) - span.settingHasEnded(true) - span.settingStatus(.error(description: "GenericError")) - span.settingAttributes(attributes) - - let jaegerSpan = Adapter.toJaeger(span: span) - let errorType = getTag(tagsList: jaegerSpan.tags, key: "error.type") - XCTAssertEqual(name, errorType?.vStr) - let error = getTag(tagsList: jaegerSpan.tags, key: "error") - XCTAssertNotNil(error) - XCTAssertEqual(true, error?.vBool) - } - - private func getTimedEvent() -> SpanData.Event { - let valueS = AttributeValue.string("bar") - let attributes = ["foo": valueS] - return SpanData.Event(name: "the log message", timestamp: Date(), attributes: attributes) - } - - private func getSpanData(startMicroseconds: UInt64, endMicroseconds: UInt64) -> SpanData { - let valueB = AttributeValue.bool(true) - let attributes = ["valueB": valueB] - - let link = SpanData.Link(context: createSpanContext(traceId: AdapterTests.linkTraceId, spanId: AdapterTests.linkSpanId), attributes: attributes) - - return SpanData(traceId: TraceId(fromHexString: AdapterTests.traceId), - spanId: SpanId(fromHexString: AdapterTests.spanId), - traceFlags: TraceFlags(), - traceState: TraceState(), - parentSpanId: SpanId(fromHexString: AdapterTests.parentSpanId), - resource: Resource(), - instrumentationScope: InstrumentationScopeInfo(), - name: "GET /api/endpoint", - kind: .server, - startTime: Date(timeIntervalSince1970: Double(startMicroseconds) / microsecondsInSecond), - attributes: attributes, - events: [getTimedEvent()], - links: [link], - status: Status.ok, - endTime: Date(timeIntervalSince1970: Double(endMicroseconds) / microsecondsInSecond), - hasRemoteParent: false) - } - - private func createSpanContext(traceId: String, spanId: String) -> SpanContext { - return SpanContext.create(traceId: TraceId(fromHexString: traceId), spanId: SpanId(fromHexString: spanId), traceFlags: TraceFlags(), traceState: TraceState()) - } - - private func getTag(tagsList: TList?, key: String) -> Tag? { - return tagsList?.first { $0.key == key } - } - - private static func assertHasFollowsFrom(jaegerSpan: JaegerExporter.Span) { - var found = false - for spanRef in jaegerSpan.references! { - if spanRef.refType == .follows_from { - XCTAssertEqual(TraceId(fromHexString: linkTraceId).idHi, UInt64(spanRef.traceIdHigh)) - XCTAssertEqual(TraceId(fromHexString: linkTraceId).idLo, UInt64(spanRef.traceIdLow)) - XCTAssertEqual(SpanId(fromHexString: linkSpanId).id, UInt64(spanRef.spanId)) - found = true - } - } - XCTAssertTrue(found) - } - - private static func assertHasParent(jaegerSpan: JaegerExporter.Span) { - var found = false - for spanRef in jaegerSpan.references! { - if spanRef.refType == .child_of { - XCTAssertEqual(TraceId(fromHexString: traceId).idHi, UInt64(spanRef.traceIdHigh)) - XCTAssertEqual(TraceId(fromHexString: traceId).idLo, UInt64(spanRef.traceIdLow)) - XCTAssertEqual(SpanId(fromHexString: parentSpanId).id, UInt64(spanRef.spanId)) - found = true - } - } - XCTAssertTrue(found) - } - } - -#endif diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/CommonAdapterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/CommonAdapterTests.swift deleted file mode 100644 index 85865de8..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/CommonAdapterTests.swift +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -@testable import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk -import XCTest - -class CommonAdapterTests: XCTestCase { - func testToProtoAttributeBool() { - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.boolValue = true - XCTAssertEqual(CommonAdapter.toProtoAttribute(key: "key", attributeValue: AttributeValue.bool(true)), attribute) - } - - func testToProtoAttributeString() { - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.stringValue = "string" - XCTAssertEqual(CommonAdapter.toProtoAttribute(key: "key", attributeValue: AttributeValue.string("string")), attribute) - } - - func testToProtoAttributeInt() { - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.intValue = 100 - XCTAssertEqual(CommonAdapter.toProtoAttribute(key: "key", attributeValue: AttributeValue.int(100)), attribute) - } - - func testToProtoAttributeDouble() { - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.doubleValue = 100.3 - XCTAssertEqual(CommonAdapter.toProtoAttribute(key: "key", attributeValue: AttributeValue.double(100.3)), attribute) - } - - func testToProtoInstrumentationScope() { - let instrumentationScope = CommonAdapter.toProtoInstrumentationScope(instrumentationScopeInfo: InstrumentationScopeInfo(name: "name", version: "version")) - XCTAssertEqual(instrumentationScope.name, "name") - XCTAssertEqual(instrumentationScope.version, "version") - } - - func testToProtoInstrumentationScopeNoVersion() { - let instrumentationScope = CommonAdapter.toProtoInstrumentationScope( - instrumentationScopeInfo: InstrumentationScopeInfo( - name: "name", - version: "1.2.0", - attributes: ["myAttribute": AttributeValue.string("myValue")] - ) - ) - XCTAssertEqual(instrumentationScope.name, "name") - XCTAssertEqual(instrumentationScope.version, "1.2.0") - XCTAssertEqual(instrumentationScope.attributes.count, 1) - XCTAssertEqual(instrumentationScope.attributes.first?.value.stringValue, "myValue") - XCTAssertEqual(instrumentationScope.attributes.first?.key, "myAttribute") - } - - func testToProtoAnyValue() { - let anyStringValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue.string("hello,world")) - XCTAssertEqual(anyStringValue.stringValue, "hello,world") - - let anyBoolValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue.bool(false)) - XCTAssertFalse(anyBoolValue.boolValue) - - let anyIntValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue.int(12)) - XCTAssertEqual(anyIntValue.intValue, 12) - - let anyDoubleValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue.double(3.14)) - XCTAssertEqual(anyDoubleValue.doubleValue, 3.14) - - let anyStringArrayValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue(["hello"])) - - XCTAssertEqual(anyStringArrayValue.arrayValue.values.count, 1) - XCTAssertTrue(anyStringArrayValue.arrayValue.values[0].stringValue == "hello") - - let anyBoolArrayValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue([true])) - - XCTAssertEqual(anyBoolArrayValue.arrayValue.values.count, 1) - XCTAssertTrue(anyBoolArrayValue.arrayValue.values[0].boolValue) - - let anyIntArrayValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue([1])) - XCTAssertEqual(anyIntArrayValue.arrayValue.values.count, 1) - XCTAssertTrue(anyIntArrayValue.arrayValue.values[0].intValue == 1) - - let anyDoubleArrayValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue([3.14])) - XCTAssertEqual(anyDoubleArrayValue.arrayValue.values.count, 1) - XCTAssertTrue(anyDoubleArrayValue.arrayValue.values[0].doubleValue == 3.14) - - let anySetValue = CommonAdapter.toProtoAnyValue(attributeValue: AttributeValue.set(AttributeSet(labels: ["Hello": AttributeValue.string("world")]))) - XCTAssertTrue(anySetValue.kvlistValue.values.count == 1) - XCTAssertTrue(anySetValue.kvlistValue.values[0].key == "Hello") - XCTAssertTrue(anySetValue.kvlistValue.values[0].value.stringValue == "world") - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/EnvVarHeadersTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/EnvVarHeadersTests.swift deleted file mode 100644 index ea6a86eb..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/EnvVarHeadersTests.swift +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryProtocolExporterCommon -import XCTest - -class EnvVarHeadersTests: XCTestCase { - func test_attributesIsNil_whenAccessedThroughStaticProperty() throws { - XCTAssertNil(EnvVarHeaders.attributes) - } - - func test_attributesIsNil_whenNoRawValueProvided() throws { - XCTAssertNil(EnvVarHeaders.attributes(for: nil)) - } - - func test_attributesContainOneKeyValuePair_whenRawValueProvidedHasOneKeyValuePair() throws { - let capturedAttributes = EnvVarHeaders.attributes(for: "key1=value1") - XCTAssertNotNil(capturedAttributes) - XCTAssertEqual(capturedAttributes![0].0, "key1") - XCTAssertEqual(capturedAttributes![0].1, "value1") - } - - func test_attributesIsNil_whenInvalidRawValueProvided() throws { - XCTAssertNil(EnvVarHeaders.attributes(for: "key1")) - } - - func test_attributesContainTwoKeyValuePair_whenRawValueProvidedHasTwoKeyValuePair() throws { - let capturedAttributes = EnvVarHeaders.attributes(for: " key1=value1, key2 = value2 ") - XCTAssertNotNil(capturedAttributes) - XCTAssertEqual(capturedAttributes![0].0, "key1") - XCTAssertEqual(capturedAttributes![0].1, "value1") - XCTAssertEqual(capturedAttributes![1].0, "key2") - XCTAssertEqual(capturedAttributes![1].1, "value2") - } - - func test_attributesIsNil_whenRawValueContainsWhiteSpace() throws { - let capturedAttributes = EnvVarHeaders.attributes(for: "key=value with\twhitespace") - XCTAssertNil(capturedAttributes) - } - - func test_attributesExcludesInvalidTuples_whenRawValueContainsInvalidCharacters() throws { - let capturedAttributes = EnvVarHeaders.attributes(for: "key=value with whitespace") - XCTAssertNil(capturedAttributes) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift deleted file mode 100644 index 8b81dccb..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation - -import Foundation -import OpenTelemetryApi -@testable import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetrySdk -import XCTest - -class LogRecordAdapterTests: XCTestCase { - let traceIdBytes: [UInt8] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4] - let spanIdBytes: [UInt8] = [0, 0, 0, 0, 4, 3, 2, 1] - var traceId: TraceId! - var spanId: SpanId! - let tracestate = TraceState() - var spanContext: SpanContext! - - override func setUp() { - traceId = TraceId(fromBytes: traceIdBytes) - spanId = SpanId(fromBytes: spanIdBytes) - spanContext = SpanContext.create(traceId: traceId, spanId: spanId, traceFlags: TraceFlags(), traceState: tracestate) - } - - func testToResourceProto() { - let logRecord = ReadableLogRecord(resource: Resource(), instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), timestamp: Date(), attributes: ["event.name": AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) - - let result = LogRecordAdapter.toProtoResourceRecordLog(logRecordList: [logRecord]) - - XCTAssertTrue(result[0].scopeLogs.count > 0) - } - - func testToProto() { - let timestamp = Date() - let logRecord = ReadableLogRecord(resource: Resource(), - instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), - timestamp: timestamp, - observedTimestamp: Date.distantPast, - spanContext: spanContext, - severity: .fatal, - body: AttributeValue.string("Hello, world"), - attributes: ["event.name": AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) - - let protoLog = LogRecordAdapter.toProtoLogRecord(logRecord: logRecord) - - XCTAssertEqual(protoLog.body.stringValue, "Hello, world") - XCTAssertEqual(protoLog.hasBody, true) - XCTAssertEqual(protoLog.severityText, "FATAL") - XCTAssertEqual(protoLog.observedTimeUnixNano, Date.distantPast.timeIntervalSince1970.toNanoseconds) - XCTAssertEqual(protoLog.severityNumber.rawValue, Severity.fatal.rawValue) - XCTAssertEqual(protoLog.spanID, Data(bytes: spanIdBytes, count: 8)) - XCTAssertEqual(protoLog.traceID, Data(bytes: traceIdBytes, count: 16)) - XCTAssertEqual(protoLog.timeUnixNano, timestamp.timeIntervalSince1970.toNanoseconds) - XCTAssertEqual(protoLog.attributes.count, 2) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/MetricsAdapterTest.swift b/Tests/ExportersTests/OpenTelemetryProtocol/MetricsAdapterTest.swift deleted file mode 100644 index ce3a8720..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/MetricsAdapterTest.swift +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import XCTest -import OpenTelemetryApi -@testable import OpenTelemetryProtocolExporterGrpc -@testable import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetrySdk - -final class MetricsAdapterTest: XCTestCase { - let resource = Resource(attributes: ["foo": AttributeValue("bar")]) - let instrumentationScopeInfo = InstrumentationScopeInfo(name: "test") - let unit = "unit" - - var testCaseDescription: String { - String(describing: self) - } - - func testToProtoResourceMetricsWithLongGuage() throws { - let pointValue = Int.random(in: 1 ... 999) - let point: PointData = LongPointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [], value: pointValue) - let guageData = GaugeData( - aggregationTemporality: .cumulative, - points: [point] - ) - let metricData = MetricData.createLongGauge( - resource: resource, - instrumentationScopeInfo: instrumentationScopeInfo, - name: name, - description: testCaseDescription, - unit: unit, - data: guageData - ) - - let result = MetricsAdapter.toProtoMetric(metricData: metricData) - guard let value = result?.gauge.dataPoints as? [Opentelemetry_Proto_Metrics_V1_NumberDataPoint] else { - let actualType = type(of: result?.gauge.dataPoints) - let errorMessage = "Got wrong type: \(actualType)" - XCTFail(errorMessage) - throw errorMessage - } - - XCTAssertEqual(value.first?.asInt, Int64(pointValue)) - } - - func testToProtoResourceMetricsWithLongSum() throws { - let pointValue = Int.random(in: 1 ... 999) - let point: PointData = LongPointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [], value: pointValue) - let sumData = SumData(aggregationTemporality: .cumulative, points: [point]) - let metricData = MetricData.createLongSum( - resource: resource, - instrumentationScopeInfo: instrumentationScopeInfo, - name: name, - description: testCaseDescription, - unit: unit, - isMonotonic: true, - data: sumData - ) - - let result = MetricsAdapter.toProtoMetric(metricData: metricData) - guard let value = result?.sum.dataPoints as? [Opentelemetry_Proto_Metrics_V1_NumberDataPoint] else { - let actualType = type(of: result?.gauge.dataPoints) - let errorMessage = "Got wrong type: \(actualType)" - XCTFail(errorMessage) - throw errorMessage - } - - XCTAssertEqual(value.first?.asInt, Int64(pointValue)) - XCTAssertEqual(result?.sum.isMonotonic, true) - } - - func testToProtoResourceMetricsWithDoubleGuage() throws { - let pointValue = Double.random(in: 1 ... 999) - let point: PointData = DoublePointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [], value: pointValue) - let guageData = GaugeData( - aggregationTemporality: .cumulative, - points: [point] - ) - let metricData = MetricData.createDoubleGauge( - resource: resource, - instrumentationScopeInfo: instrumentationScopeInfo, - name: name, - description: testCaseDescription, - unit: unit, - data: guageData - ) - - let result = MetricsAdapter.toProtoMetric(metricData: metricData) - guard let value = result?.gauge.dataPoints as? [Opentelemetry_Proto_Metrics_V1_NumberDataPoint] else { - let actualType = type(of: result?.gauge.dataPoints) - let errorMessage = "Got wrong type: \(actualType)" - XCTFail(errorMessage) - throw errorMessage - } - - XCTAssertEqual(value.first?.asDouble, pointValue) - } - - func testToProtoResourceMetricsWithDoubleSum() throws { - let pointValue = Double.random(in: 1 ... 999) - let point: PointData = DoublePointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [], value: pointValue) - let sumData = SumData(aggregationTemporality: .cumulative, points: [point]) - let metricData = MetricData.createDoubleSum( - resource: resource, - instrumentationScopeInfo: instrumentationScopeInfo, - name: name, - description: testCaseDescription, - unit: unit, - isMonotonic: false, - data: sumData - ) - - let result = MetricsAdapter.toProtoMetric(metricData: metricData) - guard let value = result?.sum.dataPoints as? [Opentelemetry_Proto_Metrics_V1_NumberDataPoint] else { - let actualType = type(of: result?.gauge.dataPoints) - let errorMessage = "Got wrong type: \(actualType)" - XCTFail(errorMessage) - throw errorMessage - } - - XCTAssertEqual(value.first?.asDouble, pointValue) - XCTAssertEqual(result?.sum.isMonotonic, false) - } - - func testToProtoResourceMetricsWithHistogram() throws { - let boundaries = [Double]() - let sum = Double.random(in: 1 ... 999) - let min = Double.greatestFiniteMagnitude - let max: Double = -1 - let count = Int.random(in: 1 ... 100) - let counts = Array(repeating: 0, count: boundaries.count + 1) - let histogramPointData = HistogramPointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [ExemplarData](), sum: sum, count: UInt64(count), min: min, max: max, boundaries: boundaries, counts: counts, hasMin: count > 0, hasMax: count > 0) - let points = [histogramPointData] - let histogramData = HistogramData( - aggregationTemporality: .cumulative, - points: points - ) - let metricData = MetricData.createHistogram( - resource: resource, - instrumentationScopeInfo: instrumentationScopeInfo, - name: name, - description: testCaseDescription, - unit: unit, - data: histogramData - ) - - let result = MetricsAdapter.toProtoMetric(metricData: metricData) - guard let value = result?.histogram.dataPoints as? [Opentelemetry_Proto_Metrics_V1_HistogramDataPoint]? else { - let actualType = type(of: result?.gauge.dataPoints) - let errorMessage = "Got wrong type: \(actualType)" - XCTFail(errorMessage) - throw errorMessage - } - - XCTAssertEqual(value?.first?.sum, sum) - XCTAssertEqual(value?.first?.count, UInt64(count)) - } - - func testToProtoResourceMetricsWithExponentialHistogram() throws { - let positivieBuckets = DoubleBase2ExponentialHistogramBuckets(scale: 20, maxBuckets: 160) - positivieBuckets.downscale(by: 20) - positivieBuckets.record(value: 10.0) - positivieBuckets.record(value: 40.0) - positivieBuckets.record(value: 90.0) - positivieBuckets.record(value: 100.0) - let negativeBuckets = DoubleBase2ExponentialHistogramBuckets(scale: 20, maxBuckets: 160) - - let expHistogramPointData = ExponentialHistogramPointData(scale: 20, sum: 240.0, zeroCount: 0, hasMin: true, hasMax: true, min: 10.0, max: 100.0, positiveBuckets: positivieBuckets, negativeBuckets: negativeBuckets, startEpochNanos: 0, epochNanos: 1, attributes: [:], exemplars: []) - - let points = [expHistogramPointData] - let histogramData = ExponentialHistogramData( - aggregationTemporality: .delta, - points: points - ) - let metricData = MetricData.createExponentialHistogram( - resource: resource, - instrumentationScopeInfo: instrumentationScopeInfo, - name: name, - description: testCaseDescription, - unit: unit, - data: histogramData - ) - - let result = MetricsAdapter.toProtoMetric(metricData: metricData) - guard let value = result?.exponentialHistogram.dataPoints as? [Opentelemetry_Proto_Metrics_V1_ExponentialHistogramDataPoint]? else { - let actualType = type(of: result?.gauge.dataPoints) - let errorMessage = "Got wrong type: \(actualType)" - XCTFail(errorMessage) - throw errorMessage - } - - XCTAssertEqual(value?.first?.scale, 20) - XCTAssertEqual(value?.first?.sum, 240) - XCTAssertEqual(value?.first?.count, 4) - XCTAssertEqual(value?.first?.min, 10) - XCTAssertEqual(value?.first?.max, 100) - XCTAssertEqual(value?.first?.zeroCount, 0) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHTTPExporterBaseTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHTTPExporterBaseTests.swift deleted file mode 100644 index 71574c8f..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHTTPExporterBaseTests.swift +++ /dev/null @@ -1,141 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -#if canImport(Compression) - import DataCompression - - import Foundation - #if canImport(FoundationNetworking) - import FoundationNetworking - #endif - import Logging - import NIO - import NIOHTTP1 - import NIOTestUtils - import OpenTelemetryApi - import OpenTelemetryProtocolExporterCommon - @testable import OpenTelemetryProtocolExporterHttp - @testable import OpenTelemetrySdk - import XCTest - - class OtlpHttpExporterBaseTests: XCTestCase { - var exporter: OtlpHttpExporterBase! - var spans: [SpanData] = [] - - override func setUp() { - super.setUp() - - spans = [] - let endpointName1 = "/api/foo" + String(Int.random(in: 1 ... 100)) - let endpointName2 = "/api/bar" + String(Int.random(in: 100 ... 500)) - spans.append(generateFakeSpan(endpointName: endpointName1)) - spans.append(generateFakeSpan(endpointName: endpointName2)) - } - - // Test for .gzip compression - func testCreateRequestWithGzipCompression() { - let config = OtlpConfiguration(compression: .gzip) - - exporter = OtlpHttpExporterBase( - endpoint: URL( - string: "http://example.com" - )!, - config: config, - httpClient: BaseHTTPClient() - ) - - let body = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans) - } - - let request = exporter.createRequest(body: body, endpoint: URL(string: "http://example.com")!) - - /// gzip - let data = try! body.serializedData().gzip() - - // Verify Content-Encoding header is set to "gzip" - XCTAssertEqual(request.value(forHTTPHeaderField: "Content-Encoding"), "gzip") - XCTAssertNotNil(request.httpBody) - XCTAssertEqual(request.httpBody!.count, data!.count) - } - - // Test for .deflate compression - func testCreateRequestWithDeflateCompression() { - let config = OtlpConfiguration(compression: .deflate) - - exporter = OtlpHttpExporterBase( - endpoint: URL( - string: "http://example.com" - )!, - config: config, - httpClient: BaseHTTPClient() - ) - - let body = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans) - } - - let request = exporter.createRequest(body: body, endpoint: URL(string: "http://example.com")!) - - /// deflate - let data = try! body.serializedData().deflate() - - // Verify Content-Encoding header is set to "deflate" - XCTAssertEqual(request.value(forHTTPHeaderField: "Content-Encoding"), "deflate") - XCTAssertNotNil(request.httpBody) - XCTAssertEqual(request.httpBody!.count, data!.count) - } - - // Test for .none compression (no compression) - func testCreateRequestWithNoCompression() { - let config = OtlpConfiguration(compression: .none) - - exporter = OtlpHttpExporterBase( - endpoint: URL( - string: "http://example.com" - )!, - config: config, - httpClient: BaseHTTPClient() - ) - - let body = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with { - $0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans) - } - - let request = exporter.createRequest(body: body, endpoint: URL(string: "http://example.com")!) - - let data = try! body.serializedData() - - // Verify Content-Encoding header is set to "deflate" - XCTAssertEqual(request.value(forHTTPHeaderField: "Content-Encoding"), nil) - XCTAssertNotNil(request.httpBody) - XCTAssertEqual(request.httpBody!.count, data.count) - } - - private func generateFakeSpan(endpointName: String = "/api/endpoint") -> SpanData { - let duration = 0.9 - let start = Date() - let end = start.addingTimeInterval(duration) - let testattributes: [String: AttributeValue] = ["foo": AttributeValue("bar")!, "fizz": AttributeValue("buzz")!] - - var testData = SpanData(traceId: TraceId.random(), - spanId: SpanId.random(), - name: "GET " + endpointName, - kind: SpanKind.server, - startTime: start, - endTime: end, - totalAttributeCount: 2) - testData.settingAttributes(testattributes) - testData.settingTotalAttributeCount(2) - testData.settingHasEnded(true) - testData.settingTotalRecordedEvents(0) - testData.settingLinks([SpanData.Link]()) - testData.settingTotalRecordedLinks(0) - testData.settingStatus(.ok) - - return testData - } - } -#endif \ No newline at end of file diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHTTPMetricsExporterTest.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHTTPMetricsExporterTest.swift deleted file mode 100644 index e7f2319c..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHTTPMetricsExporterTest.swift +++ /dev/null @@ -1,232 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import Logging -import NIO -import NIOHTTP1 -import NIOTestUtils -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetryProtocolExporterHttp -@testable import OpenTelemetrySdk -import XCTest - -class OtlpHttpMetricsExporterTest: XCTestCase { - var testServer: NIOHTTP1TestServer! - var group: MultiThreadedEventLoopGroup! - - override func setUp() { - group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - testServer = NIOHTTP1TestServer(group: group) - } - - override func tearDown() { - XCTAssertNoThrow(try testServer.stop()) - XCTAssertNoThrow(try group.syncShutdownGracefully()) - } - - // The shutdown() function is a no-op, This test is just here to make codecov happy - func testShutdown() { - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter(endpoint: endpoint) - XCTAssertEqual(exporter.shutdown(), .success) - } - - func testExportHeader() { - let metric = generateSumStableMetricData() - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter( - endpoint: endpoint, - config: OtlpConfiguration(headers: [("headerName", "headerValue")]) - ) - let result = exporter.export(metrics: [metric]) - XCTAssertEqual(result, ExportResult.success) - - XCTAssertNoThrow(try testServer.receiveHeadAndVerify { head in - XCTAssertTrue(head.headers.contains(name: "headerName")) - XCTAssertEqual("headerValue", head.headers.first(name: "headerName")) - }) - - XCTAssertNotNil(try testServer.receiveBodyAndVerify()) - XCTAssertNoThrow(try testServer.receiveEnd()) - } - - func testExport() { - let words = ["foo", "bar", "fizz", "buzz"] - var metrics: [MetricData] = [] - var metricDescriptions: [String] = [] - for word in words { - let metricDescription = word + String(Int.random(in: 1 ... 100)) - metricDescriptions.append(metricDescription) - metrics.append(generateSumStableMetricData(description: metricDescription)) - } - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter( - endpoint: endpoint, - config: .init(compression: .none) - ) - let result = exporter.export(metrics: metrics) - XCTAssertEqual(result, ExportResult.success) - - XCTAssertNoThrow(try testServer.receiveHeadAndVerify { head in - let otelVersion = Headers.getUserAgentHeader() - XCTAssertTrue(head.headers.contains(name: Constants.HTTP.userAgent)) - XCTAssertEqual(otelVersion, head.headers.first(name: Constants.HTTP.userAgent)) - }) - - XCTAssertNoThrow(try testServer.receiveBodyAndVerify { body in - var contentsBuffer = ByteBuffer(buffer: body) - let contents = contentsBuffer.readString(length: contentsBuffer.readableBytes)! - for metricDescription in metricDescriptions { - XCTAssertTrue(contents.contains(metricDescription)) - } - }) - - XCTAssertNoThrow(try testServer.receiveEnd()) - } - - func testGaugeExport() { - let words = ["foo", "bar", "fizz", "buzz"] - var metrics: [MetricData] = [] - var metricDescriptions: [String] = [] - for word in words { - let metricDescription = word + String(Int.random(in: 1 ... 100)) - metricDescriptions.append(metricDescription) - metrics.append(generateGaugeStableMetricData(description: metricDescription)) - } - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter( - endpoint: endpoint, - config: .init(compression: .none) - ) - let result = exporter.export(metrics: metrics) - XCTAssertEqual(result, ExportResult.success) - - XCTAssertNoThrow(try testServer.receiveHeadAndVerify { head in - let otelVersion = Headers.getUserAgentHeader() - XCTAssertTrue(head.headers.contains(name: Constants.HTTP.userAgent)) - XCTAssertEqual(otelVersion, head.headers.first(name: Constants.HTTP.userAgent)) - }) - - XCTAssertNoThrow(try testServer.receiveBodyAndVerify { body in - var contentsBuffer = ByteBuffer(buffer: body) - let contents = contentsBuffer.readString(length: contentsBuffer.readableBytes)! - for metricDescription in metricDescriptions { - XCTAssertTrue(contents.contains(metricDescription)) - } - }) - - XCTAssertNoThrow(try testServer.receiveEnd()) - } - - func testFlushWithoutPendingMetrics() { - _ = generateSumStableMetricData() - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter( - endpoint: endpoint, - config: OtlpConfiguration(headers: [("headerName", "headerValue")]) - ) - XCTAssertEqual(exporter.flush(), .success) - } - - func testCustomAggregationTemporalitySelector() { - let aggregationTemporalitySelector = AggregationTemporalitySelector { type in - switch type { - case .counter: - return .cumulative - case .histogram: - return .delta - case .observableCounter: - return .delta - case .observableGauge, .gauge: - return .delta - case .observableUpDownCounter: - return .cumulative - case .upDownCounter: - return .delta - } - } - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter( - endpoint: endpoint, - aggregationTemporalitySelector: aggregationTemporalitySelector - ) - XCTAssertTrue(exporter.getAggregationTemporality(for: .counter) == .cumulative) - XCTAssertTrue(exporter.getAggregationTemporality(for: .histogram) == .delta) - XCTAssertTrue(exporter.getAggregationTemporality(for: .observableCounter) == .delta) - XCTAssertTrue(exporter.getAggregationTemporality(for: .observableGauge) == .delta) - XCTAssertTrue(exporter.getAggregationTemporality(for: .observableUpDownCounter) == .cumulative) - XCTAssertTrue(exporter.getAggregationTemporality(for: .upDownCounter) == .delta) - } - - func testCustomAggregation() { - let aggregationSelector = CustomDefaultAggregationSelector() - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpMetricExporter( - endpoint: endpoint, - defaultAggregationSelector: aggregationSelector - ) - XCTAssertTrue(exporter.getDefaultAggregation(for: .counter) is SumAggregation) - XCTAssertTrue(exporter.getDefaultAggregation(for: .histogram) is SumAggregation) - XCTAssertTrue(exporter.getDefaultAggregation(for: .observableCounter) is DropAggregation) - XCTAssertTrue(exporter.getDefaultAggregation(for: .upDownCounter) is DropAggregation) - } - - func generateSumStableMetricData(description: String = "description") -> MetricData { - let scope = InstrumentationScopeInfo( - name: "lib", - version: "semver:0.0.0", - attributes: ["instrumentationScope": AttributeValue.string("attributes")] - ) - let sumPointData = DoublePointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [], value: 1) - let metric = MetricData( - resource: Resource(), - instrumentationScopeInfo: scope, - name: "metric", - description: description, - unit: "", - type: .DoubleSum, - isMonotonic: true, - data: MetricData - .Data(aggregationTemporality: .cumulative, points: [sumPointData]) - ) - return metric - } - - func generateGaugeStableMetricData(description: String = "description") -> MetricData { - let scope = InstrumentationScopeInfo(name: "lib", version: "semver:0.0.0") - let sumPointData = DoublePointData(startEpochNanos: 0, endEpochNanos: 1, attributes: [:], exemplars: [], value: 100) - let metric = MetricData( - resource: Resource(), - instrumentationScopeInfo: scope, - name: "MyGauge", - description: description, - unit: "", - type: .LongGauge, - isMonotonic: true, - data: MetricData - .Data(aggregationTemporality: .cumulative, points: [sumPointData]) - ) - return metric - } -} - -public class CustomDefaultAggregationSelector: DefaultAggregationSelector { - public func getDefaultAggregation(for instrument: OpenTelemetrySdk.InstrumentType) -> OpenTelemetrySdk.Aggregation { - switch instrument { - case .counter, .histogram: - return SumAggregation() - default: - return DropAggregation() - } - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift deleted file mode 100644 index e60ea5e6..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import Logging -import NIO -import NIOHTTP1 -import NIOTestUtils -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetryProtocolExporterHttp -@testable import OpenTelemetrySdk -import XCTest - -class OtlpHttpLogRecordExporterTests: XCTestCase { - var testServer: NIOHTTP1TestServer! - var group: MultiThreadedEventLoopGroup! - var spanContext: SpanContext! - - override func setUp() { - group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - testServer = NIOHTTP1TestServer(group: group) - - let spanId = SpanId.random() - let traceId = TraceId.random() - spanContext = SpanContext.create(traceId: traceId, spanId: spanId, traceFlags: TraceFlags(), traceState: TraceState()) - } - - override func tearDown() { - XCTAssertNoThrow(try testServer.stop()) - XCTAssertNoThrow(try group.syncShutdownGracefully()) - } - - func testExport() { - let testHeader = ("testHeader", "testValue") - let testBody = AttributeValue.string("Helloworld" + String(Int.random(in: 1 ... 100))) - let logRecord = ReadableLogRecord(resource: Resource(), - instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), - timestamp: Date(), - observedTimestamp: Date.distantPast, - spanContext: spanContext, - severity: .fatal, - body: testBody, - attributes: ["event.name": AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) - - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let config = OtlpConfiguration(compression: .none, headers: [testHeader]) - let exporter = OtlpHttpLogExporter(endpoint: endpoint, config: config) - let _ = exporter.export(logRecords: [logRecord]) - - // TODO: Use protobuf to verify that we have received the correct Log records - XCTAssertNoThrow(try testServer.receiveHeadAndVerify { head in - let otelVersion = Headers.getUserAgentHeader() - XCTAssertTrue(head.headers.contains(name: Constants.HTTP.userAgent)) - XCTAssertTrue(head.headers.contains { header in - header.name.lowercased() == testHeader.0.lowercased() && header.value == testHeader.1 - }) - XCTAssertEqual(otelVersion, head.headers.first(name: Constants.HTTP.userAgent)) - }) - XCTAssertNoThrow(try testServer.receiveBodyAndVerify { body in - var contentsBuffer = ByteBuffer(buffer: body) - let contents = contentsBuffer.readString(length: contentsBuffer.readableBytes)! - XCTAssertTrue(contents.description.contains(testBody.description)) - }) - - XCTAssertNoThrow(try testServer.receiveEnd()) - } - - // TODO: for this and the other httpexporters, see if there is some way to really test this. As writtne these tests - // won't really do much as there are no pending spans - func testFlush() { - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpLogExporter(endpoint: endpoint) - XCTAssertEqual(ExportResult.success, exporter.flush()) - } - - func testForceFlush() { - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)")! - let exporter = OtlpHttpLogExporter(endpoint: endpoint) - XCTAssertEqual(ExportResult.success, exporter.forceFlush()) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpTraceExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpTraceExporterTests.swift deleted file mode 100644 index 2f556042..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpTraceExporterTests.swift +++ /dev/null @@ -1,129 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif -import Logging -import NIO -import NIOHTTP1 -import NIOTestUtils -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetryProtocolExporterHttp -@testable import OpenTelemetrySdk -import XCTest - -class OtlpHttpTraceExporterTests: XCTestCase { - var testServer: NIOHTTP1TestServer! - var group: MultiThreadedEventLoopGroup! - - override func setUp() { - group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - testServer = NIOHTTP1TestServer(group: group) - } - - override func tearDown() { - XCTAssertNoThrow(try testServer.stop()) - XCTAssertNoThrow(try group.syncShutdownGracefully()) - } - - // This is a somewhat hacky solution to verifying that the spans got across correctly. It simply looks for the metric - // description strings (which is why I made them unique) in the body returned by testServer.receiveBodyAndVerify(). - // It should ideally turn that body into [SpanData] using protobuf and then confirm content - func testExport() { - let testHeader = ("testHeader", "testValue") - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)/v1/traces")! - let config = OtlpConfiguration(compression: .none, headers: [testHeader]) - let exporter = OtlpHttpTraceExporter(endpoint: endpoint, config: config) - - var spans: [SpanData] = [] - let endpointName1 = "/api/foo" + String(Int.random(in: 1 ... 100)) - let endpointName2 = "/api/bar" + String(Int.random(in: 100 ... 500)) - spans.append(generateFakeSpan(endpointName: endpointName1)) - spans.append(generateFakeSpan(endpointName: endpointName2)) - let _ = exporter.export(spans: spans) - - XCTAssertNoThrow(try testServer.receiveHeadAndVerify { head in - let otelVersion = Headers.getUserAgentHeader() - XCTAssertTrue(head.headers.contains(name: Constants.HTTP.userAgent)) - XCTAssertTrue(head.headers.contains { header in - header.name.lowercased() == testHeader.0.lowercased() && header.value == testHeader.1 - }) - XCTAssertEqual(otelVersion, head.headers.first(name: Constants.HTTP.userAgent)) - }) - XCTAssertNoThrow(try testServer.receiveBodyAndVerify { body in - var contentsBuffer = ByteBuffer(buffer: body) - let contents = contentsBuffer.readString(length: contentsBuffer.readableBytes)! - XCTAssertTrue(contents.contains(endpointName1)) - XCTAssertTrue(contents.contains(endpointName2)) - }) - - XCTAssertNoThrow(try testServer.receiveEnd()) - } - - // This is not a thorough test of HTTPClient, but just enough to keep code coverage happy. - // There is a more complete test as part of the DataDog exporter test - func testHttpClient() { - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)/some-route")! - let httpClient = BaseHTTPClient() - var request = URLRequest(url: endpoint) - request.httpMethod = HTTPMethod.GET.rawValue - - httpClient.send(request: request) { result in - switch result { - case let .success(response): - XCTAssertEqual(HTTPResponseStatus.imATeapot.code, UInt(response.statusCode)) - case let .failure(error): - XCTFail("Send failed: \(error)") - } - } - - // Assert the server received the expected request. - XCTAssertNoThrow(try testServer.receiveHeadAndVerify { head in - XCTAssertEqual(head.version, .http1_1) - XCTAssertEqual(head.method, .GET) - XCTAssertEqual(head.uri, "/some-route") - }) - XCTAssertNoThrow(try testServer.receiveEndAndVerify { trailers in - XCTAssertNil(trailers) - }) - - // Make the server send a response to the client. - XCTAssertNoThrow(try testServer.writeOutbound(.head(.init(version: .http1_1, status: .imATeapot)))) - XCTAssertNoThrow(try testServer.writeOutbound(.end(nil))) - } - - func testFlush() { - let endpoint = URL(string: "http://localhost:\(testServer.serverPort)/v1/traces")! - let exporter = OtlpHttpTraceExporter(endpoint: endpoint) - XCTAssertEqual(SpanExporterResultCode.success, exporter.flush()) - } - - private func generateFakeSpan(endpointName: String = "/api/endpoint") -> SpanData { - let duration = 0.9 - let start = Date() - let end = start.addingTimeInterval(duration) - let testattributes: [String: AttributeValue] = ["foo": AttributeValue("bar")!, "fizz": AttributeValue("buzz")!] - - var testData = SpanData(traceId: TraceId.random(), - spanId: SpanId.random(), - name: "GET " + endpointName, - kind: SpanKind.server, - startTime: start, - endTime: end, - totalAttributeCount: 2) - testData.settingAttributes(testattributes) - testData.settingTotalAttributeCount(2) - testData.settingHasEnded(true) - testData.settingTotalRecordedEvents(0) - testData.settingLinks([SpanData.Link]()) - testData.settingTotalRecordedLinks(0) - testData.settingStatus(.ok) - - return testData - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift deleted file mode 100644 index 69100dee..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift +++ /dev/null @@ -1,158 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import GRPC -import Logging -import NIO -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetryProtocolExporterGrpc -@testable import OpenTelemetrySdk -import XCTest - -class OtlpLogRecordExporterTests: XCTestCase { - let traceIdBytes: [UInt8] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4] - let spanIdBytes: [UInt8] = [0, 0, 0, 0, 4, 3, 2, 1] - var traceId: TraceId! - var spanId: SpanId! - let tracestate = TraceState() - var spanContext: SpanContext! - - var fakeCollector: FakeLogCollector! - var server: EventLoopFuture! - var channel: ClientConnection! - - let channelGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) - let serverGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) - - func startServer() -> EventLoopFuture { - // Start the server and print its address once it has started. - let server = Server.insecure(group: serverGroup) - .withServiceProviders([fakeCollector]) - .bind(host: "localhost", port: 4317) - - server.map(\.channel.localAddress).whenSuccess { address in - print("server started on port \(address!.port!)") - } - return server - } - - func startChannel() -> ClientConnection { - let channel = ClientConnection.insecure(group: channelGroup) - .connect(host: "localhost", port: 4317) - return channel - } - - override func setUp() { - fakeCollector = FakeLogCollector() - server = startServer() - channel = startChannel() - traceId = TraceId(fromBytes: traceIdBytes) - spanId = SpanId(fromBytes: spanIdBytes) - spanContext = SpanContext.create(traceId: traceId, spanId: spanId, traceFlags: TraceFlags(), traceState: tracestate) - } - - override func tearDown() { - try! serverGroup.syncShutdownGracefully() - try! channelGroup.syncShutdownGracefully() - } - - func testExport() { - let logRecord = ReadableLogRecord(resource: Resource(), - instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), - timestamp: Date(), - observedTimestamp: Date.distantPast, - spanContext: spanContext, - severity: .fatal, - body: AttributeValue.string("Hello, world"), - attributes: ["event.name": AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) - - let exporter = OtlpLogExporter(channel: channel) - let result = exporter.export(logRecords: [logRecord]) - XCTAssertEqual(result, ExportResult.success) - XCTAssertEqual(fakeCollector.receivedLogs, LogRecordAdapter.toProtoResourceRecordLog(logRecordList: [logRecord])) - exporter.shutdown() - } - - func testImplicitGrpcLoggingConfig() throws { - let exporter = OtlpLogExporter(channel: channel) - let logger = exporter.callOptions.logger - XCTAssertEqual(logger.label, "io.grpc") - } - - func testExplicitGrpcLoggingConfig() throws { - let exporter = OtlpLogExporter(channel: channel, logger: Logger(label: "my.grpc.logger")) - let logger = exporter.callOptions.logger - XCTAssertEqual(logger.label, "my.grpc.logger") - } - - func testConfigHeadersIsNil_whenDefaultInitCalled() throws { - let exporter = OtlpLogExporter(channel: channel) - XCTAssertNil(exporter.config.headers) - } - - func testConfigHeadersAreSet_whenInitCalledWithCustomConfig() throws { - let config = OtlpConfiguration(timeout: TimeInterval(10), headers: [("FOO", "BAR")]) - let exporter = OtlpLogExporter(channel: channel, config: config) - XCTAssertNotNil(exporter.config.headers) - XCTAssertEqual(exporter.config.headers?[0].0, "FOO") - XCTAssertEqual(exporter.config.headers?[0].1, "BAR") - XCTAssertEqual("BAR", exporter.callOptions.customMetadata.first(name: "FOO")) - } - - func testConfigHeadersAreSet_whenInitCalledWithExplicitHeaders() throws { - let exporter = OtlpLogExporter(channel: channel, envVarHeaders: [("FOO", "BAR")]) - XCTAssertNil(exporter.config.headers) - XCTAssertEqual("BAR", exporter.callOptions.customMetadata.first(name: "FOO")) - } - - func testExportAfterShutdown() { - let logRecord = ReadableLogRecord(resource: Resource(), - instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), - timestamp: Date(), - observedTimestamp: Date.distantPast, - spanContext: spanContext, - severity: .fatal, - body: AttributeValue.string("Hello, world"), - attributes: ["event.name": AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) - let exporter = OtlpLogExporter(channel: channel) - exporter.shutdown() - let result = exporter.export(logRecords: [logRecord]) - XCTAssertEqual(result, ExportResult.failure) - } - - func testExportCancelled() { - fakeCollector.returnedStatus = GRPCStatus(code: .cancelled, message: nil) - let exporter = OtlpLogExporter(channel: channel) - let logRecord = ReadableLogRecord(resource: Resource(), - instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), - timestamp: Date(), - observedTimestamp: Date.distantPast, - spanContext: spanContext, - severity: .fatal, - body: AttributeValue.string("Hello, world"), - attributes: ["event.name": AttributeValue.string("name"), - "event.domain": AttributeValue.string("domain")]) - let result = exporter.export(logRecords: [logRecord]) - XCTAssertEqual(result, ExportResult.failure) - exporter.shutdown() - } -} - -class FakeLogCollector: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceProvider { - var interceptors: Opentelemetry_Proto_Collector_Logs_V1_LogsServiceServerInterceptorFactoryProtocol? - - func export(request: Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest, context: GRPC.StatusOnlyCallContext) -> NIOCore.EventLoopFuture { - receivedLogs.append(contentsOf: request.resourceLogs) - if returnedStatus != GRPCStatus.ok { - return context.eventLoop.makeFailedFuture(returnedStatus) - } - return context.eventLoop.makeSucceededFuture(Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceResponse()) - } - - var receivedLogs = [Opentelemetry_Proto_Logs_V1_ResourceLogs]() - var returnedStatus = GRPCStatus.ok -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift deleted file mode 100644 index 012e5657..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceExporterTests.swift +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import GRPC -import Logging -import NIO -import OpenTelemetryApi -import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetryProtocolExporterGrpc -@testable import OpenTelemetrySdk -import XCTest - -extension String: @retroactive Error {} -extension Swift.String: @retroactive LocalizedError { - public var errorDescription: String? { return self } -} - -class OtlpTraceExporterTests: XCTestCase { - let traceId = "00000000000000000000000000abc123" - let spanId = "0000000000def456" - - var fakeCollector: FakeCollector! - var server: EventLoopFuture! - var channel: ClientConnection! - - let channelGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) - let serverGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) - - override func setUp() { - fakeCollector = FakeCollector() - server = startServer() - channel = startChannel() - } - - override func tearDown() { - try! serverGroup.syncShutdownGracefully() - try! channelGroup.syncShutdownGracefully() - } - - func testExport() { - let span = generateFakeSpan() - let exporter = OtlpTraceExporter(channel: channel) - let result = exporter.export(spans: [span]) - XCTAssertEqual(result, SpanExporterResultCode.success) - XCTAssertEqual(fakeCollector.receivedSpans, SpanAdapter.toProtoResourceSpans(spanDataList: [span])) - exporter.shutdown() - } - - func testImplicitGrpcLoggingConfig() throws { - let exporter = OtlpTraceExporter(channel: channel) - let logger = exporter.callOptions.logger - XCTAssertEqual(logger.label, "io.grpc") - } - - func testExplicitGrpcLoggingConfig() throws { - let exporter = OtlpTraceExporter(channel: channel, logger: Logger(label: "my.grpc.logger")) - let logger = exporter.callOptions.logger - XCTAssertEqual(logger.label, "my.grpc.logger") - } - - func verifyUserAgentIsSet(exporter: OtlpTraceExporter) { - let callOptions = exporter.callOptions - let customMetadata = callOptions.customMetadata - let userAgent = Headers.getUserAgentHeader() - if customMetadata.contains(name: Constants.HTTP.userAgent), customMetadata.first(name: Constants.HTTP.userAgent) == userAgent { - return - } - - XCTFail("User-Agent header was not set correctly") - } - - func testConfigHeadersIsNil_whenDefaultInitCalled() throws { - let exporter = OtlpTraceExporter(channel: channel) - XCTAssertNil(exporter.config.headers) - - verifyUserAgentIsSet(exporter: exporter) - } - - func testConfigHeadersAreSet_whenInitCalledWithCustomConfig() throws { - let config = OtlpConfiguration(timeout: TimeInterval(10), headers: [("FOO", "BAR")]) - let exporter = OtlpTraceExporter(channel: channel, config: config) - XCTAssertNotNil(exporter.config.headers) - XCTAssertEqual(exporter.config.headers?[0].0, "FOO") - XCTAssertEqual(exporter.config.headers?[0].1, "BAR") - XCTAssertEqual("BAR", exporter.callOptions.customMetadata.first(name: "FOO")) - - verifyUserAgentIsSet(exporter: exporter) - } - - func testConfigHeadersAreSet_whenInitCalledWithExplicitHeaders() throws { - let exporter = OtlpTraceExporter(channel: channel, envVarHeaders: [("FOO", "BAR")]) - XCTAssertNil(exporter.config.headers) - XCTAssertEqual("BAR", exporter.callOptions.customMetadata.first(name: "FOO")) - - verifyUserAgentIsSet(exporter: exporter) - } - - func testExportMultipleSpans() { - var spans = [SpanData]() - for _ in 0 ..< 10 { - spans.append(generateFakeSpan()) - } - let exporter = OtlpTraceExporter(channel: channel) - let result = exporter.export(spans: spans) - XCTAssertEqual(result, SpanExporterResultCode.success) - XCTAssertEqual(fakeCollector.receivedSpans, SpanAdapter.toProtoResourceSpans(spanDataList: spans)) - exporter.shutdown() - } - - func testExportAfterShutdown() { - let span = generateFakeSpan() - let exporter = OtlpTraceExporter(channel: channel) - exporter.shutdown() - let result = exporter.export(spans: [span]) - XCTAssertEqual(result, SpanExporterResultCode.failure) - } - - func testExportCancelled() { - fakeCollector.returnedStatus = GRPCStatus(code: .cancelled, message: nil) - let exporter = OtlpTraceExporter(channel: channel) - let span = generateFakeSpan() - let result = exporter.export(spans: [span]) - XCTAssertEqual(result, SpanExporterResultCode.failure) - exporter.shutdown() - } - - private func generateFakeSpan() -> SpanData { - let duration = 0.9 - let start = Date() - let end = start.addingTimeInterval(duration) - - var testData = SpanData(traceId: TraceId(fromHexString: traceId), - spanId: SpanId(fromHexString: spanId), - name: "GET /api/endpoint", - kind: SpanKind.server, - startTime: start, - endTime: end) - testData.settingHasEnded(true) - testData.settingTotalRecordedEvents(0) - testData.settingLinks([SpanData.Link]()) - testData.settingTotalRecordedLinks(0) - testData.settingStatus(.ok) - - return testData - } - - func startServer() -> EventLoopFuture { - // Start the server and print its address once it has started. - let server = Server.insecure(group: serverGroup) - .withServiceProviders([fakeCollector]) - .bind(host: "localhost", port: 4317) - - server.map(\.channel.localAddress).whenSuccess { address in - print("server started on port \(address!.port!)") - } - return server - } - - func startChannel() -> ClientConnection { - let channel = ClientConnection.insecure(group: channelGroup) - .connect(host: "localhost", port: 4317) - return channel - } -} - -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? - - func export(request: Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest, context: StatusOnlyCallContext) -> EventLoopFuture { - receivedSpans.append(contentsOf: request.resourceSpans) - if returnedStatus != GRPCStatus.ok { - return context.eventLoop.makeFailedFuture(returnedStatus) - } - return context.eventLoop.makeSucceededFuture(Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceResponse()) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceJsonExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceJsonExporterTests.swift deleted file mode 100644 index a1d668e4..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpTraceJsonExporterTests.swift +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -@testable import OpenTelemetryApi -@testable import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetryProtocolExporterGrpc -@testable import OpenTelemetrySdk -import XCTest - -final class OtlpTraceJsonExporterTests: XCTestCase { - // MARK: - Variable Declaration - - private var tracerSdkFactory = TracerProviderSdk() - private var spanProcessor: SpanProcessor! - private var tracer: Tracer! - private var exporter: OtlpTraceJsonExporter! - - // MARK: - setUp() - - override func setUp() { - exporter = OtlpTraceJsonExporter() - spanProcessor = SimpleSpanProcessor(spanExporter: exporter) - tracerSdkFactory.addSpanProcessor(spanProcessor) - tracer = tracerSdkFactory.get(instrumentationName: "OtlpTraceJsonExporterTests") - } - - // MARK: - Unit Tests - - func testGetExportedSpans() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - let spans = exporter.getExportedSpans() - XCTAssertEqual(spans.count, 3) - - let firstSpan = spans[0].resourceSpans?[0].scopeSpans?[0].spans - XCTAssertEqual(firstSpan?[0].name, "one") - - let secondSpan = spans[1].resourceSpans?[0].scopeSpans?[0].spans - XCTAssertEqual(secondSpan?[0].name, "two") - - let thirdSpan = spans[2].resourceSpans?[0].scopeSpans?[0].spans - XCTAssertEqual(thirdSpan?[0].name, "three") - } - - func testResetClearsFinishedSpans() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - var spans = exporter.getExportedSpans() - XCTAssertEqual(spans.count, 3) - - exporter.reset() - spans = exporter.getExportedSpans() - XCTAssertEqual(spans.count, 0) - } - - func testResetDoesNotRestartAfterShutdown() { - tracer.spanBuilder(spanName: "one").startSpan().end() - spanProcessor.forceFlush() - - exporter.shutdown() - exporter.reset() - - XCTAssertEqual(exporter.export(spans: []), .failure) - } - - func testShutdownClearsFinishedSpans() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - exporter.shutdown() - - let traces = exporter.getExportedSpans() - XCTAssertEqual(traces.count, 0) - } - - func testShutdownStopsFurtherExports() { - tracer.spanBuilder(spanName: "one").startSpan().end() - tracer.spanBuilder(spanName: "two").startSpan().end() - tracer.spanBuilder(spanName: "three").startSpan().end() - spanProcessor.forceFlush() - - exporter.shutdown() - tracer.spanBuilder(spanName: "four").startSpan().end() - spanProcessor.forceFlush() - - let spans = exporter.getExportedSpans() - XCTAssertEqual(spans.count, 0) - } - - func testExportReturnsSuccessWhenStarted() { - XCTAssertEqual(exporter.export(spans: []), .success) - } - - func testExportReturnsFailureWhenStopped() { - exporter.shutdown() - XCTAssertEqual(exporter.export(spans: []), .failure) - } - - func testFlushReturnsSuccessWhenRunning() { - XCTAssertEqual(exporter.flush(), .success) - } - - func testFlushReturnsFailiureWhenStopped() { - exporter.shutdown() - XCTAssertEqual(exporter.flush(), .failure) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/ResourceAdapterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/ResourceAdapterTests.swift deleted file mode 100644 index f560e394..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/ResourceAdapterTests.swift +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -@testable import OpenTelemetryProtocolExporterCommon -import OpenTelemetrySdk -import XCTest - -class ResourceAdapterTests: XCTestCase { - func testToResource() { - let resource = Resource(attributes: ["key_bool": AttributeValue.bool(true), - "key_string": AttributeValue.string("string"), - "key_int": AttributeValue.int(100), - "key_double": AttributeValue.double(100.3)]) - - let protoResource = ResourceAdapter.toProtoResource(resource: resource) - - XCTAssertEqual(protoResource.attributes.count, 4) - - var boolAttribute = Opentelemetry_Proto_Common_V1_KeyValue() - boolAttribute.key = "key_bool" - boolAttribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - boolAttribute.value.boolValue = true - XCTAssertNotNil(protoResource.attributes.first { $0 == boolAttribute }) - - var stringAttribute = Opentelemetry_Proto_Common_V1_KeyValue() - stringAttribute.key = "key_string" - stringAttribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - stringAttribute.value.stringValue = "string" - XCTAssertNotNil(protoResource.attributes.first { $0 == stringAttribute }) - - var intAttribute = Opentelemetry_Proto_Common_V1_KeyValue() - intAttribute.key = "key_int" - intAttribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - intAttribute.value.intValue = 100 - XCTAssertNotNil(protoResource.attributes.first { $0 == intAttribute }) - - var doubleAttribute = Opentelemetry_Proto_Common_V1_KeyValue() - doubleAttribute.key = "key_double" - doubleAttribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - doubleAttribute.value.doubleValue = 100.3 - XCTAssertNotNil(protoResource.attributes.first { $0 == doubleAttribute }) - } -} diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift deleted file mode 100644 index b43554f6..00000000 --- a/Tests/ExportersTests/OpenTelemetryProtocol/SpanAdapterTests.swift +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -@testable import OpenTelemetryProtocolExporterCommon -@testable import OpenTelemetrySdk -import XCTest - -class SpanAdapterTests: XCTestCase { - let traceIdBytes: [UInt8] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4] - var traceId: TraceId! - let spanIdBytes: [UInt8] = [0, 0, 0, 0, 4, 3, 2, 1] - var spanId: SpanId! - let tracestate = TraceState() - var spanContext: SpanContext! - - override func setUp() { - traceId = TraceId(fromBytes: traceIdBytes) - spanId = SpanId(fromBytes: spanIdBytes) - spanContext = SpanContext.create(traceId: traceId, spanId: spanId, traceFlags: TraceFlags(), traceState: tracestate) - } - - func testToProtoResourceSpans() { - let libInfo = InstrumentationScopeInfo(name: "testScope", version: "semver:0.0.1") - - let event = SpanSdk.startSpan(context: spanContext, name: "GET /api/endpoint", instrumentationScopeInfo: 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].scopeSpans.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) - testData.settingAttributes(["key": AttributeValue.bool(true)]) - testData.settingTotalAttributeCount(2) - testData.settingEvents([SpanData.Event(name: "my_event", timestamp: Date(timeIntervalSince1970: 12347))]) - testData.settingTotalRecordedEvents(3) - testData.settingLinks([SpanData.Link(context: spanContext)]) - testData.settingTotalRecordedLinks(2) - testData.settingStatus(.ok) - - let span = SpanAdapter.toProtoSpan(spanData: testData) - - XCTAssertEqual(span.traceID, Data(bytes: traceIdBytes, count: 16)) - XCTAssertEqual(span.spanID, Data(bytes: spanIdBytes, count: 8)) - XCTAssertEqual(span.parentSpanID, Data(repeating: 0, count: 0)) - XCTAssertEqual(span.name, "GET /api/endpoint") - XCTAssertEqual(span.kind, Opentelemetry_Proto_Trace_V1_Span.SpanKind.server) - XCTAssertEqual(span.startTimeUnixNano, 12345 * 1000000000) - XCTAssertEqual(span.endTimeUnixNano, 12349 * 1000000000) - - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.boolValue = true - XCTAssertEqual(span.attributes, [attribute]) - XCTAssertEqual(span.droppedAttributesCount, 1) - - var event = Opentelemetry_Proto_Trace_V1_Span.Event() - event.timeUnixNano = 12347 * 1000000000 - event.name = "my_event" - XCTAssertEqual(span.events, [event]) - XCTAssertEqual(span.droppedEventsCount, 2) - - var link = Opentelemetry_Proto_Trace_V1_Span.Link() - link.traceID = Data(bytes: traceIdBytes, count: 16) - link.spanID = Data(bytes: spanIdBytes, count: 8) - XCTAssertEqual(span.links, [link]) - XCTAssertEqual(span.droppedLinksCount, 1) - - var status = Opentelemetry_Proto_Trace_V1_Status() - status.code = .ok - XCTAssertEqual(span.status, status) - } - - func testToProtoSpanKind() { - XCTAssertEqual(SpanAdapter.toProtoSpanKind(kind: .internal), Opentelemetry_Proto_Trace_V1_Span.SpanKind.internal) - XCTAssertEqual(SpanAdapter.toProtoSpanKind(kind: .client), Opentelemetry_Proto_Trace_V1_Span.SpanKind.client) - XCTAssertEqual(SpanAdapter.toProtoSpanKind(kind: .server), Opentelemetry_Proto_Trace_V1_Span.SpanKind.server) - XCTAssertEqual(SpanAdapter.toProtoSpanKind(kind: .producer), Opentelemetry_Proto_Trace_V1_Span.SpanKind.producer) - XCTAssertEqual(SpanAdapter.toProtoSpanKind(kind: .consumer), Opentelemetry_Proto_Trace_V1_Span.SpanKind.consumer) - } - - func testToProtoStatus() { - var status = Opentelemetry_Proto_Trace_V1_Status() - status.code = .unset - XCTAssertEqual(SpanAdapter.toStatusProto(status: .unset), status) - - status = Opentelemetry_Proto_Trace_V1_Status() - status.code = .ok - XCTAssertEqual(SpanAdapter.toStatusProto(status: .ok), status) - - status = Opentelemetry_Proto_Trace_V1_Status() - status.code = .error - status.message = "ERROR" - XCTAssertEqual(SpanAdapter.toStatusProto(status: .error(description: "ERROR")), status) - } - - func testToProtoSpanEvent() { - var eventNoAttrib = Opentelemetry_Proto_Trace_V1_Span.Event() - eventNoAttrib.timeUnixNano = 12345 * 1000000000 - eventNoAttrib.name = "test_without_attributes" - XCTAssertEqual(SpanAdapter.toProtoSpanEvent(event: SpanData.Event(name: "test_without_attributes", timestamp: Date(timeIntervalSince1970: 12345))), eventNoAttrib) - - var eventWithAttrib = Opentelemetry_Proto_Trace_V1_Span.Event() - eventWithAttrib.timeUnixNano = 12345 * 1000000000 - eventWithAttrib.name = "test_with_attributes" - - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key_string" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.stringValue = "string" - eventWithAttrib.attributes = [attribute] - - XCTAssertEqual(SpanAdapter.toProtoSpanEvent(event: SpanData.Event(name: "test_with_attributes", timestamp: Date(timeIntervalSince1970: 12345), attributes: ["key_string": AttributeValue.string("string")])), eventWithAttrib) - } - - func testToProtoSpanLink() { - var linkNoAttrib = Opentelemetry_Proto_Trace_V1_Span.Link() - linkNoAttrib.traceID = Data(bytes: traceIdBytes, count: 16) - linkNoAttrib.spanID = Data(bytes: spanIdBytes, count: 8) - XCTAssertEqual(SpanAdapter.toProtoSpanLink(link: SpanData.Link(context: spanContext)), linkNoAttrib) - - var linkWithAttrib = Opentelemetry_Proto_Trace_V1_Span.Link() - linkWithAttrib.traceID = Data(bytes: traceIdBytes, count: 16) - linkWithAttrib.spanID = Data(bytes: spanIdBytes, count: 8) - var attribute = Opentelemetry_Proto_Common_V1_KeyValue() - attribute.key = "key_string" - attribute.value = Opentelemetry_Proto_Common_V1_AnyValue() - attribute.value.stringValue = "string" - linkWithAttrib.attributes = [attribute] - XCTAssertEqual(SpanAdapter.toProtoSpanLink(link: SpanData.Link(context: spanContext, attributes: ["key_string": AttributeValue.string("string")])), linkWithAttrib) - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Export/DataExportDelayTests.swift b/Tests/ExportersTests/PersistenceExporter/Export/DataExportDelayTests.swift deleted file mode 100644 index 2346daf9..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Export/DataExportDelayTests.swift +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class DataExportDelayTests: XCTestCase { - private let mockPerformance = ExportPerformanceMock(initialExportDelay: 3, - defaultExportDelay: 5, - minExportDelay: 1, - maxExportDelay: 20, - exportDelayChangeRate: 0.1) - - func testWhenNotModified_itReturnsInitialDelay() { - let delay = DataExportDelay(performance: mockPerformance) - XCTAssertEqual(delay.current, mockPerformance.initialExportDelay) - XCTAssertEqual(delay.current, mockPerformance.initialExportDelay) - } - - func testWhenDecreasing_itGoesDownToMinimumDelay() { - var delay = DataExportDelay(performance: mockPerformance) - var previousValue: TimeInterval = delay.current - - while previousValue > mockPerformance.minExportDelay { - delay.decrease() - - let nextValue = delay.current - XCTAssertEqual(nextValue / previousValue, - 1.0 - mockPerformance.exportDelayChangeRate, - accuracy: 0.1) - XCTAssertLessThanOrEqual(nextValue, max(previousValue, mockPerformance.minExportDelay)) - - previousValue = nextValue - } - } - - func testWhenIncreasing_itClampsToMaximumDelay() { - var delay = DataExportDelay(performance: mockPerformance) - var previousValue: TimeInterval = delay.current - - while previousValue < mockPerformance.maxExportDelay { - delay.increase() - - let nextValue = delay.current - XCTAssertEqual(nextValue / previousValue, - 1.0 + mockPerformance.exportDelayChangeRate, - accuracy: 0.1) - XCTAssertGreaterThanOrEqual(nextValue, min(previousValue, mockPerformance.maxExportDelay)) - previousValue = nextValue - } - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Export/DataExportWorkerTests.swift b/Tests/ExportersTests/PersistenceExporter/Export/DataExportWorkerTests.swift deleted file mode 100644 index 00b2e606..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Export/DataExportWorkerTests.swift +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class DataExportWorkerTests: XCTestCase { - lazy var dateProvider = RelativeDateProvider(advancingBySeconds: 1) - - override func setUp() { - super.setUp() - } - - override func tearDown() { - super.tearDown() - } - - // MARK: - Data Exports - - func testItExportsAllData() { - let v1ExportExpectation = expectation(description: "V1 exported") - let v2ExportExpectation = expectation(description: "V2 exported") - let v3ExportExpectation = expectation(description: "V3 exported") - - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: false)) - - mockDataExporter.onExport = { data in - switch data.utf8String { - case "v1": v1ExportExpectation.fulfill() - case "v2": v2ExportExpectation.fulfill() - case "v3": v3ExportExpectation.fulfill() - default: break - } - } - - // Given - let fileReader = FileReaderMock() - fileReader.addFile(name: "1", data: "v1".utf8Data) - fileReader.addFile(name: "2", data: "v2".utf8Data) - fileReader.addFile(name: "3", data: "v3".utf8Data) - - // When - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { true }, - delay: DataExportDelay(performance: ExportPerformanceMock.veryQuick)) - - // Then - waitForExpectations(timeout: 1, handler: nil) - - worker.cancelSynchronously() - - XCTAssertEqual(fileReader.files.count, 0) - } - - func testGivenDataToExport_whenExportFinishesAndDoesNotNeedToBeRetried_thenDataIsDeleted() { - let startExportExpectation = expectation(description: "Export has started") - - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: false)) - mockDataExporter.onExport = { _ in startExportExpectation.fulfill() } - - // Given - let fileReader = FileReaderMock() - fileReader.addFile(name: "file", data: "value".utf8Data) - - // When - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { true }, - delay: DataExportDelay(performance: ExportPerformanceMock.veryQuick)) - - wait(for: [startExportExpectation], timeout: 0.5) - - worker.cancelSynchronously() - - // Then - XCTAssertEqual(fileReader.files.count, 0, "When export finishes with `needsRetry: false`, data should be deleted") - } - - func testGivenDataToExport_whenExportFinishesAndNeedsToBeRetried_thenDataIsPreserved() { - let startExportExpectation = expectation(description: "Export has started") - - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: true)) - mockDataExporter.onExport = { _ in startExportExpectation.fulfill() } - - // Given - let fileReader = FileReaderMock() - fileReader.addFile(name: "file", data: "value".utf8Data) - - // When - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { true }, - delay: DataExportDelay(performance: ExportPerformanceMock.veryQuick)) - - wait(for: [startExportExpectation], timeout: 0.5) - worker.cancelSynchronously() - - // Then - XCTAssertEqual(fileReader.files.count, 1, "When export finishes with `needsRetry: true`, data should be preserved") - } - - // MARK: - Export Interval Changes - - func testWhenThereIsNoBatch_thenIntervalIncreases() { - let delayChangeExpectation = expectation(description: "Export delay is increased") - let mockDelay = MockDelay { command in - if case .increase = command { - delayChangeExpectation.fulfill() - } else { - XCTFail("Wrong command is sent!") - } - } - - // When - let fileReader = FileReaderMock() - let mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: false)) - - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { false }, - delay: mockDelay) - - // Then - waitForExpectations(timeout: 1, handler: nil) - worker.cancelSynchronously() - } - - func testWhenBatchFails_thenIntervalIncreases() { - let delayChangeExpectation = expectation(description: "Export delay is increased") - let mockDelay = MockDelay { command in - if case .increase = command { - delayChangeExpectation.fulfill() - } else { - XCTFail("Wrong command is sent!") - } - } - - let exportExpectation = expectation(description: "value exported") - - // The onExport closure is called more than once as part of test execution - // It does not seem to be called the same number of times on each test run. - // Setting `assertForOverFulfill` to `false` works around the XCTestExpectation - // error that fails the test. - // "API violation - multiple calls made to -[XCTestExpectation fulfill] for value exported." - exportExpectation.assertForOverFulfill = false - - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: true)) - mockDataExporter.onExport = { _ in exportExpectation.fulfill() } - - // When - let fileReader = FileReaderMock() - fileReader.addFile(name: "file", data: "value".utf8Data) - - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { true }, - delay: mockDelay) - - // Then - waitForExpectations(timeout: 1, handler: nil) - worker.cancelSynchronously() - } - - func testWhenBatchSucceeds_thenIntervalDecreases() { - let delayChangeExpectation = expectation(description: "Export delay is decreased") - let mockDelay = MockDelay { command in - if case .decrease = command { - delayChangeExpectation.fulfill() - } else { - XCTFail("Wrong command is sent!") - } - } - - let exportExpectation = expectation(description: "value exported") - - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: false)) - - mockDataExporter.onExport = { _ in exportExpectation.fulfill() } - - // When - let fileReader = FileReaderMock() - fileReader.addFile(name: "file", data: "value".utf8Data) - - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { true }, - delay: mockDelay) - - // Then - waitForExpectations(timeout: 1, handler: nil) - worker.cancelSynchronously() - } - - // MARK: - Tearing Down - - func testWhenCancelled_itPerformsNoMoreExports() { - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: false)) - - mockDataExporter.onExport = { _ in XCTFail("Expected no exports after cancel") } - - // When - let fileReader = FileReaderMock() - - // Given - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { false }, - delay: MockDelay()) - - worker.cancelSynchronously() - fileReader.addFile(name: "file", data: "value".utf8Data) - - // Then - worker.queue.sync(flags: .barrier) {} - } - - func testItFlushesAllData() { - let v1ExportExpectation = expectation(description: "V1 exported") - let v2ExportExpectation = expectation(description: "V2 exported") - let v3ExportExpectation = expectation(description: "V3 exported") - - var mockDataExporter = DataExporterMock(exportStatus: .mockWith(needsRetry: false)) - - mockDataExporter.onExport = { data in - switch data.utf8String { - case "v1": v1ExportExpectation.fulfill() - case "v2": v2ExportExpectation.fulfill() - case "v3": v3ExportExpectation.fulfill() - default: break - } - } - - // Given - let fileReader = FileReaderMock() - fileReader.addFile(name: "1", data: "v1".utf8Data) - fileReader.addFile(name: "2", data: "v2".utf8Data) - fileReader.addFile(name: "3", data: "v3".utf8Data) - - // When - let worker = DataExportWorker(fileReader: fileReader, - dataExporter: mockDataExporter, - exportCondition: { true }, - delay: DataExportDelay(performance: ExportPerformanceMock.veryQuick)) - - // When - XCTAssertTrue(worker.flush()) - - // Then - waitForExpectations(timeout: 1, handler: nil) - XCTAssertEqual(fileReader.files.count, 0) - } -} - -struct MockDelay: Delay { - enum Command { - case increase, decrease - } - - var callback: ((Command) -> Void)? - let current: TimeInterval = 0.1 - - mutating func decrease() { - callback?(.decrease) - callback = nil - } - - mutating func increase() { - callback?(.increase) - callback = nil - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Helpers/CoreMocks.swift b/Tests/ExportersTests/PersistenceExporter/Helpers/CoreMocks.swift deleted file mode 100644 index d5845754..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Helpers/CoreMocks.swift +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import Foundation - -// MARK: - PerformancePreset Mocks - -struct StoragePerformanceMock: StoragePerformancePreset { - let maxFileSize: UInt64 - let maxDirectorySize: UInt64 - let maxFileAgeForWrite: TimeInterval - let minFileAgeForRead: TimeInterval - let maxFileAgeForRead: TimeInterval - let maxObjectsInFile: Int - let maxObjectSize: UInt64 - - static let readAllFiles = StoragePerformanceMock(maxFileSize: .max, - maxDirectorySize: .max, - maxFileAgeForWrite: 0, - minFileAgeForRead: -1, // make all files eligible for read - maxFileAgeForRead: .distantFuture, // make all files eligible for read - maxObjectsInFile: .max, - maxObjectSize: .max) - - static let writeEachObjectToNewFileAndReadAllFiles = StoragePerformanceMock(maxFileSize: .max, - maxDirectorySize: .max, - maxFileAgeForWrite: 0, // always return new file for writing - minFileAgeForRead: readAllFiles.minFileAgeForRead, - maxFileAgeForRead: readAllFiles.maxFileAgeForRead, - maxObjectsInFile: 1, // write each data to new file - maxObjectSize: .max) - - static let writeAllObjectsToTheSameFile = StoragePerformanceMock(maxFileSize: .max, - maxDirectorySize: .max, - maxFileAgeForWrite: .distantFuture, - minFileAgeForRead: -1, // make all files eligible for read - maxFileAgeForRead: .distantFuture, // make all files eligible for read - maxObjectsInFile: .max, - maxObjectSize: .max) -} - -struct ExportPerformanceMock: ExportPerformancePreset { - let initialExportDelay: TimeInterval - let defaultExportDelay: TimeInterval - let minExportDelay: TimeInterval - let maxExportDelay: TimeInterval - let exportDelayChangeRate: Double - - static let veryQuick = ExportPerformanceMock(initialExportDelay: 0.05, - defaultExportDelay: 0.05, - minExportDelay: 0.05, - maxExportDelay: 0.05, - exportDelayChangeRate: 0) -} - -extension PersistencePerformancePreset { - static func mockWith(storagePerformance: StoragePerformancePreset, - synchronousWrite: Bool, - exportPerformance: ExportPerformancePreset) -> PersistencePerformancePreset { - return PersistencePerformancePreset(maxFileSize: storagePerformance.maxFileSize, - maxDirectorySize: storagePerformance.maxDirectorySize, - maxFileAgeForWrite: storagePerformance.maxFileAgeForWrite, - minFileAgeForRead: storagePerformance.minFileAgeForRead, - maxFileAgeForRead: storagePerformance.maxFileAgeForRead, - maxObjectsInFile: storagePerformance.maxObjectsInFile, - maxObjectSize: storagePerformance.maxObjectSize, - synchronousWrite: synchronousWrite, - initialExportDelay: exportPerformance.initialExportDelay, - defaultExportDelay: exportPerformance.defaultExportDelay, - minExportDelay: exportPerformance.minExportDelay, - maxExportDelay: exportPerformance.maxExportDelay, - exportDelayChangeRate: exportPerformance.exportDelayChangeRate) - } -} - -/// `DateProvider` mock returning consecutive dates in custom intervals, starting from given reference date. -class RelativeDateProvider: DateProvider { - private(set) var date: Date - let timeInterval: TimeInterval - private let queue = DispatchQueue(label: "queue-RelativeDateProvider-\(UUID().uuidString)") - - private init(date: Date, timeInterval: TimeInterval) { - self.date = date - self.timeInterval = timeInterval - } - - convenience init(using date: Date = Date()) { - self.init(date: date, timeInterval: 0) - } - - convenience init(startingFrom referenceDate: Date = Date(), advancingBySeconds timeInterval: TimeInterval = 0) { - self.init(date: referenceDate, timeInterval: timeInterval) - } - - /// Returns current date and advances next date by `timeInterval`. - func currentDate() -> Date { - defer { - queue.async { - self.date.addTimeInterval(self.timeInterval) - } - } - return queue.sync { - return date - } - } - - /// Pushes time forward by given number of seconds. - func advance(bySeconds seconds: TimeInterval) { - queue.async { - self.date = self.date.addingTimeInterval(seconds) - } - } -} - -struct DataExporterMock: DataExporter { - let exportStatus: DataExportStatus - - var onExport: ((Data) -> Void)? = nil - - func export(data: Data) -> DataExportStatus { - onExport?(data) - return exportStatus - } -} - -extension DataExportStatus { - static func mockWith(needsRetry: Bool) -> DataExportStatus { - return DataExportStatus(needsRetry: needsRetry) - } -} - -class FileWriterMock: FileWriter { - var onWrite: ((Bool, Data) -> Void)? = nil - - func write(data: Data) { - onWrite?(false, data) - } - - func writeSync(data: Data) { - onWrite?(true, data) - } - - var onFlush: (() -> Void)? = nil - - func flush() { - onFlush?() - } -} - -class FileReaderMock: FileReader { - private class ReadableFileMock: ReadableFile { - private var deleted = false - private let data: Data - - private(set) var name: String - - init(name: String, data: Data) { - self.name = name - self.data = data - } - - func read() throws -> Data { - guard deleted == false else { - throw ErrorMock("read failed because delete was called") - } - return data - } - - func delete() throws { - deleted = true - } - } - - var files: [ReadableFile] = [] - - func addFile(name: String, data: Data) { - files.append(ReadableFileMock(name: name, data: data)) - } - - func readNextBatch() -> Batch? { - if let file = files.first, - let fileData = try? file.read() { - return Batch(data: fileData, file: file) - } - - return nil - } - - func onRemainingBatches(process: (Batch) -> Void) -> Bool { - do { - try files.forEach { - let fileData = try $0.read() - process(Batch(data: fileData, file: $0)) - } - - return true - } catch { - return false - } - } - - func markBatchAsRead(_ batch: Batch) { - try? batch.file.delete() - files.removeAll { file -> Bool in - return file.name == batch.file.name - } - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Helpers/FoundationMocks.swift b/Tests/ExportersTests/PersistenceExporter/Helpers/FoundationMocks.swift deleted file mode 100644 index c16610ef..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Helpers/FoundationMocks.swift +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation - -/* - A collection of mocks for different `Foundation` types. The convention we use is to extend - types with static factory function prefixed with "mock". For example: - - ``` - extension URL { - static func mockAny() -> URL { - // ... - } - } - - extension URLSession { - static func mockDeliverySuccess(data: Data, response: HTTPURLResponse) -> URLSessionMock { - // ... - } - } - ``` - - Other conventions to follow: - * Use the name `mockAny()` to name functions that return any value of given type. - * Use descriptive function and parameter names for functions that configure the object for particular scenario. - * Always use the minimal set of parameters which is required by given mock scenario. - - */ - -// MARK: - Basic types - -protocol AnyMockable { - static func mockAny() -> Self -} - -extension Data: AnyMockable { - static func mockAny() -> Data { - return Data() - } - - static func mockRepeating(byte: UInt8, times count: Int) -> Data { - return Data(repeating: byte, count: count) - } - - static func mock(ofSize size: UInt64) -> Data { - return mockRepeating(byte: 0x41, times: Int(size)) - } -} - -extension [Data] { - /// Returns chunks of mocked data. Accumulative size of all chunks equals `totalSize`. - static func mockChunksOf(totalSize: UInt64, maxChunkSize: UInt64) -> [Data] { - var chunks: [Data] = [] - var bytesWritten: UInt64 = 0 - - while bytesWritten < totalSize { - let bytesLeft = totalSize - bytesWritten - var nextChunkSize: UInt64 = bytesLeft > Int.max ? UInt64(Int.max) : bytesLeft // prevents `Int` overflow - nextChunkSize = nextChunkSize > maxChunkSize ? maxChunkSize : nextChunkSize // caps the next chunk to its max size - chunks.append(.mockRepeating(byte: 0x1, times: Int(nextChunkSize))) - bytesWritten += UInt64(nextChunkSize) - } - - return chunks - } -} - -extension Date: AnyMockable { - static func mockAny() -> Date { - return Date(timeIntervalSinceReferenceDate: 1) - } -} - -extension TimeInterval: AnyMockable { - static func mockAny() -> TimeInterval { - return 0 - } - - static let distantFuture = TimeInterval(integerLiteral: .max) -} - -struct ErrorMock: Error, CustomStringConvertible { - let description: String - - init(_ description: String = "") { - self.description = description - } -} - -struct FailingCodableMock: Codable { - init() {} - - init(from decoder: Decoder) throws { - throw ErrorMock("Failing codable failed to decode") - } - - func encode(to encoder: Encoder) throws { - throw ErrorMock("Failing codable failed to encode") - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Helpers/PersistenceExtensions.swift b/Tests/ExportersTests/PersistenceExporter/Helpers/PersistenceExtensions.swift deleted file mode 100644 index cdb24bba..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Helpers/PersistenceExtensions.swift +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import Foundation - -/* - Set of Persistence domain extensions over standard types for writing more readable tests. - Domain agnostic extensions should be put in `SwiftExtensions.swift`. - */ - -extension Date { - /// Returns name of the logs file createde at this date. - var toFileName: String { - return fileNameFrom(fileCreationDate: self) - } -} - -extension File { - func makeReadonly() throws { - try FileManager.default.setAttributes([.immutable: true], ofItemAtPath: url.path) - } - - func makeReadWrite() throws { - try FileManager.default.setAttributes([.immutable: false], ofItemAtPath: url.path) - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Helpers/SwiftExtensions.swift b/Tests/ExportersTests/PersistenceExporter/Helpers/SwiftExtensions.swift deleted file mode 100644 index 107a02a4..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Helpers/SwiftExtensions.swift +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import XCTest - -/* - Set of general extensions over standard types for writing more readable tests. - Extensiosn using Persistence domain objects should be put in `PersistenceExtensions.swift`. - */ - -extension Optional { - struct UnwrappingException: Error {} - - func unwrapOrThrow(file: StaticString = #file, line: UInt = #line) throws -> Wrapped { - switch self { - case let .some(unwrappedValue): - return unwrappedValue - case .none: - XCTFail("Expected value, got `nil`.", file: file, line: line) - throw UnwrappingException() - } - } -} - -extension Date { - func secondsAgo(_ seconds: TimeInterval) -> Date { - return addingTimeInterval(-seconds) - } -} - -extension TimeZone { - static var UTC: TimeZone { TimeZone(abbreviation: "UTC")! } - static var EET: TimeZone { TimeZone(abbreviation: "EET")! } - static func mockAny() -> TimeZone { .EET } -} - -extension String { - var utf8Data: Data { data(using: .utf8)! } -} - -extension Data { - var utf8String: String { String(decoding: self, as: UTF8.self) } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Helpers/TestsDirectory.swift b/Tests/ExportersTests/PersistenceExporter/Helpers/TestsDirectory.swift deleted file mode 100644 index a7bfea91..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Helpers/TestsDirectory.swift +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import Foundation -import XCTest - -/// Creates `Directory` pointing to unique subfolder in `/var/folders/`. -/// Does not create the subfolder - it must be later created with `.create()`. -@propertyWrapper class UniqueTemporaryDirectory { - private let directory: Directory - private var printedDir = false - - var wrappedValue: Directory { - if printedDir == false { - printedDir = true - // Printing this message during initialization breaks `swift test --filter...` on platforms without Objective-C support, so we do it on first access instead - print("💡 Obtained temporary directory URL: \(directory.url)") - } - - return directory - } - - init() { - let subdirectoryName = "com.datadoghq.ios-sdk-tests-\(UUID().uuidString)" - let osTemporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(subdirectoryName, isDirectory: true) - directory = Directory(url: osTemporaryDirectoryURL) - } -} - -/// `Directory` pointing to subfolder in `/var/folders/`. -/// The subfolder does not exist and can be created and deleted by calling `.create()` and `.delete()`. -// let temporaryDirectory = obtainUniqueTemporaryDirectory() - -/// Extends `Directory` with set of utilities for convenient work with files in tests. -/// Provides handy methods to create / delete files and directires. -extension Directory { - /// Creates empty directory with given attributes . - func create(attributes: [FileAttributeKey: Any]? = nil, file: StaticString = #file, line: UInt = #line) { - do { - try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: attributes) - let initialFilesCount = try files().count - XCTAssert(initialFilesCount == 0, "🔥 `TestsDirectory` is not empty: \(url)", file: file, line: line) - } catch { - XCTFail("🔥 Failed to create `TestsDirectory`: \(error)", file: file, line: line) - } - } - - /// Deletes entire directory with its content. - func delete(file: StaticString = #file, line: UInt = #line) { - if FileManager.default.fileExists(atPath: url.path) { - do { - try FileManager.default.removeItem(at: url) - } catch { - XCTFail("🔥 Failed to delete `TestsDirectory`: \(error)", file: file, line: line) - } - } - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/PersistenceExporterDecoratorTests.swift b/Tests/ExportersTests/PersistenceExporter/PersistenceExporterDecoratorTests.swift deleted file mode 100644 index c5649b93..00000000 --- a/Tests/ExportersTests/PersistenceExporter/PersistenceExporterDecoratorTests.swift +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class PersistenceExporterDecoratorTests: XCTestCase { - class DecoratedExporterMock: DecoratedExporter { - typealias SignalType = T - let exporter: ([T]) -> DataExportStatus - init(exporter: @escaping ([T]) -> DataExportStatus) { - self.exporter = exporter - } - - func export(values: [T]) -> DataExportStatus { - return exporter(values) - } - } - - class DataExportWorkerMock: DataExportWorkerProtocol { - var dataExporter: DataExporter? = nil - var onFlush: (() -> Bool)? = nil - - func flush() -> Bool { - return onFlush?() ?? true - } - } - - private typealias PersistenceExporter = PersistenceExporterDecorator> - - private func createPersistenceExporter(fileWriter: FileWriterMock = FileWriterMock(), - worker: inout DataExportWorkerMock, - decoratedExporter: DecoratedExporterMock = DecoratedExporterMock(exporter: { _ in - return DataExportStatus(needsRetry: false) - }), - storagePerformance: StoragePerformancePreset = StoragePerformanceMock.writeEachObjectToNewFileAndReadAllFiles, - synchronousWrite: Bool = true, - exportPerformance: ExportPerformancePreset = ExportPerformanceMock.veryQuick) -> PersistenceExporter { - return PersistenceExporterDecorator>(decoratedExporter: decoratedExporter, - fileWriter: fileWriter, - workerFactory: { - worker.dataExporter = $0 - return worker - }, - performancePreset: PersistencePerformancePreset.mockWith(storagePerformance: storagePerformance, - synchronousWrite: synchronousWrite, - exportPerformance: exportPerformance)) - } - - func testWhenSetupWithSynchronousWrite_thenWritesAreSynchronous() throws { - var worker = DataExportWorkerMock() - let fileWriter = FileWriterMock() - - let exporter: PersistenceExporter = createPersistenceExporter(fileWriter: fileWriter, - worker: &worker) - - fileWriter.onWrite = { writeSync, _ in - XCTAssertTrue(writeSync) - } - - try exporter.export(values: ["value"]) - } - - func testWhenSetupWithAsynchronousWrite_thenWritesAreAsynchronous() throws { - var worker = DataExportWorkerMock() - let fileWriter = FileWriterMock() - - let exporter: PersistenceExporter = createPersistenceExporter(fileWriter: fileWriter, - worker: &worker, - synchronousWrite: false) - - fileWriter.onWrite = { writeSync, _ in - XCTAssertFalse(writeSync) - } - - try exporter.export(values: ["value"]) - } - - func testWhenValueCannotBeEncoded_itThrowsAnError() { - // When - var worker = DataExportWorkerMock() - - let exporter: PersistenceExporter = createPersistenceExporter( - worker: &worker) - - XCTAssertThrowsError(try exporter.export(values: [FailingCodableMock()])) - } - - func testWhenValueCannotBeDecoded_itReportsNoRetryIsNeeded() { - var worker = DataExportWorkerMock() - - _ = createPersistenceExporter(worker: &worker) as PersistenceExporter - - let result = worker.dataExporter?.export(data: Data()) - - XCTAssertNotNil(result) - XCTAssertFalse(result!.needsRetry) - } - - func testWhenItIsFlushed_thenItFlushesTheWriterAndWorker() { - let writerIsFlushedExpectation = expectation(description: "FileWriter was flushed") - let workerIsFlushedExpectation = expectation(description: "DataExportWorker was flushed") - - var worker = DataExportWorkerMock() - let fileWriter = FileWriterMock() - - let exporter: PersistenceExporter = createPersistenceExporter(fileWriter: fileWriter, - worker: &worker) - - fileWriter.onFlush = { - writerIsFlushedExpectation.fulfill() - } - - worker.onFlush = { - workerIsFlushedExpectation.fulfill() - return true - } - - exporter.flush() - - waitForExpectations(timeout: 1, handler: nil) - } - - func testWhenObjectsDataIsExportedSeparately_thenObjectsAreExported() throws { - let v1ExportExpectation = expectation(description: "V1 exported") - let v2ExportExpectation = expectation(description: "V2 exported") - let v3ExportExpectation = expectation(description: "V3 exported") - - let decoratedExporter = DecoratedExporterMock(exporter: { values in - values.forEach { value in - switch value { - case "v1": v1ExportExpectation.fulfill() - case "v2": v2ExportExpectation.fulfill() - case "v3": v3ExportExpectation.fulfill() - default: break - } - } - - return DataExportStatus(needsRetry: false) - }) - - var worker = DataExportWorkerMock() - let fileWriter = FileWriterMock() - - let exporter: PersistenceExporter = createPersistenceExporter(fileWriter: fileWriter, - worker: &worker, - decoratedExporter: decoratedExporter) - - fileWriter.onWrite = { _, data in - if let dataExporter = worker.dataExporter { - XCTAssertFalse(dataExporter.export(data: data).needsRetry) - } - } - - try exporter.export(values: ["v1"]) - try exporter.export(values: ["v2"]) - try exporter.export(values: ["v3"]) - - waitForExpectations(timeout: 1, handler: nil) - } - - func testWhenObjectsDataIsExportedConcatenated_thenObjectsAreExported() throws { - let v1ExportExpectation = expectation(description: "V1 exported") - let v2ExportExpectation = expectation(description: "V2 exported") - let v3ExportExpectation = expectation(description: "V3 exported") - - let decoratedExporter = DecoratedExporterMock(exporter: { values in - values.forEach { value in - switch value { - case "v1": v1ExportExpectation.fulfill() - case "v2": v2ExportExpectation.fulfill() - case "v3": v3ExportExpectation.fulfill() - default: break - } - } - - return DataExportStatus(needsRetry: false) - }) - - var worker = DataExportWorkerMock() - let fileWriter = FileWriterMock() - - let exporter: PersistenceExporter = createPersistenceExporter(fileWriter: fileWriter, - worker: &worker, - decoratedExporter: decoratedExporter) - - var writtenData = Data() - fileWriter.onWrite = { _, data in - writtenData.append(data) - } - - try exporter.export(values: ["v1"]) - try exporter.export(values: ["v2"]) - try exporter.export(values: ["v3"]) - - if let dataExporter = worker.dataExporter { - XCTAssertFalse(dataExporter.export(data: writtenData).needsRetry) - } - - waitForExpectations(timeout: 1, handler: nil) - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/PersistenceMetricExporterDecoratorTests.swift b/Tests/ExportersTests/PersistenceExporter/PersistenceMetricExporterDecoratorTests.swift deleted file mode 100644 index 90e138c5..00000000 --- a/Tests/ExportersTests/PersistenceExporter/PersistenceMetricExporterDecoratorTests.swift +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import OpenTelemetryApi -import OpenTelemetrySdk -import XCTest - -class PersistenceMetricExporterDecoratorTests: XCTestCase { - @UniqueTemporaryDirectory private var temporaryDirectory: Directory - - class MetricExporterMock: MetricExporter { - func flush() -> OpenTelemetrySdk.ExportResult { - .success - } - - func shutdown() -> OpenTelemetrySdk.ExportResult { - .success - } - - func getAggregationTemporality(for instrument: OpenTelemetrySdk.InstrumentType) -> OpenTelemetrySdk.AggregationTemporality { - .cumulative - } - - let onExport: ([MetricData]) -> ExportResult - init(onExport: @escaping ([MetricData]) -> ExportResult) { - self.onExport = onExport - } - - func export(metrics: [MetricData]) -> ExportResult { - return onExport(metrics) - } - } - - override func setUp() { - super.setUp() - temporaryDirectory.create() - } - - override func tearDown() { - temporaryDirectory.delete() - super.tearDown() - } - - func testWhenExportMetricIsCalled_thenMetricsAreExported() throws { - let metricsExportExpectation = expectation(description: "metrics exported") - let mockMetricExporter = MetricExporterMock(onExport: { metrics in - metrics.forEach { metric in - if metric.name == "MyCounter", metric.data.points.count == 1 { - let pointData: LongPointData = metric.data.points[0] as! LongPointData - if pointData.value == 100, - pointData.attributes == ["labelKey": AttributeValue.string("labelValue")] { - metricsExportExpectation.fulfill() - } - } - } - return .success - }) - - let persistenceMetricExporter = - try PersistenceMetricExporterDecorator(metricExporter: mockMetricExporter, - storageURL: temporaryDirectory.url, - exportCondition: { return true }, - performancePreset: PersistencePerformancePreset.mockWith(storagePerformance: StoragePerformanceMock.writeEachObjectToNewFileAndReadAllFiles, - synchronousWrite: true, - exportPerformance: ExportPerformanceMock.veryQuick)) - - let provider = MeterProviderSdk.builder().registerMetricReader( - reader: PeriodicMetricReaderBuilder( - exporter: persistenceMetricExporter - ).setInterval(timeInterval: 1) - .build() - ).registerView( - selector: InstrumentSelector.builder().setInstrument( - name: ".*" - ).build(), - view: View.builder().build() - ).build() - - let meter = provider.get(name: "MyMeter") - - let myCounter = meter.counterBuilder(name: "MyCounter").build() - - myCounter.add(value: 100, attributes: ["labelKey": AttributeValue.string("labelValue")]) - - waitForExpectations(timeout: 10, handler: nil) - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/PersistenceSpanExporterDecoratorTests.swift b/Tests/ExportersTests/PersistenceExporter/PersistenceSpanExporterDecoratorTests.swift deleted file mode 100644 index cce3acb4..00000000 --- a/Tests/ExportersTests/PersistenceExporter/PersistenceSpanExporterDecoratorTests.swift +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import OpenTelemetryApi -import OpenTelemetrySdk -@testable import PersistenceExporter -import XCTest - -class PersistenceSpanExporterDecoratorTests: XCTestCase { - @UniqueTemporaryDirectory private var temporaryDirectory: Directory - - class SpanExporterMock: SpanExporter { - let onExport: ([SpanData], TimeInterval?) -> SpanExporterResultCode - let onFlush: (TimeInterval?) -> SpanExporterResultCode - let onShutdown: (TimeInterval?) -> Void - - init(onExport: @escaping ([SpanData], TimeInterval?) -> SpanExporterResultCode, - onFlush: @escaping (TimeInterval?) -> SpanExporterResultCode = { _ in .success }, - onShutdown: @escaping (TimeInterval?) -> Void = { _ in }) { - self.onExport = onExport - self.onFlush = onFlush - self.onShutdown = onShutdown - } - - @discardableResult func export(spans: [SpanData], explicitTimeout: TimeInterval?) -> SpanExporterResultCode { - return onExport(spans, explicitTimeout) - } - - func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode { - return onFlush(explicitTimeout) - } - - func shutdown(explicitTimeout: TimeInterval?) { - onShutdown(explicitTimeout) - } - } - - override func setUp() { - super.setUp() - temporaryDirectory.create() - } - - override func tearDown() { - temporaryDirectory.delete() - super.tearDown() - } - - func testWhenExportMetricIsCalled_thenSpansAreExported() throws { - let spansExportExpectation = expectation(description: "spans exported") - let exporterShutdownExpectation = expectation(description: "exporter shut down") - - let mockSpanExporter = SpanExporterMock(onExport: { spans, _ in - spans.forEach { span in - if span.name == "SimpleSpan", - span.events.count == 1, - span.events.first!.name == "My event" { - spansExportExpectation.fulfill() - } - } - - return .success - }, onShutdown: { _ in - exporterShutdownExpectation.fulfill() - }) - - let persistenceSpanExporter = - try PersistenceSpanExporterDecorator(spanExporter: mockSpanExporter, - storageURL: temporaryDirectory.url, - exportCondition: { true }, - performancePreset: PersistencePerformancePreset.mockWith(storagePerformance: StoragePerformanceMock.writeEachObjectToNewFileAndReadAllFiles, - synchronousWrite: true, - exportPerformance: ExportPerformanceMock.veryQuick)) - - let instrumentationScopeName = "SimpleExporter" - let instrumentationScopeVersion = "semver:0.1.0" - let tracerProviderSDK = TracerProviderSdk() - OpenTelemetry.registerTracerProvider(tracerProvider: tracerProviderSDK) - let tracer = tracerProviderSDK.get(instrumentationName: instrumentationScopeName, instrumentationVersion: instrumentationScopeVersion) as! TracerSdk - - let spanProcessor = SimpleSpanProcessor(spanExporter: persistenceSpanExporter) - tracerProviderSDK.addSpanProcessor(spanProcessor) - - simpleSpan(tracer: tracer) - spanProcessor.shutdown() - - waitForExpectations(timeout: 10, handler: nil) - } - - private func simpleSpan(tracer: TracerSdk) { - let span = tracer.spanBuilder(spanName: "SimpleSpan").setSpanKind(spanKind: .client).startSpan() - span.addEvent(name: "My event", timestamp: Date()) - span.end() - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Storage/DirectoryTests.swift b/Tests/ExportersTests/PersistenceExporter/Storage/DirectoryTests.swift deleted file mode 100644 index ada4e74f..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Storage/DirectoryTests.swift +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class DirectoryTests: XCTestCase { - private let uniqueSubdirectoryName = UUID().uuidString - private let fileManager = FileManager.default - - // MARK: - Directory creation - - func testGivenSubdirectoryName_itCreatesIt() throws { - let directory = try Directory(withSubdirectoryPath: uniqueSubdirectoryName) - defer { directory.delete() } - - XCTAssertTrue(fileManager.fileExists(atPath: directory.url.path)) - } - - func testGivenSubdirectoryPath_itCreatesIt() throws { - let path = uniqueSubdirectoryName + "/subdirectory/another-subdirectory" - let directory = try Directory(withSubdirectoryPath: path) - defer { directory.delete() } - - XCTAssertTrue(fileManager.fileExists(atPath: directory.url.path)) - } - - func testWhenDirectoryExists_itDoesNothing() throws { - let path = uniqueSubdirectoryName + "/subdirectory/another-subdirectory" - let originalDirectory = try Directory(withSubdirectoryPath: path) - defer { originalDirectory.delete() } - _ = try originalDirectory.createFile(named: "abcd") - - // Try again when directory exists - let retrievedDirectory = try Directory(withSubdirectoryPath: path) - - XCTAssertEqual(retrievedDirectory.url, originalDirectory.url) - XCTAssertTrue(fileManager.fileExists(atPath: retrievedDirectory.url.appendingPathComponent("abcd").path)) - } - - // MARK: - Files manipulation - - func testItCreatesFile() throws { - let path = uniqueSubdirectoryName + "/subdirectory/another-subdirectory" - let directory = try Directory(withSubdirectoryPath: path) - defer { directory.delete() } - - let file = try directory.createFile(named: "abcd") - - XCTAssertEqual(file.url, directory.url.appendingPathComponent("abcd")) - XCTAssertTrue(fileManager.fileExists(atPath: file.url.path)) - } - - func testItRetrievesFile() throws { - let directory = try Directory(withSubdirectoryPath: uniqueSubdirectoryName) - defer { directory.delete() } - _ = try directory.createFile(named: "abcd") - - let file = directory.file(named: "abcd") - XCTAssertEqual(file?.url, directory.url.appendingPathComponent("abcd")) - XCTAssertTrue(fileManager.fileExists(atPath: file!.url.path)) - } - - func testItRetrievesAllFiles() throws { - let directory = try Directory(withSubdirectoryPath: uniqueSubdirectoryName) - defer { directory.delete() } - _ = try directory.createFile(named: "f1") - _ = try directory.createFile(named: "f2") - _ = try directory.createFile(named: "f3") - - let files = try directory.files() - XCTAssertEqual(files.count, 3) - files.forEach { file in XCTAssertTrue(file.url.relativePath.contains(directory.url.relativePath)) } - files.forEach { file in XCTAssertTrue(fileManager.fileExists(atPath: file.url.path)) } - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Storage/FileTests.swift b/Tests/ExportersTests/PersistenceExporter/Storage/FileTests.swift deleted file mode 100644 index 7863be7c..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Storage/FileTests.swift +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class FileTests: XCTestCase { - private let fileManager = FileManager.default - @UniqueTemporaryDirectory private var temporaryDirectory: Directory - - override func setUp() { - super.setUp() - temporaryDirectory.create() - } - - override func tearDown() { - temporaryDirectory.delete() - super.tearDown() - } - - func testItAppendsDataToFile() throws { - let file = try temporaryDirectory.createFile(named: "file") - - try file.append(data: Data([0x41, 0x41, 0x41, 0x41, 0x41])) // 5 bytes - - XCTAssertEqual(try Data(contentsOf: file.url), - Data([0x41, 0x41, 0x41, 0x41, 0x41])) - - try file.append(data: Data([0x42, 0x42, 0x42, 0x42, 0x42])) // 5 bytes - try file.append(data: Data([0x41, 0x41, 0x41, 0x41, 0x41])) // 5 bytes - - XCTAssertEqual(try Data(contentsOf: file.url), - Data( - [ - 0x41, 0x41, 0x41, 0x41, 0x41, - 0x42, 0x42, 0x42, 0x42, 0x42, - 0x41, 0x41, 0x41, 0x41, 0x41 - ] - )) - } - - func testItReadsDataFromFile() throws { - let file = try temporaryDirectory.createFile(named: "file") - try file.append(data: "Hello 👋".utf8Data) - - XCTAssertEqual(try file.read().utf8String, "Hello 👋") - } - - func testItDeletesFile() throws { - let file = try temporaryDirectory.createFile(named: "file") - XCTAssertTrue(fileManager.fileExists(atPath: file.url.path)) - - try file.delete() - - XCTAssertFalse(fileManager.fileExists(atPath: file.url.path)) - } - - func testItReturnsFileSize() throws { - let file = try temporaryDirectory.createFile(named: "file") - - try file.append(data: .mock(ofSize: 5)) - XCTAssertEqual(try file.size(), 5) - - try file.append(data: .mock(ofSize: 10)) - XCTAssertEqual(try file.size(), 15) - } - - func testWhenIOExceptionHappens_itThrowsWhenWriting() throws { - let file = try temporaryDirectory.createFile(named: "file") - try file.delete() - - XCTAssertThrowsError(try file.append(data: .mock(ofSize: 5))) { error in - XCTAssertTrue((error as NSError).localizedDescription.contains("doesn’t exist.")) - } - } - - func testWhenIOExceptionHappens_itThrowsWhenReading() throws { - let file = try temporaryDirectory.createFile(named: "file") - try file.append(data: .mock(ofSize: 5)) - try file.delete() - - XCTAssertThrowsError(try file.read()) { error in - XCTAssertTrue((error as NSError).localizedDescription.contains("doesn’t exist.")) - } - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Storage/FilesOrchestratorTests.swift b/Tests/ExportersTests/PersistenceExporter/Storage/FilesOrchestratorTests.swift deleted file mode 100644 index 229efa42..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Storage/FilesOrchestratorTests.swift +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class FilesOrchestratorTests: XCTestCase { - private let performance: PersistencePerformancePreset = .default - @UniqueTemporaryDirectory private var temporaryDirectory: Directory - - override func setUp() { - super.setUp() - temporaryDirectory.create() - } - - override func tearDown() { - temporaryDirectory.delete() - super.tearDown() - } - - /// Configures `FilesOrchestrator` under tests. - private func configureOrchestrator(using dateProvider: DateProvider) -> FilesOrchestrator { - return FilesOrchestrator(directory: temporaryDirectory, - performance: performance, - dateProvider: dateProvider) - } - - // MARK: - Writable file tests - - func testGivenDefaultWriteConditions_whenUsedFirstTime_itCreatesNewWritableFile() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - _ = try orchestrator.getWritableFile(writeSize: 1) - - XCTAssertEqual(try temporaryDirectory.files().count, 1) - XCTAssertNotNil(temporaryDirectory.file(named: dateProvider.currentDate().toFileName)) - } - - func testGivenDefaultWriteConditions_whenUsedNextTime_itReusesWritableFile() throws { - let orchestrator = configureOrchestrator(using: RelativeDateProvider(advancingBySeconds: 1)) - let file1 = try orchestrator.getWritableFile(writeSize: 1) - let file2 = try orchestrator.getWritableFile(writeSize: 1) - - XCTAssertEqual(try temporaryDirectory.files().count, 1) - XCTAssertEqual(file1.name, file2.name) - } - - func testGivenDefaultWriteConditions_whenFileCanNotBeUsedMoreTimes_itCreatesNewFile() throws { - let orchestrator = configureOrchestrator(using: RelativeDateProvider(advancingBySeconds: 0.001)) - var previousFile: WritableFile = try orchestrator.getWritableFile(writeSize: 1) // first use - var nextFile: WritableFile - - // use file maximum number of times - for _ in (0 ..< performance.maxObjectsInFile).dropLast() { // skip first use - nextFile = try orchestrator.getWritableFile(writeSize: 1) - XCTAssertEqual(nextFile.name, previousFile.name) // assert it uses same file - previousFile = nextFile - } - - // next time it returns different file - nextFile = try orchestrator.getWritableFile(writeSize: 1) - XCTAssertNotEqual(nextFile.name, previousFile.name) - } - - func testGivenDefaultWriteConditions_whenFileHasNoRoomForMore_itCreatesNewFile() throws { - let orchestrator = configureOrchestrator(using: RelativeDateProvider(advancingBySeconds: 1)) - let chunkedData: [Data] = .mockChunksOf(totalSize: performance.maxFileSize, - maxChunkSize: performance.maxObjectSize) - - let file1 = try orchestrator.getWritableFile(writeSize: performance.maxObjectSize) - try chunkedData.forEach { chunk in try file1.append(data: chunk, synchronized: false) } - let file2 = try orchestrator.getWritableFile(writeSize: 1) - - XCTAssertNotEqual(file1.name, file2.name) - } - - func testGivenDefaultWriteConditions_fileIsNotRecentEnough_itCreatesNewFile() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - - let file1 = try orchestrator.getWritableFile(writeSize: 1) - dateProvider.advance(bySeconds: 1 + performance.maxFileAgeForWrite) - let file2 = try orchestrator.getWritableFile(writeSize: 1) - - XCTAssertNotEqual(file1.name, file2.name) - } - - func testWhenCurrentWritableFileIsDeleted_itCreatesNewOne() throws { - let orchestrator = configureOrchestrator(using: RelativeDateProvider(advancingBySeconds: 1)) - - let file1 = try orchestrator.getWritableFile(writeSize: 1) - try temporaryDirectory.files().forEach { try $0.delete() } - let file2 = try orchestrator.getWritableFile(writeSize: 1) - - XCTAssertNotEqual(file1.name, file2.name) - } - - /// This test makes sure that if SDK is used by multiple processes simultaneously, each `FileOrchestrator` works on a separate writable file. - /// It is important when SDK is used by iOS App and iOS App Extension at the same time. - func testWhenRequestedFirstTime_eachOrchestratorInstanceCreatesNewWritableFile() throws { - let orchestrator1 = configureOrchestrator(using: RelativeDateProvider()) - let orchestrator2 = configureOrchestrator(using: RelativeDateProvider(startingFrom: Date().secondsAgo(0.01)) // simulate time difference - ) - - _ = try orchestrator1.getWritableFile(writeSize: 1) - XCTAssertEqual(try temporaryDirectory.files().count, 1) - - _ = try orchestrator2.getWritableFile(writeSize: 1) - XCTAssertEqual(try temporaryDirectory.files().count, 2) - } - - func testWhenFilesDirectorySizeIsBig_itKeepsItUnderLimit_byRemovingOldestFilesFirst() throws { - let oneMB: UInt64 = 1024 * 1024 - - let orchestrator = FilesOrchestrator(directory: temporaryDirectory, - performance: StoragePerformanceMock(maxFileSize: oneMB, // 1MB - maxDirectorySize: 3 * oneMB, // 3MB, - maxFileAgeForWrite: .distantFuture, - minFileAgeForRead: .mockAny(), - maxFileAgeForRead: .mockAny(), - maxObjectsInFile: 1, // create new file each time - maxObjectSize: .max), - dateProvider: RelativeDateProvider(advancingBySeconds: 1)) - - // write 1MB to first file (1MB of directory size in total) - let file1 = try orchestrator.getWritableFile(writeSize: oneMB) - try file1.append(data: .mock(ofSize: oneMB), synchronized: false) - - // write 1MB to second file (2MB of directory size in total) - let file2 = try orchestrator.getWritableFile(writeSize: oneMB) - try file2.append(data: .mock(ofSize: oneMB), synchronized: true) - - // write 1MB to third file (3MB of directory size in total) - let file3 = try orchestrator.getWritableFile(writeSize: oneMB + 1) // +1 byte to exceed the limit - try file3.append(data: .mock(ofSize: oneMB + 1), synchronized: false) - - XCTAssertEqual(try temporaryDirectory.files().count, 3) - - // At this point, directory reached its maximum size. - // Asking for the next file should purge the oldest one. - let file4 = try orchestrator.getWritableFile(writeSize: oneMB) - XCTAssertEqual(try temporaryDirectory.files().count, 3) - XCTAssertNil(temporaryDirectory.file(named: file1.name)) - try file4.append(data: .mock(ofSize: oneMB + 1), synchronized: true) - - _ = try orchestrator.getWritableFile(writeSize: oneMB) - XCTAssertEqual(try temporaryDirectory.files().count, 3) - XCTAssertNil(temporaryDirectory.file(named: file2.name)) - } - - // MARK: - Readable file tests - - func testGivenDefaultReadConditions_whenThereAreNoFiles_itReturnsNil() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - dateProvider.advance(bySeconds: 1 + performance.minFileAgeForRead) - XCTAssertNil(orchestrator.getReadableFile()) - } - - func testGivenDefaultReadConditions_whenFileIsOldEnough_itReturnsReadableFile() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - let file = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - - dateProvider.advance(bySeconds: 1 + performance.minFileAgeForRead) - XCTAssertEqual(orchestrator.getReadableFile()?.name, file.name) - } - - func testGivenDefaultReadConditions_whenFileIsTooYoung_itReturnsNoFile() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - _ = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - - dateProvider.advance(bySeconds: 0.5 * performance.minFileAgeForRead) - XCTAssertNil(orchestrator.getReadableFile()) - } - - func testGivenDefaultReadConditions_whenThereAreSeveralFiles_itReturnsTheOldestOne() throws { - let dateProvider = RelativeDateProvider(advancingBySeconds: 1) - let orchestrator = configureOrchestrator(using: dateProvider) - let fileNames = (0 ..< 4).map { _ in dateProvider.currentDate().toFileName } - try fileNames.forEach { fileName in _ = try temporaryDirectory.createFile(named: fileName) } - - dateProvider.advance(bySeconds: 1 + performance.minFileAgeForRead) - XCTAssertEqual(orchestrator.getReadableFile()?.name, fileNames[0]) - try temporaryDirectory.file(named: fileNames[0])?.delete() - XCTAssertEqual(orchestrator.getReadableFile()?.name, fileNames[1]) - try temporaryDirectory.file(named: fileNames[1])?.delete() - XCTAssertEqual(orchestrator.getReadableFile()?.name, fileNames[2]) - try temporaryDirectory.file(named: fileNames[2])?.delete() - XCTAssertEqual(orchestrator.getReadableFile()?.name, fileNames[3]) - try temporaryDirectory.file(named: fileNames[3])?.delete() - XCTAssertNil(orchestrator.getReadableFile()) - } - - func testGivenDefaultReadConditions_whenThereAreSeveralFiles_itExcludesGivenFileNames() throws { - let dateProvider = RelativeDateProvider(advancingBySeconds: 1) - let orchestrator = configureOrchestrator(using: dateProvider) - let fileNames = (0 ..< 4).map { _ in dateProvider.currentDate().toFileName } - try fileNames.forEach { fileName in _ = try temporaryDirectory.createFile(named: fileName) } - - dateProvider.advance(bySeconds: 1 + performance.minFileAgeForRead) - - XCTAssertEqual(orchestrator.getReadableFile(excludingFilesNamed: Set(fileNames[0 ... 2]))?.name, - fileNames[3]) - } - - func testGivenDefaultReadConditions_whenFileIsTooOld_itGetsDeleted() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - _ = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - - dateProvider.advance(bySeconds: 2 * performance.maxFileAgeForRead) - - XCTAssertNil(orchestrator.getReadableFile()) - XCTAssertEqual(try temporaryDirectory.files().count, 0) - } - - func testItDeletesReadableFile() throws { - let dateProvider = RelativeDateProvider() - let orchestrator = configureOrchestrator(using: dateProvider) - _ = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - - dateProvider.advance(bySeconds: 1 + performance.minFileAgeForRead) - - let readableFile = try orchestrator.getReadableFile().unwrapOrThrow() - XCTAssertEqual(try temporaryDirectory.files().count, 1) - orchestrator.delete(readableFile: readableFile) - XCTAssertEqual(try temporaryDirectory.files().count, 0) - } - - // MARK: - File names tests - - // swiftlint:disable number_separator - func testItTurnsFileNameIntoFileCreationDate() { - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 0)), "0") - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456)), "123456000") - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456.7)), "123456700") - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456.78)), "123456780") - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456.789)), "123456789") - - // microseconds rounding - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456.1111)), "123456111") - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456.1115)), "123456112") - XCTAssertEqual(fileNameFrom(fileCreationDate: Date(timeIntervalSinceReferenceDate: 123456.1119)), "123456112") - - // overflows - let maxDate = Date(timeIntervalSinceReferenceDate: TimeInterval.greatestFiniteMagnitude) - let minDate = Date(timeIntervalSinceReferenceDate: -TimeInterval.greatestFiniteMagnitude) - XCTAssertEqual(fileNameFrom(fileCreationDate: maxDate), "0") - XCTAssertEqual(fileNameFrom(fileCreationDate: minDate), "0") - } - - func testItTurnsFileCreationDateIntoFileName() { - XCTAssertEqual(fileCreationDateFrom(fileName: "0"), Date(timeIntervalSinceReferenceDate: 0)) - XCTAssertEqual(fileCreationDateFrom(fileName: "123456000"), Date(timeIntervalSinceReferenceDate: 123456)) - XCTAssertEqual(fileCreationDateFrom(fileName: "123456700"), Date(timeIntervalSinceReferenceDate: 123456.7)) - XCTAssertEqual(fileCreationDateFrom(fileName: "123456780"), Date(timeIntervalSinceReferenceDate: 123456.78)) - XCTAssertEqual(fileCreationDateFrom(fileName: "123456789"), Date(timeIntervalSinceReferenceDate: 123456.789)) - - // ignores invalid names - let invalidFileName = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - XCTAssertEqual(fileCreationDateFrom(fileName: invalidFileName), Date(timeIntervalSinceReferenceDate: 0)) - } - - // swiftlint:enable number_separator -} diff --git a/Tests/ExportersTests/PersistenceExporter/Storage/OrchestratedFileReaderTests.swift b/Tests/ExportersTests/PersistenceExporter/Storage/OrchestratedFileReaderTests.swift deleted file mode 100644 index 8f54fee5..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Storage/OrchestratedFileReaderTests.swift +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class OrchestratedFileReaderTests: XCTestCase { - @UniqueTemporaryDirectory private var temporaryDirectory: Directory - - override func setUp() { - super.setUp() - temporaryDirectory.create() - } - - override func tearDown() { - temporaryDirectory.delete() - super.tearDown() - } - - func testItReadsSingleBatch() throws { - let reader = OrchestratedFileReader( - orchestrator: FilesOrchestrator(directory: temporaryDirectory, - performance: StoragePerformanceMock.readAllFiles, - dateProvider: SystemDateProvider()) - ) - _ = try temporaryDirectory - .createFile(named: Date.mockAny().toFileName) - .append(data: "ABCD".utf8Data) - - XCTAssertEqual(try temporaryDirectory.files().count, 1) - let batch = reader.readNextBatch() - - XCTAssertEqual(batch?.data, "ABCD".utf8Data) - } - - func testItMarksBatchesAsRead() throws { - let dateProvider = RelativeDateProvider(advancingBySeconds: 60) - let reader = OrchestratedFileReader( - orchestrator: FilesOrchestrator(directory: temporaryDirectory, - performance: StoragePerformanceMock.readAllFiles, - dateProvider: dateProvider) - ) - let file1 = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - try file1.append(data: "1".utf8Data) - - let file2 = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - try file2.append(data: "2".utf8Data) - - let file3 = try temporaryDirectory.createFile(named: dateProvider.currentDate().toFileName) - try file3.append(data: "3".utf8Data) - - var batch: Batch - batch = try reader.readNextBatch().unwrapOrThrow() - XCTAssertEqual(batch.data, "1".utf8Data) - reader.markBatchAsRead(batch) - - batch = try reader.readNextBatch().unwrapOrThrow() - XCTAssertEqual(batch.data, "2".utf8Data) - reader.markBatchAsRead(batch) - - batch = try reader.readNextBatch().unwrapOrThrow() - XCTAssertEqual(batch.data, "3".utf8Data) - reader.markBatchAsRead(batch) - - XCTAssertNil(reader.readNextBatch()) - XCTAssertEqual(try temporaryDirectory.files().count, 0) - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Storage/OrchestratedFileWriterTests.swift b/Tests/ExportersTests/PersistenceExporter/Storage/OrchestratedFileWriterTests.swift deleted file mode 100644 index 304f7c35..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Storage/OrchestratedFileWriterTests.swift +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class OrchestratedFileWriterTests: XCTestCase { - @UniqueTemporaryDirectory private var temporaryDirectory: Directory - - override func setUp() { - super.setUp() - temporaryDirectory.create() - } - - override func tearDown() { - temporaryDirectory.delete() - super.tearDown() - } - - func testItWritesDataToSingleFile() throws { - let expectation = expectation(description: "write completed") - let writer = OrchestratedFileWriter( - orchestrator: FilesOrchestrator(directory: temporaryDirectory, - performance: PersistencePerformancePreset.default, - dateProvider: SystemDateProvider()) - ) - - var data = Data() - - var value = "value1" - writer.write(data: value.utf8Data) - data.append(value.utf8Data) - - value = "value2" - writer.write(data: value.utf8Data) - data.append(value.utf8Data) - - value = "value3" - writer.write(data: value.utf8Data) - data.append(value.utf8Data) - - waitForWritesCompletion(on: writer.queue, thenFulfill: expectation) - waitForExpectations(timeout: 1, handler: nil) - XCTAssertEqual(try temporaryDirectory.files().count, 1) - XCTAssertEqual(try temporaryDirectory.files()[0].read(), data) - } - - func testGivenErrorVerbosity_whenIndividualDataExceedsMaxWriteSize_itDropsDataAndPrintsError() throws { - let expectation1 = expectation(description: "write completed") - let expectation2 = expectation(description: "second write completed") - - let writer = OrchestratedFileWriter( - orchestrator: FilesOrchestrator(directory: temporaryDirectory, - performance: StoragePerformanceMock(maxFileSize: .max, - maxDirectorySize: .max, - maxFileAgeForWrite: .distantFuture, - minFileAgeForRead: .mockAny(), - maxFileAgeForRead: .mockAny(), - maxObjectsInFile: .max, - maxObjectSize: 17 // 17 bytes is enough to write {"key1":"value1"} JSON - ), - dateProvider: SystemDateProvider()) - ) - - writer.write(data: "value1".utf8Data) // will be written - - waitForWritesCompletion(on: writer.queue, thenFulfill: expectation1) - wait(for: [expectation1], timeout: 1) - XCTAssertEqual(try temporaryDirectory.files()[0].read(), "value1".utf8Data) - - writer.write(data: "value2 that makes it exceed 17 bytes".utf8Data) // will be dropped - - waitForWritesCompletion(on: writer.queue, thenFulfill: expectation2) - wait(for: [expectation2], timeout: 1) - XCTAssertEqual(try temporaryDirectory.files()[0].read(), "value1".utf8Data) // same content as before - } - - /// NOTE: Test added after incident-4797 - /// NOTE 2: Test disabled after random failures/successes -// func testWhenIOExceptionsHappenRandomly_theFileIsNeverMalformed() throws { -// let expectation = self.expectation(description: "write completed") -// let writer = OrchestratedFileWriter( -// orchestrator: FilesOrchestrator( -// directory: temporaryDirectory, -// performance: StoragePerformanceMock( -// maxFileSize: .max, -// maxDirectorySize: .max, -// maxFileAgeForWrite: .distantFuture, // write to single file -// minFileAgeForRead: .distantFuture, -// maxFileAgeForRead: .distantFuture, -// maxObjectsInFile: .max, // write to single file -// maxObjectSize: .max -// ), -// dateProvider: SystemDateProvider() -// ) -// ) -// -// let ioInterruptionQueue = DispatchQueue(label: "com.otel.persistence.file-writer-random-io") -// -// func randomlyInterruptIO(for file: File?) { -// ioInterruptionQueue.async { try? file?.makeReadonly() } -// ioInterruptionQueue.async { try? file?.makeReadWrite() } -// } -// -// struct Foo: Codable { -// var foo = "bar" -// } -// -// let jsonEncoder = JSONEncoder() -// -// // Write 300 of `Foo`s and interrupt writes randomly -// try (0..<300).forEach { _ in -// var fooData = try jsonEncoder.encode(Foo()) -// fooData.append(",".utf8Data) -// writer.write(data: fooData) -// randomlyInterruptIO(for: try? temporaryDirectory.files().first) -// } -// -// ioInterruptionQueue.sync {} -// waitForWritesCompletion(on: writer.queue, thenFulfill: expectation) -// waitForExpectations(timeout: 7, handler: nil) -// XCTAssertEqual(try temporaryDirectory.files().count, 1) -// -// let fileData = try temporaryDirectory.files()[0].read() -// let jsonDecoder = JSONDecoder() -// -// // Assert that data written is not malformed -// let writtenData = try jsonDecoder.decode([Foo].self, from: "[".utf8Data + fileData + "]".utf8Data) -// // Assert that some (including all) `Foo`s were written -// XCTAssertGreaterThan(writtenData.count, 0) -// XCTAssertLessThanOrEqual(writtenData.count, 300) -// } - - private func waitForWritesCompletion(on queue: DispatchQueue, thenFulfill expectation: XCTestExpectation) { - queue.async { expectation.fulfill() } - } -} diff --git a/Tests/ExportersTests/PersistenceExporter/Utils/PerformancePresetTests.swift b/Tests/ExportersTests/PersistenceExporter/Utils/PerformancePresetTests.swift deleted file mode 100644 index 9008db39..00000000 --- a/Tests/ExportersTests/PersistenceExporter/Utils/PerformancePresetTests.swift +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import PersistenceExporter -import XCTest - -class PerformancePresetTests: XCTestCase { - func testDefaultPreset() { - XCTAssertEqual(PersistencePerformancePreset.default, .lowRuntimeImpact) - } - - func testPresetsConsistency() { - let presets: [PersistencePerformancePreset] = [.lowRuntimeImpact, .instantDataDelivery] - - presets.forEach { preset in - XCTAssertLessThan(preset.maxFileSize, - preset.maxDirectorySize, - "Size of individual file must not exceed the directory size limit.") - XCTAssertLessThan(preset.maxFileAgeForWrite, - preset.minFileAgeForRead, - "File should not be considered for export (read) while it is eligible for writes.") - XCTAssertGreaterThan(preset.maxFileAgeForRead, - preset.minFileAgeForRead, - "File read boundaries must be consistent.") - XCTAssertGreaterThan(preset.maxExportDelay, - preset.minExportDelay, - "Export delay boundaries must be consistent.") - XCTAssertGreaterThan(preset.maxExportDelay, - preset.minExportDelay, - "Export delay boundaries must be consistent.") - XCTAssertLessThanOrEqual(preset.exportDelayChangeRate, - 1, - "Export delay should not change by more than %100 at once.") - XCTAssertGreaterThan(preset.exportDelayChangeRate, - 0, - "Export delay must change at non-zero rate.") - } - } -} diff --git a/Tests/ExportersTests/Prometheus/PrometheusExporterTests.swift b/Tests/ExportersTests/Prometheus/PrometheusExporterTests.swift deleted file mode 100644 index e4d0be49..00000000 --- a/Tests/ExportersTests/Prometheus/PrometheusExporterTests.swift +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif -import OpenTelemetryApi -import OpenTelemetrySdk -@testable import PrometheusExporter -import XCTest - -class PrometheusExporterTests: XCTestCase { - let metricPushIntervalSec = 0.05 - let waitDuration = 0.1 + 0.1 - - func testMetricsHttpServerAsync() { - let promOptions = PrometheusExporterOptions(url: "http://localhost:9184/metrics/") - let promExporter = PrometheusExporter(options: promOptions) - let metricsHttpServer = PrometheusExporterHttpServer(exporter: promExporter) - - let expec = expectation(description: "Get metrics from server") - - DispatchQueue.global(qos: .default).async { - do { - try metricsHttpServer.start() - } catch { - XCTFail() - return - } - } - - let retain_me = collectMetrics(exporter: promExporter) - _ = retain_me // silence warning - usleep(useconds_t(waitDuration * 1000000)) - let url = URL(string: "http://localhost:9184/metrics/")! - let task = URLSession.shared.dataTask(with: url) { data, response, error in - if error == nil, let data, let response = response as? HTTPURLResponse { - XCTAssert(response.statusCode == 200) - let responseText = String(decoding: data, as: UTF8.self) - print("Response from metric API is: \n\(responseText)") - self.validateResponse(responseText: responseText) - // This is your file-variable: - // data - expec.fulfill() - } else { - XCTFail() - expec.fulfill() - return - } - } - task.resume() - - waitForExpectations(timeout: 30) { error in - if let error { - print("Error: \(error.localizedDescription)") - XCTFail() - } - } - - metricsHttpServer.stop() - } - - private func collectMetrics(exporter: any MetricExporter) -> MeterProviderSdk { - let meterProvider = MeterProviderSdk.builder() - .registerMetricReader( - reader: PeriodicMetricReaderBuilder( - exporter: exporter - ) - .setInterval(timeInterval: 0.01) - .build() - ) - .registerView( - selector: InstrumentSelector - .builder() - .setInstrument(name: "testHistogram") - .build(), - view: View.builder() - .withAggregation( - aggregation: ExplicitBucketHistogramAggregation(bucketBoundaries: [5, 10, 25]) - ).build() - ) - .registerView( - selector: InstrumentSelector.builder().setInstrument(name: "testCounter|testGauge").build(), - view: View.builder().build() - ) - .build() - let meter = meterProvider.get(name: "scope1") - - let testCounter = meter.counterBuilder(name: "testCounter").build() - let testGauge = meter.gaugeBuilder(name: "testGauge").build() - let testHistogram = meter.histogramBuilder(name: "testHistogram").build() - let labels1 = ["dim1": AttributeValue.string("value1"), "dim2": AttributeValue.string("value1")] - let labels2 = ["dim1": AttributeValue.string("value2"), "dim2": AttributeValue.string("value2")] - let labels3 = ["dim1": AttributeValue.string("value1")] - - for _ in 0 ..< 10 { - testCounter.add(value: 100, attributes: labels1) - testCounter.add(value: 10, attributes: labels1) - testCounter.add(value: 200, attributes: labels2) - testCounter.add(value: 10, attributes: labels2) - - testGauge.record(value: 500, attributes: labels1) - - testHistogram.record(value: 8, attributes: labels3) - testHistogram.record(value: 20, attributes: labels3) - testHistogram.record(value: 30, attributes: labels3) - } - return meterProvider - } - - private func validateResponse(responseText: String) { - // Validate counters. - XCTAssert(responseText.contains("TYPE testCounter counter")) - XCTAssert(responseText.contains("testCounter{dim1=\"value1\",dim2=\"value1\"}") || responseText.contains("testCounter{dim2=\"value1\",dim1=\"value1\"}")) - XCTAssert(responseText.contains("testCounter{dim1=\"value2\",dim2=\"value2\"}") || responseText.contains("testCounter{dim2=\"value2\",dim1=\"value2\"}")) - - // Validate measure. - XCTAssert(responseText.contains("# TYPE testGauge gauge")) - XCTAssert(responseText.contains("testGauge{dim2=\"value1\",dim1=\"value1\"} 500") || - responseText.contains("testGauge{dim1=\"value1\",dim2=\"value1\"} 500")) - - // Validate histogram. - XCTAssert(responseText.contains("# TYPE testHistogram histogram")) - // sum is 58 = 8 + 20 + 30 - XCTAssert(responseText.contains("testHistogram_sum{dim1=\"value1\"} 58")) - // count is 1 * 3 - XCTAssert(responseText.contains("testHistogram_count{dim1=\"value1\"} 3")) - // validate le - XCTAssert(responseText.contains("testHistogram{dim1=\"value1\",le=\"5.000000\"} 0") || responseText.contains("testHistogram{le=\"5.000000\",dim1=\"value1\"} 0")) - XCTAssert(responseText.contains("testHistogram{dim1=\"value1\",le=\"10.000000\"} 1") || responseText.contains("testHistogram{le=\"10.000000\",dim1=\"value1\"} 1")) - XCTAssert(responseText.contains("testHistogram{dim1=\"value1\",le=\"25.000000\"} 1") || responseText.contains("testHistogram{le=\"25.000000\",dim1=\"value1\"} 1")) - XCTAssert(responseText.contains("testHistogram{dim1=\"value1\",le=\"+Inf\"} 1") || responseText.contains("testHistogram{le=\"+Inf\",dim1=\"value1\"} 1")) - } -} diff --git a/Tests/ExportersTests/Zipkin/Implementation/ZipkinSpanConverterTests.swift b/Tests/ExportersTests/Zipkin/Implementation/ZipkinSpanConverterTests.swift deleted file mode 100644 index d3dc09a0..00000000 --- a/Tests/ExportersTests/Zipkin/Implementation/ZipkinSpanConverterTests.swift +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -@testable import OpenTelemetrySdk -import XCTest -@testable import ZipkinExporter - -class ZipkinSpanConverterTests: XCTestCase { - let defaultZipkinEndpoint = ZipkinEndpoint(serviceName: "TestService") - - func testGenerateSpanRemoteEndpointOmittedByDefault() { - let span = ZipkinSpanConverterTests.createTestSpan() - let zipkinSpan = ZipkinConversionExtension.toZipkinSpan(otelSpan: span, defaultLocalEndpoint: defaultZipkinEndpoint) - XCTAssertNil(zipkinSpan.remoteEndpoint) - } - - func testGenerateSpanRemoteEndpointResolution() { - let span = ZipkinSpanConverterTests.createTestSpan(additionalAttributes: ["net.peer.name": "RemoteServiceName"]) - let zipkinSpan = ZipkinConversionExtension.toZipkinSpan(otelSpan: span, defaultLocalEndpoint: defaultZipkinEndpoint) - XCTAssertNotNil(zipkinSpan.remoteEndpoint) - XCTAssertEqual(zipkinSpan.remoteEndpoint?.serviceName, "RemoteServiceName") - } - - func testGenerateSpanRemoteEndpointResolutionPriority() { - let span = ZipkinSpanConverterTests.createTestSpan(additionalAttributes: ["http.host": "DiscardedRemoteServiceName", - "net.peer.name": "RemoteServiceName", - "peer.hostname": "DiscardedRemoteServiceName"]) - let zipkinSpan = ZipkinConversionExtension.toZipkinSpan(otelSpan: span, defaultLocalEndpoint: defaultZipkinEndpoint) - XCTAssertNotNil(zipkinSpan.remoteEndpoint) - XCTAssertEqual(zipkinSpan.remoteEndpoint?.serviceName, "RemoteServiceName") - } - - func testStatusUnset() { - let span = ZipkinSpanConverterTests.createTestSpan(status: Status.unset) - let zipkinSpan = ZipkinConversionExtension.toZipkinSpan(otelSpan: span, defaultLocalEndpoint: defaultZipkinEndpoint) - XCTAssertNil(zipkinSpan.tags["otel.status_code"]) - } - - func testStatusError() { - let span = ZipkinSpanConverterTests.createTestSpan(status: Status.error(description: "error message")) - let zipkinSpan = ZipkinConversionExtension.toZipkinSpan(otelSpan: span, defaultLocalEndpoint: defaultZipkinEndpoint) - XCTAssertEqual(zipkinSpan.tags["otel.status_code"], "ERROR") - XCTAssertEqual(zipkinSpan.tags["error"], "error message") - } - - public static func createTestSpan(setAttributes: Bool = true, additionalAttributes: [String: Any]? = nil, addEvents: Bool = true, addLinks: Bool = true, status: Status = Status.ok) -> SpanData { - let startTimestamp = Date(timeIntervalSince1970: Double(Int(Date().timeIntervalSince1970))) // Round for comparison - let endTimestamp = startTimestamp.addingTimeInterval(60) - let eventTimestamp = startTimestamp - let traceId = TraceId(fromHexString: "e8ea7e9ac72de94e91fabc613f9686b2") - - let spanId = SpanId.random() - let parentSpanId = SpanId(fromBytes: [12, 23, 34, 45, 56, 67, 78, 89]) - var attributes: [String: AttributeValue] = ["stringKey": AttributeValue.string("value"), - "longKey": AttributeValue.int(1), - "longKey2": AttributeValue.int(1), - "doubleKey": AttributeValue.double(1.0), - "doubleKey2": AttributeValue.double(1.0), - "boolKey": AttributeValue.bool(true)] - - additionalAttributes?.forEach { - attributes[$0.key] = AttributeValue($0.value) - } - - let events: [SpanData.Event] = [SpanData.Event(name: "Event1", timestamp: eventTimestamp, attributes: ["key": AttributeValue.string("value")]), - SpanData.Event(name: "Event2", timestamp: eventTimestamp, attributes: ["key": AttributeValue.string("value")])] - -// let linkedSpanId = SpanId(fromHexString: "888915b6286b9c41") - - return SpanData(traceId: traceId, spanId: spanId, parentSpanId: parentSpanId, resource: Resource.empty, name: "Name", kind: .client, startTime: startTimestamp, attributes: attributes, events: events, status: status, endTime: endTimestamp) - } -} diff --git a/Tests/ExportersTests/Zipkin/ZipkinExporterTests.swift b/Tests/ExportersTests/Zipkin/ZipkinExporterTests.swift deleted file mode 100644 index c6d03551..00000000 --- a/Tests/ExportersTests/Zipkin/ZipkinExporterTests.swift +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -@testable import OpenTelemetrySdk -import XCTest -@testable import ZipkinExporter - -class ZipkinExporterTests: XCTestCase { - func testZipkinExporterIntegration() { - let spans = [ZipkinSpanConverterTests.createTestSpan()] - - _ = UUID() - - let exporter = ZipkinTraceExporter(options: ZipkinTraceExporterOptions(endpoint: "http://localhost:9090/api/v2/spans?requestId={requestId}")) - - _ = exporter.export(spans: spans) - - let span = spans[0] - - let timestamp = span.startTime.timeIntervalSince1970 * 1000000 - - var ipInformation = "" - if let ipv4 = exporter.localEndPoint.ipv4 { - ipInformation += #","ipv4":"\#(ipv4)""# - } - - if let ipv6 = exporter.localEndPoint.ipv6 { - ipInformation += #","ipv6":"\#(ipv6)""# - } - - let exporterOutputArray = spans.map { ZipkinConversionExtension.toZipkinSpan(otelSpan: $0, defaultLocalEndpoint: ZipkinTraceExporter.getLocalZipkinEndpoint(name: "Open Telemetry Exporter")) }.map { $0.write() } - - let expectedOutputString = #"{"traceId":"e8ea7e9ac72de94e91fabc613f9686b2","name":"Name","parentId":"\#(span.parentSpanId!.hexString)","id":"\#(span.spanId.hexString)","kind":"CLIENT","timestamp":\#(timestamp),"duration":60000000,"localEndpoint":{"serviceName":"Open Telemetry Exporter"\#(ipInformation)},"annotations":[{"timestamp":\#(timestamp),"value":"Event1"},{"timestamp":\#(timestamp),"value":"Event2"}],"tags":{"stringKey":"value","longKey":"1","longKey2":"1","doubleKey":"1.0","doubleKey2":"1.0","boolKey":"true","otel.status_code":"OK"}}"# - let expectedData = expectedOutputString.data(using: .utf8)! - let expectedOutputObject = try? JSONSerialization.jsonObject(with: expectedData) - let expectedOutput = expectedOutputObject as! NSDictionary - - let exporterOutput = exporterOutputArray[0] as NSDictionary - - compareDictionaries(dict1: exporterOutput, dict2: expectedOutput) - } -} - -func compareDictionaries(dict1: NSDictionary, dict2: NSDictionary) { - XCTAssertEqual(dict1.count, dict2.count) - let keys1 = dict1.allKeys.map { $0 as! NSString } - let keys2 = dict2.allKeys.map { $0 as! NSString } - - for key in keys1 { - let found = keys2.first { $0 == key } - XCTAssertNotNil(found) - if (dict1[key] as? NSDictionary) != nil { - compareDictionaries(dict1: dict1[key] as! NSDictionary, dict2: dict2[key] as! NSDictionary) - } else if (dict1[key] as? [Any]) != nil { - compareArrays(array1: dict1[key] as! [Any], array2: dict2[key] as! [Any]) - } else { - let object1 = dict1[key] as! NSObject - let object2 = dict2[key] as! NSObject - let equal = object1.isEqual(object2) - if !equal { - print(" Element error, key: \(key) differs: \(object1.description) VS \(object2.description)") - } - XCTAssertTrue(equal) - } - } -} - -func compareArrays(array1: [Any], array2: [Any]) { - let set1 = NSSet(array: array1) - let set2 = NSSet(array: array2) - - let equal = set1.isEqual(to: set2 as! Set) - if !equal { - print(" Element error, \(array1) and \(array2) differs") - } - XCTAssertTrue(equal) -} diff --git a/Tests/ImportersTests/OpenTracingShim/SpanShimTests.swift b/Tests/ImportersTests/OpenTracingShim/SpanShimTests.swift deleted file mode 100644 index f335862e..00000000 --- a/Tests/ImportersTests/OpenTracingShim/SpanShimTests.swift +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import OpenTelemetryApi -@testable import OpenTelemetrySdk -@testable import OpenTracingShim -import XCTest - -class SpanShimTests: XCTestCase { - let tracerProviderSdk = TracerProviderSdk() - var tracer: Tracer! - var telemetryInfo: TelemetryInfo! - var span: Span! - var tracerShim: TracerShim! - - let spanName = "Span" - - override func setUp() { - tracer = tracerProviderSdk.get(instrumentationName: "SpanShimTest") - telemetryInfo = TelemetryInfo(tracer: tracer, baggageManager: OpenTelemetry.instance.baggageManager, propagators: OpenTelemetry.instance.propagators) - span = tracer.spanBuilder(spanName: spanName).startSpan() - tracerShim = TracerShim(telemetryInfo: telemetryInfo) - } - - override func tearDown() { - span.end() - } - - func testContextSimple() { - let spanShim = SpanShim(telemetryInfo: telemetryInfo, span: span) - let contextShim = spanShim.context() as! SpanContextShim - XCTAssertEqual(contextShim.context, span.context) - } - - func testBaggage() { - let spanShim = SpanShim(telemetryInfo: telemetryInfo, span: span) - - _ = spanShim.setBaggageItem("key1", value: "value1") - _ = spanShim.setBaggageItem("key2", value: "value2") - XCTAssertEqual(spanShim.getBaggageItem("key1"), "value1") - XCTAssertEqual(spanShim.getBaggageItem("key2"), "value2") - - let contextShim = spanShim.context() as! SpanContextShim - let baggageDict = TestUtils.contextBaggageToDictionary(context: contextShim) - XCTAssertEqual(baggageDict.count, 2) - XCTAssertEqual(baggageDict["key1"], "value1") - XCTAssertEqual(baggageDict["key2"], "value2") - } - - func testBaggageReplacement() { - let spanShim = SpanShim(telemetryInfo: telemetryInfo, span: span) - let contextShim1 = spanShim.context() as! SpanContextShim - - _ = spanShim.setBaggageItem("key1", value: "value1") - let contextShim2 = spanShim.context() as! SpanContextShim - - XCTAssertNotEqual(contextShim1, contextShim2) - XCTAssertEqual(TestUtils.contextBaggageToDictionary(context: contextShim1).count, 0) - XCTAssertNotEqual(TestUtils.contextBaggageToDictionary(context: contextShim2).count, 0) - } - - func testBaggageDifferentShimObjs() { - let spanShim1 = SpanShim(telemetryInfo: telemetryInfo, span: span) - _ = spanShim1.setBaggageItem("key1", value: "value1") - - // Baggage should be synchronized among different SpanShim objects referring to the same Span. - - let spanShim2 = SpanShim(telemetryInfo: telemetryInfo, span: span) - _ = spanShim2.setBaggageItem("key1", value: "value2") - XCTAssertEqual(spanShim1.getBaggageItem("key1"), "value2") - XCTAssertEqual(spanShim2.getBaggageItem("key1"), "value2") - XCTAssertEqual(TestUtils.contextBaggageToDictionary(context: spanShim1.context()), TestUtils.contextBaggageToDictionary(context: spanShim2.context())) - } - - func testBaggageParent() { - let parentSpan = tracerShim.startSpan(spanName) - parentSpan.setBaggageItem("key1", value: "value1") - let childSpan = tracerShim.startSpan(spanName, childOf: parentSpan.context()) as! SpanShim - XCTAssertEqual(childSpan.getBaggageItem("key1"), "value1") - XCTAssertEqual(TestUtils.contextBaggageToDictionary(context: parentSpan.context()), TestUtils.contextBaggageToDictionary(context: childSpan.context())) - childSpan.finish() - parentSpan.finish() - } - - func testParentNullContextShim() { - let parentSpan = tracerShim.startSpan(spanName) - let childSpan = tracerShim.startSpan(spanName, childOf: parentSpan.context()) as! SpanShim - XCTAssertEqual(TestUtils.contextBaggageToDictionary(context: childSpan.context()).count, 0) - childSpan.finish() - parentSpan.finish() - } -} diff --git a/Tests/ImportersTests/OpenTracingShim/TestUtils.swift b/Tests/ImportersTests/OpenTracingShim/TestUtils.swift deleted file mode 100644 index 6ceb5db4..00000000 --- a/Tests/ImportersTests/OpenTracingShim/TestUtils.swift +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import Opentracing - -enum TestUtils { - static func contextBaggageToDictionary(context: OTSpanContext) -> [String: String] { - var dictionary = [String: String]() - context.forEachBaggageItem { key, value -> Bool in - dictionary[key] = value - return true - } - return dictionary - } -} diff --git a/Tests/ImportersTests/OpenTracingShim/TraceShimTests.swift b/Tests/ImportersTests/OpenTracingShim/TraceShimTests.swift deleted file mode 100644 index d394b9b1..00000000 --- a/Tests/ImportersTests/OpenTracingShim/TraceShimTests.swift +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import OpenTelemetryApi -import OpenTelemetrySdk -import Opentracing -@testable import OpenTracingShim -import XCTest - -class TraceShimTests: XCTestCase { - func testCreateTracerShimDefault() { - let tracerShim = TraceShim.createTracerShim() as! TracerShim - XCTAssert(OpenTelemetry.instance.tracerProvider.get(instrumentationName: "opentracingshim", instrumentationVersion: nil) === tracerShim.tracer) - XCTAssert(OpenTelemetry.instance.baggageManager === tracerShim.baggageManager) - } - - func testCreateTracerShim() { - let sdk = OpenTelemetry.instance.tracerProvider - let baggageManager = DefaultBaggageManager.instance - let tracerShim = TraceShim.createTracerShim(tracerProvider: sdk, baggageManager: baggageManager) as! TracerShim - - XCTAssert(sdk.get(instrumentationName: "opentracingshim", instrumentationVersion: nil) === tracerShim.tracer) - XCTAssert(baggageManager === tracerShim.baggageManager) - } -} diff --git a/Tests/ImportersTests/OpenTracingShim/TracerShimTests.swift b/Tests/ImportersTests/OpenTracingShim/TracerShimTests.swift deleted file mode 100644 index 3699142c..00000000 --- a/Tests/ImportersTests/OpenTracingShim/TracerShimTests.swift +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import OpenTelemetryApi -import OpenTelemetrySdk -import Opentracing -@testable import OpenTracingShim -import XCTest - -class TracerShimTests: XCTestCase { - let tracerProviderSdk = TracerProviderSdk() - var tracer: Tracer! - var telemetryInfo: TelemetryInfo! - var tracerShim: TracerShim! - - override func setUp() { - tracer = tracerProviderSdk.get(instrumentationName: "SpanShimTest") - let telemetryInfo = TelemetryInfo(tracer: tracer, baggageManager: OpenTelemetry.instance.baggageManager, propagators: OpenTelemetry.instance.propagators) - tracerShim = TracerShim(telemetryInfo: telemetryInfo) - } - - func testDefaultTracer() { - _ = tracerShim.startSpan("one") - XCTAssertNotNil(OpenTelemetry.instance.contextProvider.activeSpan) - } - - func testActiveSpan() { - let otSpan = tracerShim.startSpan("one") as! SpanShim - XCTAssertNotNil(OpenTelemetry.instance.contextProvider.activeSpan) - otSpan.finish() - } - - func testExtractNullContext() { - let result = tracerShim.extract(withFormat: OTFormatTextMap, carrier: [String: String]()) - XCTAssertNil(result) - } - - func testInjecttNullContext() { - let otSpan = tracerShim.startSpan("one") as! SpanShim - let map = [String: String]() - _ = tracerShim.inject(otSpan.context(), format: OTFormatTextMap, carrier: map) - XCTAssertEqual(map.count, 0) - } -} diff --git a/Tests/ImportersTests/SwiftMetricsShim/SwiftMetricsShimTests.swift b/Tests/ImportersTests/SwiftMetricsShim/SwiftMetricsShimTests.swift deleted file mode 100644 index 73ea567c..00000000 --- a/Tests/ImportersTests/SwiftMetricsShim/SwiftMetricsShimTests.swift +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import OpenTelemetryApi -@testable import OpenTelemetrySdk -@testable import CoreMetrics -@testable import SwiftMetricsShim -import XCTest - -class MetricExporterMock: MetricExporter { - func flush() -> OpenTelemetrySdk.ExportResult { - .success - } - - func shutdown() -> OpenTelemetrySdk.ExportResult { - .success - } - - func getAggregationTemporality(for instrument: OpenTelemetrySdk.InstrumentType) -> OpenTelemetrySdk.AggregationTemporality { - return AggregationTemporality.cumulative - } - - let onExport: ([MetricData]) -> ExportResult - init(onExport: @escaping ([MetricData]) -> ExportResult) { - self.onExport = onExport - } - - func export(metrics: [MetricData]) -> ExportResult { - return onExport(metrics) - } -} - -class SwiftMetricsShimTests: XCTestCase { - var mockExporter: MetricExporterMock! = nil - let provider: MeterSdk! = nil - var stableMetrics = [MetricData]() - var metrics: OpenTelemetrySwiftMetrics! = nil - var metricsExportExpectation: XCTestExpectation! = nil - override func setUp() { - super.setUp() - metricsExportExpectation = expectation(description: "metrics exported") - - var reader: PeriodicMetricReaderSdk! = nil - stableMetrics = [MetricData]() - mockExporter = MetricExporterMock { metrics in - self.stableMetrics = metrics - self.metricsExportExpectation.fulfill() - _ = reader.shutdown() - return .success - } - - reader = PeriodicMetricReaderSdk( - exporter: mockExporter, - exportInterval: 0.5 - ) - - let provider = MeterProviderSdk.builder() - .registerView( - selector: InstrumentSelector.builder().setInstrument(name: ".*").build(), - view: View.builder().build() - ) - .registerMetricReader( - reader: reader - ) - .build() - - metrics = .init(meter: provider.meterBuilder(name: "meter").build()) - MetricsSystem.bootstrapInternal(metrics) - } - - // MARK: - Test Lifecycle - - func testDestroy() { - let handler = metrics.makeCounter(label: "my_label", dimensions: []) - XCTAssertEqual(metrics.metrics.count, 1) - handler.increment(by: 1) - waitForExpectations(timeout: 10, handler: nil) - metrics.destroyCounter(handler) - XCTAssertEqual(metrics.metrics.count, 0) - } - - // MARK: - Test Metric: Counter - - func testCounter() throws { - let counter = Counter(label: "my_counter") - counter.increment() - - waitForExpectations(timeout: 10, handler: nil) - - let metric = stableMetrics[0] - let data = try XCTUnwrap(metric.data.points.last as? LongPointData) - XCTAssertEqual(metric.name, "my_counter") - XCTAssertEqual(metric.type, .LongSum) - XCTAssertEqual(data.value, 1) - XCTAssertNil(data.attributes["label_one"]) - } - - func testCounter_withLabels() throws { - let counter = Counter(label: "my_counter", dimensions: [("label_one", "value")]) - counter.increment(by: 5) - - waitForExpectations(timeout: 10, handler: nil) - - let metric = stableMetrics[0] - let data = try XCTUnwrap(metric.data.points.last as? LongPointData) - XCTAssertEqual(metric.name, "my_counter") - XCTAssertEqual(metric.type, .LongSum) - XCTAssertEqual(data.value, 5) - XCTAssertEqual(data.attributes["label_one"]?.description, "value") - } - - // MARK: - Test Metric: Gauge - - func testGauge() throws { - let gauge = Gauge(label: "my_gauge") - gauge.record(100) - - waitForExpectations(timeout: 10, handler: nil) - - let metric = stableMetrics[0] - let data = try XCTUnwrap(metric.data.points.last as? DoublePointData) - XCTAssertEqual(metric.name, "my_gauge") - XCTAssertEqual(metric.type, .DoubleGauge) - XCTAssertEqual(data.value, 100) - XCTAssertNil(data.attributes["label_one"]) - } - - // MARK: - Test Metric: Histogram - - func testHistogram() throws { - let histogram = Gauge(label: "my_histogram", dimensions: [], aggregate: true) - histogram.record(100) - - waitForExpectations(timeout: 10, handler: nil) - - let metric = stableMetrics[0] - let data = try XCTUnwrap(metric.data.points.last as? HistogramPointData) - XCTAssertEqual(metric.name, "my_histogram") - XCTAssertEqual(metric.type, .Histogram) -// XCTAssertEqual(/*data*/., 100) - XCTAssertNil(data.attributes["label_one"]) - } - - // MARK: - Test Metric: Summary - - func testSummary() throws { - let timer = CoreMetrics.Timer(label: "my_timer") - timer.recordSeconds(1) - - waitForExpectations(timeout: 10, handler: nil) - - let metric = stableMetrics[0] - let data = try XCTUnwrap(metric.data.points.last as? DoublePointData) - XCTAssertEqual(metric.name, "my_timer") - XCTAssertEqual(metric.type, .DoubleSum) - XCTAssertEqual(data.value, 1000000000) - XCTAssertNil(data.attributes["label_one"]) - } - - // MARK: - Test Concurrency - - func testConcurrency() throws { - DispatchQueue.concurrentPerform(iterations: 5) { _ in - let counter = Counter(label: "my_counter") - counter.increment() - } - - waitForExpectations(timeout: 10, handler: nil) - - let metric = stableMetrics[0] - let data = try XCTUnwrap(metric.data.points.last as? LongPointData) - XCTAssertEqual(metric.name, "my_counter") - XCTAssertEqual(metric.type, .LongSum) - XCTAssertEqual(data.value, 5) - XCTAssertNil(data.attributes["label_one"]) - } -} diff --git a/Tests/InstrumentationTests/NetworkStatusTests/NetworkStatusTests.swift b/Tests/InstrumentationTests/NetworkStatusTests/NetworkStatusTests.swift deleted file mode 100644 index 3e5e30aa..00000000 --- a/Tests/InstrumentationTests/NetworkStatusTests/NetworkStatusTests.swift +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#if os(iOS) && !targetEnvironment(macCatalyst) - import CoreTelephony - import Foundation - @testable import NetworkStatus - - import XCTest - - class MockNetworkMonitor: NetworkMonitorProtocol { - var connection: Connection - init(connection: Connection) { - self.connection = connection - } - - func getConnection() -> Connection { - return connection - } - } - - class MockCTTelephonyNetworkInfo: CTTelephonyNetworkInfo { - let dsi: String? - let ctc: CTCarrier? - let crt: String? - override var dataServiceIdentifier: String? { - dsi - } - - override var serviceSubscriberCellularProviders: [String: CTCarrier]? { - if let dataServiceidentifier = dsi, let carrier = ctc { - return [dataServiceidentifier: carrier] - } - return nil - } - - override var serviceCurrentRadioAccessTechnology: [String: String]? { - if let dataServiceIdentifier = dsi, let currentRadioTechnology = crt { - return [dataServiceIdentifier: currentRadioTechnology] - } - return nil - } - - override var currentRadioAccessTechnology: String? { - crt - } - - public init(dataServiceIndentifier: String?, currentRadioAccessTechnology: String?, carrier: CTCarrier?) { - dsi = dataServiceIndentifier - ctc = carrier - crt = currentRadioAccessTechnology - } - } - - class MockCTCarrier: CTCarrier { - let cn: String? - let iso: String? - let mcc: String? - let mnc: String? - - override var carrierName: String? { - cn - } - - override var isoCountryCode: String? { - iso - } - - override var mobileCountryCode: String? { - mcc - } - - override var mobileNetworkCode: String? { - mnc - } - - public init(carrierName: String?, isoCountryCode: String?, mobileCountryCode: String?, mobileNetworkCode: String?) { - cn = carrierName - iso = isoCountryCode - mcc = mobileCountryCode - mnc = mobileNetworkCode - } - } - - final class InstrumentorTests: XCTestCase { - func test() { - let wifi_status = NetworkStatus(with: MockNetworkMonitor(connection: .wifi)) - - var (type, subtype, info) = wifi_status.status() - - XCTAssertNil(info) - XCTAssertEqual("wifi", type) - - let cell_status = NetworkStatus(with: MockNetworkMonitor(connection: .cellular), - info: MockCTTelephonyNetworkInfo(dataServiceIndentifier: "blah", - currentRadioAccessTechnology: "CTRadioAccessTechnologyEdge", - carrier: MockCTCarrier(carrierName: "mobile-carrier", isoCountryCode: "1", mobileCountryCode: "120", mobileNetworkCode: "202"))) - - (type, subtype, info) = cell_status.status() - - XCTAssertNotNil(info) - XCTAssertEqual("mobile-carrier", info?.carrierName) - XCTAssertEqual("1", info?.isoCountryCode) - XCTAssertEqual("120", info?.mobileCountryCode) - XCTAssertEqual("202", info?.mobileNetworkCode) - XCTAssertEqual("cell", type) - XCTAssertEqual("EDGE", subtype) - - let unavailable = NetworkStatus(with: MockNetworkMonitor(connection: .unavailable)) - - (type, subtype, info) = unavailable.status() - - XCTAssertNil(info) - - XCTAssertEqual("unavailable", type) - } - - func testEdgeCases() { - let wifi_status = NetworkStatus(with: MockNetworkMonitor(connection: .wifi), info: MockCTTelephonyNetworkInfo(dataServiceIndentifier: nil, currentRadioAccessTechnology: nil, carrier: nil)) - - var (type, subtype, info) = wifi_status.status() - XCTAssertNil(info) - XCTAssertNil(subtype) - XCTAssertEqual("wifi", type) - - let cell_status = NetworkStatus(with: MockNetworkMonitor(connection: .cellular), info: MockCTTelephonyNetworkInfo(dataServiceIndentifier: nil, currentRadioAccessTechnology: nil, carrier: nil)) - - (type, subtype, info) = cell_status.status() - - XCTAssertNil(info) - XCTAssertEqual("cell", type) - - let unavailable_status = NetworkStatus(with: MockNetworkMonitor(connection: .unavailable), info: MockCTTelephonyNetworkInfo(dataServiceIndentifier: nil, currentRadioAccessTechnology: nil, carrier: nil)) - - (type, subtype, info) = unavailable_status.status() - - XCTAssertNil(info) - XCTAssertEqual("unavailable", type) - } - } - -#endif // os(iOS) && !targetEnvironment(macCatalyst) diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/ApplicationResourceProviderTests.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/ApplicationResourceProviderTests.swift deleted file mode 100644 index ebf122e5..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/ApplicationResourceProviderTests.swift +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ -import Foundation -import OpenTelemetrySdk -import XCTest - -@testable import ResourceExtension - -class ApplicationResourceProviderTests: XCTestCase { - func testContents() { - let appData = mockApplicationData(name: "appName", identifier: "com.bundle.id", version: "1.2.3", build: "9876") - - let provider = ApplicationResourceProvider(source: appData) as ResourceProvider - - let resource = provider.create() - - XCTAssertEqual(appData.name, resource.attributes[ResourceAttributes.serviceName.rawValue]?.description) - let versionDescription = resource.attributes[ResourceAttributes.serviceVersion.rawValue]?.description - - XCTAssertNotNil(versionDescription) - - XCTAssertTrue(versionDescription!.hasPrefix(appData.version!)) - XCTAssertTrue(versionDescription!.contains(appData.build!)) - } - - func testNoBundleVersion() { - let appData = mockApplicationData(name: "appName", identifier: "com.bundle.id", version: "1.2.3", build: nil) - - let provider = ApplicationResourceProvider(source: appData) as ResourceProvider - - let resource = provider.create() - - XCTAssertEqual(appData.name, resource.attributes[ResourceAttributes.serviceName.rawValue]?.description) - let versionDescription = resource.attributes[ResourceAttributes.serviceVersion.rawValue]?.description - - XCTAssertNotNil(versionDescription) - - XCTAssertEqual(versionDescription, appData.version) - } - - func testNoShortVersion() { - let appData = mockApplicationData(name: "appName", identifier: "com.bundle.id", version: nil, build: "3456") - - let provider = ApplicationResourceProvider(source: appData) as ResourceProvider - - let resource = provider.create() - - XCTAssertEqual(appData.name, resource.attributes[ResourceAttributes.serviceName.rawValue]?.description) - let versionDescription = resource.attributes[ResourceAttributes.serviceVersion.rawValue]?.description - - XCTAssertNotNil(versionDescription) - XCTAssertEqual(versionDescription, appData.build) - } - - func testNoAppData() { - let appData = mockApplicationData(name: nil, identifier: nil, version: nil, build: nil) - - let provider = ApplicationResourceProvider(source: appData) as ResourceProvider - - let resource = provider.create() - - XCTAssertEqual(resource.attributes.count, 0) - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/DeviceResourceProviderTests.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/DeviceResourceProviderTests.swift deleted file mode 100644 index 3a523112..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/DeviceResourceProviderTests.swift +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -@testable import ResourceExtension -import XCTest - -class DeviceResourceProviderTests: XCTestCase { - func testContents() { - let mock = MockDeviceDataSource(identifier: "00000-0000-000-00000000", model: "testPhone1,0") - let provider = DeviceResourceProvider(source: mock) - - let resource = provider.create() - - XCTAssertEqual(mock.model, resource.attributes[ResourceAttributes.deviceModelIdentifier.rawValue]?.description) - XCTAssertEqual(mock.identifier, resource.attributes[ResourceAttributes.deviceId.rawValue]?.description) - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockApplicationDataSource.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockApplicationDataSource.swift deleted file mode 100644 index 7f83eb56..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockApplicationDataSource.swift +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -@testable import ResourceExtension - -class mockApplicationData: IApplicationDataSource { - var name: String? - var identifier: String? - var version: String? - var build: String? - - init(name: String? = nil, identifier: String? = nil, version: String? = nil, build: String? = nil) { - self.name = name - self.identifier = identifier - self.version = version - self.build = build - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockDeviceDataSource.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockDeviceDataSource.swift deleted file mode 100644 index d1b3f863..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockDeviceDataSource.swift +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -@testable import ResourceExtension - -class MockDeviceDataSource: IDeviceDataSource { - var identifier: String? - var model: String? - - init(identifier: String?, model: String?) { - self.identifier = identifier - self.model = model - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockOperatingSystemDataSource.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockOperatingSystemDataSource.swift deleted file mode 100644 index a012f958..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockOperatingSystemDataSource.swift +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -@testable import ResourceExtension - -class MockOperatingSystemDataSource: IOperatingSystemDataSource { - private(set) var type: String - private(set) var description: String - private(set) var name: String - private(set) var version: String - - init(type: String, description: String, name: String, version: String) { - self.type = type - self.description = description - self.name = name - self.version = version - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockTelemetryDataSource.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockTelemetryDataSource.swift deleted file mode 100644 index bba7c154..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/Mocks/MockTelemetryDataSource.swift +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -@testable import ResourceExtension - -class MockTelemetryDataSource: ITelemetryDataSource { - var version: String? - var name: String - var language: String - - init(name: String, language: String, version: String?) { - self.version = version - self.name = name - self.language = language - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/OSResourceProviderTests.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/OSResourceProviderTests.swift deleted file mode 100644 index 38a063d0..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/OSResourceProviderTests.swift +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ -import Foundation - -import OpenTelemetrySdk -@testable import ResourceExtension -import XCTest - -#if canImport(UIKit) - - class OSResourceProviderTests: XCTestCase { - func testContents() { - let mock = MockOperatingSystemDataSource(type: "darwin", description: "iOS Version 15.0 (Build 19A339)", - name: "iOS", version: "15.0.2") - let provider = OSResourceProvider(source: mock) - - let resource = provider.create() - - XCTAssertEqual(mock.type, resource.attributes["os.type"]?.description) - XCTAssertEqual(mock.description, resource.attributes["os.description"]?.description) - XCTAssertEqual(mock.version, resource.attributes["os.version"]?.description) - XCTAssertEqual(mock.name, resource.attributes["os.name"]?.description) - } - } - -#endif // canImport(UIKit) diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/ResourcePropagationTests.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/ResourcePropagationTests.swift deleted file mode 100644 index 82ed0cb6..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/ResourcePropagationTests.swift +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ -import Foundation - -import OpenTelemetryApi -import OpenTelemetrySdk -@testable import ResourceExtension -import XCTest - -class ResourcePropagationTests: XCTestCase { - func testPropagation() { - let defaultResource = Resource() - let appProvider = ApplicationResourceProvider(source: ApplicationDataSource()) - let resultResource = DefaultResources().get() - - let defaultValue = defaultResource.attributes[ResourceAttributes.serviceName.rawValue]?.description - let resultValue = resultResource.attributes[ResourceAttributes.serviceName.rawValue]?.description - let applicationName = appProvider.attributes[ResourceAttributes.serviceName.rawValue]?.description - - XCTAssertNotNil(defaultValue) - XCTAssertNotNil(resultValue) - XCTAssertNotNil(applicationName) - XCTAssertEqual(resultValue, applicationName) - XCTAssertNotEqual(resultValue, defaultValue) - } -} diff --git a/Tests/InstrumentationTests/SDKResourceExtensionTests/TelemetryResourceProviderTests.swift b/Tests/InstrumentationTests/SDKResourceExtensionTests/TelemetryResourceProviderTests.swift deleted file mode 100644 index cae6ce14..00000000 --- a/Tests/InstrumentationTests/SDKResourceExtensionTests/TelemetryResourceProviderTests.swift +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import OpenTelemetryApi -import OpenTelemetrySdk -@testable import ResourceExtension -import XCTest - -class TelemetryResourceProviderTests: XCTestCase { - func testAll() { - let resources = DefaultResources().get() - print("\(resources)") - } - - func testContents() { - let mock = MockTelemetryDataSource(name: "testAgent", language: "swift", version: "1.2.3") - let provider = TelemetryResourceProvider(source: mock) - - let resource = provider.create() - - XCTAssertEqual(mock.name, resource.attributes["telemetry.sdk.name"]?.description) - XCTAssertEqual(mock.language, resource.attributes["telemetry.sdk.language"]?.description) - XCTAssertEqual(mock.version, resource.attributes["telemetry.sdk.version"]?.description) - } - - func testNils() { - let mock = MockTelemetryDataSource(name: "testAgent", language: "swift", version: nil) - let provider = TelemetryResourceProvider(source: mock) - - let resource = provider.create() - - XCTAssertEqual(mock.name, resource.attributes["telemetry.sdk.name"]?.description) - XCTAssertEqual(mock.language, resource.attributes["telemetry.sdk.language"]?.description) - XCTAssertNil(resource.attributes["telemetry.sdk.version"]) - } -} diff --git a/Tests/InstrumentationTests/URLSessionTests/URLSessionInstrumentationTests.swift b/Tests/InstrumentationTests/URLSessionTests/URLSessionInstrumentationTests.swift deleted file mode 100644 index d95b47ab..00000000 --- a/Tests/InstrumentationTests/URLSessionTests/URLSessionInstrumentationTests.swift +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@testable import OpenTelemetryApi -@testable import OpenTelemetrySdk -@testable import URLSessionInstrumentation -import XCTest - -class URLSessionInstrumentationTests: XCTestCase { - class Check { - public var shouldRecordPayloadCalled: Bool = false - public var shouldInstrumentCalled: Bool = false - public var nameSpanCalled: Bool = false - public var spanCustomizationCalled: Bool = false - public var shouldInjectTracingHeadersCalled: Bool = false - public var createdRequestCalled: Bool = false - public var receivedResponseCalled: Bool = false - public var receivedErrorCalled: Bool = false - } - - class SessionDelegate: NSObject, URLSessionDelegate, URLSessionDataDelegate { - var semaphore: DispatchSemaphore - - init(semaphore: DispatchSemaphore) { - self.semaphore = semaphore - } - - func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { - semaphore.signal() - } - - func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - semaphore.signal() - } - } - - class CountingSessionDelegate: NSObject, URLSessionDelegate, URLSessionDataDelegate { - var callCount: Int = 0 - - func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { - callCount += 1 - } - - func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - callCount += 1 - } - - func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { - callCount += 1 - } - } - - static var requestCopy: URLRequest! - static var responseCopy: HTTPURLResponse! - - static var activeBaggage: Baggage! - static var customBaggage: Baggage! - - static var config = URLSessionInstrumentationConfiguration(shouldRecordPayload: nil, - shouldInstrument: { req in - checker.shouldInstrumentCalled = true - if req.url?.path == "/dontinstrument" || req.url?.host == "dontinstrument.com" { - return false - } - return true - - }, - nameSpan: { req in - checker.nameSpanCalled = true - if req.url?.host?.contains("defaultName") ?? false { - return nil - } - return "new name" - }, - spanCustomization: { req, spanBuilder in - checker.spanCustomizationCalled = true - if !(req.url?.host?.contains("defaultName") ?? false) { - spanBuilder.setSpanKind(spanKind: .consumer) - } - }, - shouldInjectTracingHeaders: { _ in - checker.shouldInjectTracingHeadersCalled = true - return true - - }, - createdRequest: { request, _ in - requestCopy = request - checker.createdRequestCalled = true - }, - receivedResponse: { response, _, _ in - responseCopy = response as? HTTPURLResponse - checker.receivedResponseCalled = true - }, - receivedError: { _, _, _, _ in - URLSessionInstrumentationTests.checker.receivedErrorCalled = true - }, - baggageProvider: { _, _ in - customBaggage - }) - - static var checker = Check() - static var semaphore: DispatchSemaphore! - var sessionDelegate: SessionDelegate! - static var instrumentation: URLSessionInstrumentation! - - static let server = HttpTestServer(url: URL(string: "http://localhost:33333"), config: nil) - - override class func setUp() { - OpenTelemetry.registerPropagators(textPropagators: [W3CTraceContextPropagator()], baggagePropagator: W3CBaggagePropagator()) - OpenTelemetry.registerTracerProvider(tracerProvider: TracerProviderSdk()) - - customBaggage = DefaultBaggageManager.instance.baggageBuilder() - .put(key: EntryKey(name: "bar")!, value: EntryValue(string: "baz")!, metadata: nil) - .build() - - activeBaggage = DefaultBaggageManager.instance.baggageBuilder() - .put(key: EntryKey(name: "foo")!, value: EntryValue(string: "bar")!, metadata: nil) - .build() - - OpenTelemetry.instance.contextProvider.setActiveBaggage(activeBaggage) - - let sem = DispatchSemaphore(value: 0) - DispatchQueue.global(qos: .default).async { - do { - try server.start(semaphore: sem) - } catch { - XCTFail() - return - } - } - sem.wait() - instrumentation = URLSessionInstrumentation(configuration: config) - } - - override class func tearDown() { - server.stop() - customBaggage = nil - OpenTelemetry.instance.contextProvider.removeContextForBaggage(activeBaggage) - } - - override func setUp() { - URLSessionInstrumentationTests.checker = Check() - URLSessionInstrumentationTests.semaphore = DispatchSemaphore(value: 0) - sessionDelegate = SessionDelegate(semaphore: URLSessionInstrumentationTests.semaphore) - URLSessionInstrumentationTests.requestCopy = nil - URLSessionInstrumentationTests.responseCopy = nil - XCTAssertEqual(0, URLSessionInstrumentationTests.instrumentation.startedRequestSpans.count) - } - - override func tearDown() { - URLSessionLogger.runningSpansQueue.sync { - URLSessionLogger.runningSpans.removeAll() - } - XCTAssertEqual(0, URLSessionInstrumentationTests.instrumentation.startedRequestSpans.count) - } - - public func testOverrideSpanName() { - let request = URLRequest(url: URL(string: "http://google.com")!) - - URLSessionLogger.processAndLogRequest(request, sessionTaskId: "id", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - XCTAssertNotNil(URLSessionLogger.runningSpans["id"]) - if let span = URLSessionLogger.runningSpans["id"] { - XCTAssertEqual("new name", span.name) - } - } - - public func testDefaultSpanName() { - let request = URLRequest(url: URL(string: "http://defaultName.com")!) - - URLSessionLogger.processAndLogRequest(request, sessionTaskId: "id", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true) - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - XCTAssertNotNil(URLSessionLogger.runningSpans["id"]) - if let span = URLSessionLogger.runningSpans["id"] { - XCTAssertEqual("HTTP GET", span.name) - } - } - - public func testOverrideSpanCustomization() { - let request = URLRequest(url: URL(string: "http://google.com")!) - - URLSessionLogger.processAndLogRequest(request, sessionTaskId: "id", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - XCTAssertNotNil(URLSessionLogger.runningSpans["id"]) - if let span = URLSessionLogger.runningSpans["id"] { - XCTAssertEqual(SpanKind.consumer, span.kind) - } - } - - public func testDefaultSpanCustomization() { - let request = URLRequest(url: URL(string: "http://defaultName.com")!) - - URLSessionLogger.processAndLogRequest(request, sessionTaskId: "id", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true) - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - XCTAssertNotNil(URLSessionLogger.runningSpans["id"]) - if let span = URLSessionLogger.runningSpans["id"] { - XCTAssertEqual(SpanKind.client, span.kind) - } - } - - public func testConfigurationCallbacksCalledWhenSuccess() { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - let task = URLSession.shared.dataTask(with: request) { data, _, _ in - if let data { - let string = String(decoding: data, as: UTF8.self) - print(string) - } - URLSessionInstrumentationTests.semaphore.signal() - } - task.resume() - - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - } - - public func testConfigurationCallbacksCalledWhenForbidden() throws { - #if os(watchOS) - throw XCTSkip("Implementation needs to be updated for watchOS to make this test pass") - #endif - - let request = URLRequest(url: URL(string: "http://localhost:33333/forbidden")!) - let task = URLSession.shared.dataTask(with: request) { data, _, _ in - if let data { - let string = String(decoding: data, as: UTF8.self) - print(string) - } - URLSessionInstrumentationTests.semaphore.signal() - } - task.resume() - - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertFalse(URLSessionInstrumentationTests.checker.receivedErrorCalled) - } - - public func testConfigurationCallbacksCalledWhenError() { - let request = URLRequest(url: URL(string: "http://localhost:33333/error")!) - let semaphore = DispatchSemaphore(value: 0) - - let task = URLSession.shared.dataTask(with: request) { _, _, _ in - semaphore.signal() - } - task.resume() - - semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertFalse(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedErrorCalled) - } - - public func testShouldInstrumentRequest() throws { - let request1 = URLRequest(url: URL(string: "http://defaultName.com")!) - let request2 = URLRequest(url: URL(string: "http://dontinstrument.com")!) - - _ = try XCTUnwrap( - URLSessionLogger - .processAndLogRequest( - request1, - sessionTaskId: "111", - instrumentation: URLSessionInstrumentationTests.instrumentation, - shouldInjectHeaders: true - ) - ) - let processedRequest2 = URLSessionLogger.processAndLogRequest(request2, sessionTaskId: "222", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true) - - // `processedRequest2` is expected to be nil, because its URL was marked as not to be instrumented. - XCTAssertNil(processedRequest2) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - - let span = try XCTUnwrap(URLSessionLogger.runningSpans["111"]) - XCTAssertEqual("HTTP GET", span.name) - } - - public func testShouldInstrumentRequest_PropagateCombinedActiveAndCustomBaggages() throws { - let request1 = URLRequest(url: URL(string: "http://defaultName.com")!) - let request2 = URLRequest(url: URL(string: "http://dontinstrument.com")!) - - let processedRequest1 = try XCTUnwrap(URLSessionLogger.processAndLogRequest(request1, sessionTaskId: "111", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true)) - let processedRequest2 = URLSessionLogger.processAndLogRequest(request2, sessionTaskId: "222", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true) - - // `processedRequest2` is expected to be nil, because its URL was marked as not to be instrumented. - XCTAssertNil(processedRequest2) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - - let processedHeaders1 = try XCTUnwrap(processedRequest1.allHTTPHeaderFields) - - // headers injected from `TextMapPropagator` implementation - XCTAssertTrue(processedHeaders1.contains(where: { $0.key == W3CTraceContextPropagator.traceparent })) - - // headers injected from `TextMapBaggagePropagator` implementation - let baggageHeaderValue = try XCTUnwrap(processedHeaders1[W3CBaggagePropagator.headerBaggage]) - - // foo=bar propagated through active baggage defined in `setUp` - XCTAssertTrue(baggageHeaderValue.contains("foo=bar")) - - // bar=baz propagated through custom baggage provided in `URLSessionInstrumentationConfiguration` - XCTAssertTrue(baggageHeaderValue.contains("bar=baz")) - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - - let span = try XCTUnwrap(URLSessionLogger.runningSpans["111"]) - XCTAssertEqual("HTTP GET", span.name) - } - - public func testShouldInstrumentRequest_PropagateOnlyActiveBaggage() throws { - Self.customBaggage = nil - - let request1 = URLRequest(url: URL(string: "http://defaultName.com")!) - - let processedRequest1 = try XCTUnwrap(URLSessionLogger.processAndLogRequest(request1, sessionTaskId: "111", instrumentation: URLSessionInstrumentationTests.instrumentation, shouldInjectHeaders: true)) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - - let processedHeaders1 = try XCTUnwrap(processedRequest1.allHTTPHeaderFields) - - // headers injected from `TextMapPropagator` implementation - XCTAssertTrue(processedHeaders1.contains(where: { $0.key == W3CTraceContextPropagator.traceparent })) - - // headers injected from `TextMapBaggagePropagator` implementation - let baggageHeaderValue = try XCTUnwrap(processedHeaders1[W3CBaggagePropagator.headerBaggage]) - - // bar=baz propagated through default baggage provided in `URLSessionInstrumentationConfiguration` - XCTAssertEqual(baggageHeaderValue, "foo=bar") - - XCTAssertEqual(1, URLSessionLogger.runningSpans.count) - - let span = try XCTUnwrap(URLSessionLogger.runningSpans["111"]) - XCTAssertEqual("HTTP GET", span.name) - } - - public func testDataTaskWithRequestBlock() { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - let task = URLSession.shared.dataTask(with: request) { _, _, _ in - URLSessionInstrumentationTests.semaphore.signal() - } - - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - -#if os(watchOS) - XCTAssertEqual(1, URLSessionInstrumentationTests.instrumentation.startedRequestSpans.count) -#else - XCTAssertEqual(0, URLSessionInstrumentationTests.instrumentation.startedRequestSpans.count) -#endif - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDataTaskWithUrlBlock() { - let url = URL(string: "http://localhost:33333/success")! - - let task = URLSession.shared.dataTask(with: url) { _, _, _ in - URLSessionInstrumentationTests.semaphore.signal() - } - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDataTaskWithUrlBlock_doesNotCrashWhenResumed_whenDataTaskIsRunning() { - let url = URL(string: "http://localhost:33333/success")! - let dataTask = URLSession.shared.dataTask(with: url) { _, _, _ in - URLSessionInstrumentationTests.semaphore.signal() - } - - dataTask.resume() - Task.detached { - dataTask.resume() - } - - URLSessionInstrumentationTests.semaphore.wait() - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDownloadTaskWithUrlBlock() { - let url = URL(string: "http://localhost:33333/success")! - - let task = URLSession.shared.downloadTask(with: url) { _, _, _ in - URLSessionInstrumentationTests.semaphore.signal() - } - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testUploadTaskWithUrlBlock() { - let url = URL(string: "http://localhost:33333/success")! - var request = URLRequest(url: url) - request.httpMethod = "POST" - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.uploadTask( - with: request, - from: "UploadData".data(using: .utf8)! - ) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testUploadFileTaskWithUrlBlock() { - let url = URL(string: "http://localhost:33333/success")! - var request = URLRequest(url: url) - request.httpMethod = "POST" - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - - let task = session.uploadTask(with: URLRequest(url: url), fromFile: url) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDownloadTaskWithRequestBlock() { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - let task = URLSession.shared.downloadTask(with: request) { _, _, _ in - URLSessionInstrumentationTests.semaphore.signal() - } - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testUploadTaskWithRequestBlock() { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - let task = URLSession.shared.uploadTask(with: request, from: Data()) { _, _, _ in - URLSessionInstrumentationTests.semaphore.signal() - } - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDataTaskWithRequestDelegate() { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.dataTask(with: request) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDataTaskWithUrlDelegate() { - let url = URL(string: "http://localhost:33333/success")! - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.dataTask(with: url) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDownloadTaskWithUrlDelegate() { - let url = URL(string: "http://localhost:33333/success")! - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.downloadTask(with: url) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testDownloadTaskWithRequestDelegate() { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.downloadTask(with: request) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testUploadTaskWithRequestDelegate() { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.uploadTask(with: request, from: Data()) - task.resume() - URLSessionInstrumentationTests.semaphore.wait() - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testConfigurationCallbacksCalledWhenSuccessAsync() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - let (data, _) = try await URLSession.shared.data(for: request) - let string = String(decoding: data, as: UTF8.self) - print(string) - - // Note: These tests were passing incorrectly. The async/await methods - // introduced in iOS 15/macOS 12 are NOT instrumented at all, which is what - // testAsyncAwaitMethodsAreNotInstrumented demonstrates. - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testConfigurationCallbacksCalledWhenForbiddenAsync() async throws { - #if os(watchOS) - throw XCTSkip("Implementation needs to be updated for watchOS to make this test pass") - #endif - let request = URLRequest(url: URL(string: "http://localhost:33333/forbidden")!) - let (data, _) = try await URLSession.shared.data(for: request) - let string = String(decoding: data, as: UTF8.self) - print(string) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertFalse(URLSessionInstrumentationTests.checker.receivedErrorCalled) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testConfigurationCallbacksCalledWhenErrorAsync() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/error")!) - - do { - _ = try await URLSession.shared.data(for: request) - } catch {} - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.nameSpanCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.spanCustomizationCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertFalse(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedErrorCalled) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testDataTaskWithRequestBlockAsync() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - _ = try await URLSession.shared.data(for: request) - -#if os(watchOS) - XCTAssertEqual(1, URLSessionInstrumentationTests.instrumentation.startedRequestSpans.count) -#else - XCTAssertEqual(0, URLSessionInstrumentationTests.instrumentation.startedRequestSpans.count) -#endif - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testDataTaskWithUrlBlockAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - - _ = try await URLSession.shared.data(from: url) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 12, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testDownloadTaskWithUrlBlockAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - - _ = try await URLSession.shared.download(from: url) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 12, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testDownloadTaskWithRequestBlockAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - _ = try await URLSession.shared.download(for: request) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testUploadTaskWithRequestBlockAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - _ = try await URLSession.shared.upload(for: request, from: Data()) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func - testDataTaskWithRequestDelegateAsync() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - let delegate = CountingSessionDelegate() - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: delegate, delegateQueue: nil) - let _ = try await session.data(for: request) - - XCTAssertEqual(1, delegate.callCount) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func - testDataTaskWithTaskDelegateAsync() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - let delegate = CountingSessionDelegate() - - let session = URLSession(configuration: URLSessionConfiguration.default) - let _ = try await session.data(for: request, delegate: delegate) - - XCTAssertEqual(1, delegate.callCount) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testDataTaskWithUrlDelegateAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - _ = try await session.data(from: url) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 12, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testDownloadTaskWithUrlDelegateAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - - _ = try await URLSession.shared.download(from: url, delegate: sessionDelegate) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 12, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testDownloadTaskWithSessionDelegateAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - _ = try await session.download(for: request) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 12, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testDownloadTaskWithRequestDelegateAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - let session = URLSession(configuration: URLSessionConfiguration.default) - _ = try await session.download(for: request, delegate: sessionDelegate) - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testUploadTaskWithSessionDelegateAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - _ = try await session.upload(for: request, from: Data()) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - @available(macOS 10.15, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testUploadTaskWithRequestDelegateAsync() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - let session = URLSession(configuration: URLSessionConfiguration.default) - _ = try await session.upload(for: request, from: Data(), delegate: sessionDelegate) - - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled) - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent]) - } - - public func testNonInstrumentedRequestCompletes() { - let request = URLRequest(url: URL(string: "http://localhost:33333/dontinstrument")!) - let expectation = expectation(description: "Non-instrumented request completes") - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: sessionDelegate, delegateQueue: nil) - let task = session.dataTask(with: request) { _, response, error in - XCTAssertNil(error, "Non-instrumented request should not error") - XCTAssertNotNil(response, "Non-instrumented request should receive response") - if let httpResponse = response as? HTTPURLResponse { - XCTAssertEqual(httpResponse.statusCode, 200, "Non-instrumented request should receive 200 OK") - } else { - XCTFail("Response should be HTTPURLResponse") - } - - // Verify that no instrumentation was added - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled, "shouldInstrument should be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.nameSpanCalled, "nameSpan should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.spanCustomizationCalled, "spanCustomization should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled, "shouldInjectTracingHeaders should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.createdRequestCalled, "createdRequest should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.receivedResponseCalled, "receivedResponse should not be called") - - // Verify the request wasn't modified - XCTAssertNil(URLSessionInstrumentationTests.requestCopy, "Request should not have been copied/modified") - XCTAssertEqual(0, URLSessionLogger.runningSpans.count, "No spans should be created for non-instrumented requests") - - expectation.fulfill() - } - task.resume() - - waitForExpectations(timeout: 5, handler: nil) - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testNonInstrumentedRequestCompletesAsync() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/dontinstrument")!) - - let configuration = URLSessionConfiguration.default - let session = URLSession(configuration: configuration, delegate: sessionDelegate, delegateQueue: nil) - - let (_, response) = try await session.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - XCTFail("Response should be HTTPURLResponse") - return - } - - XCTAssertEqual(httpResponse.statusCode, 200, "Non-instrumented request should receive 200 OK") - - // Verify that no instrumentation was added - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled, "shouldInstrument should be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.nameSpanCalled, "nameSpan should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.spanCustomizationCalled, "spanCustomization should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.shouldInjectTracingHeadersCalled, "shouldInjectTracingHeaders should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.createdRequestCalled, "createdRequest should not be called") - XCTAssertFalse(URLSessionInstrumentationTests.checker.receivedResponseCalled, "receivedResponse should not be called") - - // Verify the request wasn't modified - XCTAssertNil(URLSessionInstrumentationTests.requestCopy, "Request should not have been copied/modified") - XCTAssertEqual(0, URLSessionLogger.runningSpans.count, "No spans should be created for non-instrumented requests") - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testNonInstrumentedRequestCompletesAsync_NonTaskContext() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/dontinstrument")!) - - let configuration = URLSessionConfiguration.default - let session = URLSession(configuration: configuration, delegate: sessionDelegate, delegateQueue: nil) - - // Run in a detached task to ensure we're not in the main Task context - let task = Task.detached { - // Ensure we're not in a Task context by running on a background thread - await Task.yield() - let (_, response) = try await session.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - XCTFail("Response should be HTTPURLResponse") - return - } - - XCTAssertEqual(httpResponse.statusCode, 200, "Non-instrumented request should receive 200 OK") - } - - try await task.value - } - - @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) - public func testNonInstrumentedRequestCompletesAsync_ExplicitTaskContext() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/dontinstrument")!) - - let configuration = URLSessionConfiguration.default - let session = URLSession(configuration: configuration, delegate: sessionDelegate, delegateQueue: nil) - - // Run in an explicit task to ensure we're in a Task context - let task = Task { - let (_, response) = try await session.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - XCTFail("Response should be HTTPURLResponse") - return - } - - XCTAssertEqual(httpResponse.statusCode, 200, "Non-instrumented request should receive 200 OK") - } - - try await task.value - } - - @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testAsyncAwaitMethodsDoNotCompleteSpans() async throws { - let request = URLRequest(url: URL(string: "http://localhost:33333/success")!) - - // Test data(for:) method - the new async/await API introduced in iOS 15 - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - XCTFail("Response should be HTTPURLResponse") - return - } - - XCTAssertEqual(httpResponse.statusCode, 200, "Request should succeed") - XCTAssertNotNil(data, "Should receive data") - - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled, "receivedResponse should be called") - XCTAssertNotNil(URLSessionInstrumentationTests.requestCopy?.allHTTPHeaderFields?[W3CTraceContextPropagator.traceparent], "Headers are injected") - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled, "shouldInstrument should be called") - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled, "createdRequest should be called") - } - - @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testAsyncAwaitDownloadMethodsAreNotInstrumented() async throws { - let url = URL(string: "http://localhost:33333/success")! - - // Test download(from:) method - let (fileURL, response) = try await URLSession.shared.download(from: url) - - guard let httpResponse = response as? HTTPURLResponse else { - XCTFail("Response should be HTTPURLResponse") - return - } - - XCTAssertEqual(httpResponse.statusCode, 200, "Request should succeed") - XCTAssertNotNil(fileURL, "Should receive file URL") - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled, "shouldInstrument should be called") - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled, "createdRequest should be called") - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled, "receivedResponse should be called") - - // Clean up downloaded file - try? FileManager.default.removeItem(at: fileURL) - } - - @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) - public func testAsyncAwaitUploadMethodsAreNotInstrumented() async throws { - let url = URL(string: "http://localhost:33333/success")! - let request = URLRequest(url: url) - - // Test upload(for:from:) method - let (data, response) = try await URLSession.shared.upload(for: request, from: Data()) - - guard let httpResponse = response as? HTTPURLResponse else { - XCTFail("Response should be HTTPURLResponse") - return - } - - XCTAssertEqual(httpResponse.statusCode, 200, "Request should succeed") - XCTAssertNotNil(data, "Should receive response data") - - XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled, "shouldInstrument should be called") - XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled, "createdRequest should be called") - XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled, "receivedResponse should be called") - } -} diff --git a/Tests/InstrumentationTests/URLSessionTests/Utils/HttpTestServer.swift b/Tests/InstrumentationTests/URLSessionTests/Utils/HttpTestServer.swift deleted file mode 100644 index a59292b5..00000000 --- a/Tests/InstrumentationTests/URLSessionTests/Utils/HttpTestServer.swift +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import Foundation -import NIO -import NIOHTTP1 - -typealias GenericCallback = () -> Void - -struct HttpTestServerConfig { - var successCallback: GenericCallback? - var errorCallback: GenericCallback? -} - -class HttpTestServer { - private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - private var host: String - private var port: Int - - var config: HttpTestServerConfig? - - public init(url: URL?, config: HttpTestServerConfig?) { - host = url?.host ?? "localhost" - port = url?.port ?? 33333 - self.config = config - } - - public func start(semaphore: DispatchSemaphore) throws { - do { - let channel = try serverBootstrap.bind(host: host, port: port).wait() - print("Listening on \(String(describing: channel.localAddress))...") - semaphore.signal() - try channel.closeFuture.wait() - } catch { - throw error - } - } - - public func stop() { - do { - try group.syncShutdownGracefully() - } catch { - print("Error shutting down \(error.localizedDescription)") - exit(0) - } - print("Client connection closed") - } - - private var serverBootstrap: ServerBootstrap { - return ServerBootstrap(group: group) - // Specify backlog and enable SO_REUSEADDR for the server itself - .serverChannelOption(ChannelOptions.backlog, value: 256) - .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) - // Set the handlers that are appled to the accepted Channels - .childChannelInitializer { [weak self] channel in - // Ensure we don't read faster than we can write by adding the BackPressureHandler into the pipeline. - channel.pipeline.configureHTTPServerPipeline(withErrorHandling: true).flatMap { - channel.pipeline.addHandler(TestHTTPHandler(config: self?.config)) - } - } - - // Enable SO_REUSEADDR for the accepted Channels - .childChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) - .childChannelOption(ChannelOptions.maxMessagesPerRead, value: 1) - } - - private final class TestHTTPHandler: ChannelInboundHandler { - public typealias InboundIn = HTTPServerRequestPart - public typealias OutboundOut = HTTPServerResponsePart - - var config: HttpTestServerConfig? - - init(config: HttpTestServerConfig?) { - self.config = config - } - - public func channelRead(context: ChannelHandlerContext, data: NIOAny) { - let reqPart = unwrapInboundIn(data) - - switch reqPart { - case let .head(request): - if request.uri.unicodeScalars.starts(with: "/success".unicodeScalars) || - request.uri.unicodeScalars.starts(with: "/dontinstrument".unicodeScalars) { - let channel = context.channel - - let head = HTTPResponseHead(version: request.version, - status: .ok, - headers: HTTPHeaders([("Content-Length", "0")])) - let part = HTTPServerResponsePart.head(head) - _ = channel.write(part) - - config?.successCallback?() - - let endpart = HTTPServerResponsePart.end(nil) - _ = channel.writeAndFlush(endpart).flatMap { - channel.close() - } - break - } else if request.uri.unicodeScalars.starts(with: "/forbidden".unicodeScalars) { - let channel = context.channel - - let head = HTTPResponseHead(version: request.version, - status: .forbidden) - let part = HTTPServerResponsePart.head(head) - _ = channel.write(part) - - config?.errorCallback?() - - let endpart = HTTPServerResponsePart.end(nil) - _ = channel.writeAndFlush(endpart).flatMap { - channel.close() - } - break - } else if request.uri.unicodeScalars.starts(with: "/error".unicodeScalars) { - let channel = context.channel - config?.errorCallback?() - _ = channel.close() - break - } - case .body: - break - case .end: - break - } - } - - // Flush it out. This can make use of gathering writes if multiple buffers are pending - public func channelReadComplete(context: ChannelHandlerContext) { - context.flush() - } - - public func errorCaught(context: ChannelHandlerContext, error: Error) { - print("error: ", error) - - // As we are not really interested getting notified on success or failure we just pass nil as promise to - // reduce allocations. - context.close(promise: nil) - } - } -}