Skip to content

Commit c0cd7d3

Browse files
committed
expanded exporter APIs with explicitTimeout on force flush and shutdown
1 parent bf5f4ec commit c0cd7d3

File tree

45 files changed

+261
-214
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+261
-214
lines changed

Sources/Exporters/InMemory/InMemoryExporter.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class InMemoryExporter: SpanExporter {
1616
return finishedSpanItems
1717
}
1818

19-
public func export(spans: [SpanData]) -> SpanExporterResultCode {
19+
public func export(spans: [SpanData], explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
2020
guard isRunning else {
2121
return .failure
2222
}
@@ -25,7 +25,7 @@ public class InMemoryExporter: SpanExporter {
2525
return .success
2626
}
2727

28-
public func flush() -> SpanExporterResultCode {
28+
public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
2929
guard isRunning else {
3030
return .failure
3131
}
@@ -37,7 +37,7 @@ public class InMemoryExporter: SpanExporter {
3737
finishedSpanItems.removeAll()
3838
}
3939

40-
public func shutdown() {
40+
public func shutdown(explicitTimeout: TimeInterval?) {
4141
finishedSpanItems.removeAll()
4242
isRunning = false
4343
}

Sources/Exporters/Jaeger/JaegerSpanExporter.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ public class JaegerSpanExporter: SpanExporter {
1818
self.collectorAddress = collectorAddress
1919
}
2020

21-
public func export(spans: [SpanData]) -> SpanExporterResultCode {
21+
public func export(spans: [SpanData], explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
2222
var spanList = TList<Span>()
2323
spanList.append(contentsOf: Adapter.toJaeger(spans: spans))
2424
let batch = Batch(process: process, spans: spanList)
25-
let sender = Sender(host: collectorAddress)
25+
let sender = Sender(host: collectorAddress)
2626
let success = sender.sendBatch(batch: batch)
2727
return success ? SpanExporterResultCode.success : SpanExporterResultCode.failure
2828
}
2929

30-
public func flush() -> SpanExporterResultCode {
30+
public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
3131
return .success
3232
}
3333

34-
public func shutdown() {
34+
public func shutdown(explicitTimeout: TimeInterval?) {
3535
}
3636
}
3737

Sources/Exporters/OpenTelemetryProtocolGrpc/logs/OtlpLogExporter.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ public class OtlpLogExporter : LogRecordExporter {
4242
}
4343
}
4444

45-
public func export(logRecords: [ReadableLogRecord]) -> ExportResult {
45+
public func export(logRecords: [ReadableLogRecord], explicitTimeout: TimeInterval?) -> ExportResult {
4646
let logRequest = Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest.with { request in
4747
request.resourceLogs = LogRecordAdapter.toProtoResourceRecordLog(logRecordList: logRecords)
4848
}
49-
50-
if config.timeout > 0 {
51-
callOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(config.timeout.toNanoseconds)))
49+
let timeout = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, config.timeout)
50+
if timeout > 0 {
51+
callOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(timeout.toNanoseconds)))
5252
}
5353

5454

@@ -61,11 +61,11 @@ public class OtlpLogExporter : LogRecordExporter {
6161
}
6262
}
6363

64-
public func shutdown() {
64+
public func shutdown(explicitTimeout: TimeInterval?) {
6565
_ = channel.close()
6666
}
6767

68-
public func forceFlush() -> ExportResult {
68+
public func forceFlush(explicitTimeout: TimeInterval?) -> ExportResult {
6969
.success
7070
}
7171
}

Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceExporter.swift

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import OpenTelemetrySdk
1313
import OpenTelemetryProtocolExporterCommon
1414

1515
public class OtlpTraceExporter: SpanExporter {
16+
1617
let channel: GRPCChannel
1718
var traceClient: Opentelemetry_Proto_Collector_Trace_V1_TraceServiceNIOClient
1819
let config : OtlpConfiguration
@@ -38,31 +39,32 @@ public class OtlpTraceExporter: SpanExporter {
3839
}
3940
}
4041

41-
public func export(spans: [SpanData]) -> SpanExporterResultCode {
42-
let exportRequest = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with {
43-
$0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans)
44-
}
4542

46-
if config.timeout > 0 {
47-
callOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(config.timeout.toNanoseconds)))
48-
}
43+
public func export(spans: [SpanData], explicitTimeout: TimeInterval? = nil) -> SpanExporterResultCode {
44+
let exportRequest = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with {
45+
$0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans)
46+
}
47+
let timeout = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude, config.timeout)
48+
if timeout > 0 {
49+
callOptions.timeLimit = TimeLimit.timeout(TimeAmount.nanoseconds(Int64(timeout.toNanoseconds)))
50+
}
4951

50-
let export = traceClient.export(exportRequest, callOptions: callOptions)
52+
let export = traceClient.export(exportRequest, callOptions: callOptions)
5153

52-
do {
53-
// wait() on the response to stop the program from exiting before the response is received.
54-
_ = try export.response.wait()
55-
return .success
56-
} catch {
57-
return .failure
58-
}
59-
}
54+
do {
55+
// wait() on the response to stop the program from exiting before the response is received.
56+
_ = try export.response.wait()
57+
return .success
58+
} catch {
59+
return .failure
60+
}
61+
}
6062

61-
public func flush() -> SpanExporterResultCode {
63+
public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
6264
return .success
6365
}
6466

65-
public func shutdown() {
67+
public func shutdown(explicitTimeout: TimeInterval?) {
6668
_ = channel.close()
6769
}
6870
}

Sources/Exporters/OpenTelemetryProtocolGrpc/trace/OtlpTraceJsonExporter.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import OpenTelemetrySdk
88
import OpenTelemetryProtocolExporterCommon
99

1010
public class OtlpTraceJsonExporter: SpanExporter {
11+
1112

1213
// MARK: - Variables declaration
1314
private var exportedSpans = [OtlpSpan]()
@@ -18,7 +19,7 @@ public class OtlpTraceJsonExporter: SpanExporter {
1819
exportedSpans
1920
}
2021

21-
public func export(spans: [SpanData]) -> SpanExporterResultCode {
22+
public func export(spans: [SpanData], explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
2223
guard isRunning else { return .failure }
2324

2425
let exportRequest = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with {
@@ -39,7 +40,7 @@ public class OtlpTraceJsonExporter: SpanExporter {
3940
}
4041
}
4142

42-
public func flush() -> SpanExporterResultCode {
43+
public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
4344
guard isRunning else { return .failure }
4445
return .success
4546
}
@@ -48,7 +49,7 @@ public class OtlpTraceJsonExporter: SpanExporter {
4849
exportedSpans.removeAll()
4950
}
5051

51-
public func shutdown() {
52+
public func shutdown(explicitTimeout: TimeInterval?) {
5253
exportedSpans.removeAll()
5354
isRunning = false
5455
}

Sources/Exporters/OpenTelemetryProtocolHttp/OtlpHttpExporterBase.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ import OpenTelemetryProtocolExporterCommon
1010
public class OtlpHttpExporterBase {
1111
let endpoint: URL
1212
let httpClient: HTTPClient
13-
14-
public init(endpoint: URL, useSession: URLSession? = nil) {
15-
self.endpoint = endpoint
13+
let envVarHeaders : [(String,String)]?
14+
15+
let config : OtlpConfiguration
16+
public init(endpoint: URL, config: OtlpConfiguration = OtlpConfiguration(), useSession: URLSession? = nil, envVarHeaders: [(String,String)]? = EnvVarHeaders.attributes) {
17+
self.envVarHeaders = envVarHeaders
18+
19+
self.endpoint = endpoint
20+
self.config = config
1621
if let providedSession = useSession {
1722
self.httpClient = HTTPClient(session: providedSession)
1823
} else {
@@ -35,6 +40,6 @@ public class OtlpHttpExporterBase {
3540
return request
3641
}
3742

38-
public func shutdown() {
43+
public func shutdown(explicitTimeout: TimeInterval?) {
3944
}
4045
}

Sources/Exporters/OpenTelemetryProtocolHttp/logs/OtlpHttpLogExporter.swift

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ public func defaultOltpHttpLoggingEndpoint() -> URL {
1212
}
1313

1414
public class OtlpHttpLogExporter : OtlpHttpExporterBase, LogRecordExporter {
15+
1516
var pendingLogRecords: [ReadableLogRecord] = []
1617

17-
override
18-
public init(endpoint: URL = defaultOltpHttpLoggingEndpoint(), useSession: URLSession? = nil) {
19-
super.init(endpoint: endpoint, useSession: useSession)
18+
override public init(endpoint: URL = defaultOltpHttpLoggingEndpoint(),
19+
config: OtlpConfiguration = OtlpConfiguration(),
20+
useSession: URLSession? = nil,
21+
envVarHeaders: [(String,String)]? = EnvVarHeaders.attributes){
22+
super.init(endpoint: endpoint, config: config, useSession: useSession, envVarHeaders: envVarHeaders)
2023
}
2124

22-
public func export(logRecords: [OpenTelemetrySdk.ReadableLogRecord]) -> OpenTelemetrySdk.ExportResult {
25+
public func export(logRecords: [OpenTelemetrySdk.ReadableLogRecord], explicitTimeout: TimeInterval? = nil) -> OpenTelemetrySdk.ExportResult {
2326
pendingLogRecords.append(contentsOf: logRecords)
2427
let sendingLogRecords = pendingLogRecords
2528
pendingLogRecords = []
@@ -28,7 +31,8 @@ public class OtlpHttpLogExporter : OtlpHttpExporterBase, LogRecordExporter {
2831
request.resourceLogs = LogRecordAdapter.toProtoResourceRecordLog(logRecordList: sendingLogRecords)
2932
}
3033

31-
let request = createRequest(body: body, endpoint: endpoint)
34+
var request = createRequest(body: body, endpoint: endpoint)
35+
request.timeoutInterval = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude , config.timeout)
3236
httpClient.send(request: request) { [weak self] result in
3337
switch result {
3438
case .success(_):
@@ -42,20 +46,21 @@ public class OtlpHttpLogExporter : OtlpHttpExporterBase, LogRecordExporter {
4246
return .success
4347
}
4448

45-
public func forceFlush() -> OpenTelemetrySdk.ExportResult {
46-
self.flush()
49+
public func forceFlush(explicitTimeout: TimeInterval? = nil) -> ExportResult {
50+
self.flush(explicitTimeout: explicitTimeout)
4751
}
4852

49-
public func flush() -> ExportResult {
53+
public func flush(explicitTimeout: TimeInterval? = nil) -> ExportResult {
5054
var exporterResult: ExportResult = .success
5155

5256
if !pendingLogRecords.isEmpty {
5357
let body = Opentelemetry_Proto_Collector_Logs_V1_ExportLogsServiceRequest.with { request in
5458
request.resourceLogs = LogRecordAdapter.toProtoResourceRecordLog(logRecordList: pendingLogRecords)
5559
}
5660
let semaphore = DispatchSemaphore(value: 0)
57-
let request = createRequest(body: body, endpoint: endpoint)
58-
61+
var request = createRequest(body: body, endpoint: endpoint)
62+
request.timeoutInterval = min(explicitTimeout ?? TimeInterval.greatestFiniteMagnitude , config.timeout)
63+
5964
httpClient.send(request: request) { result in
6065
switch result {
6166
case .success(_):

Sources/Exporters/OpenTelemetryProtocolHttp/metric/OltpHTTPMetricExporter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ public class OtlpHttpMetricExporter: OtlpHttpExporterBase, MetricExporter {
1515
var pendingMetrics: [Metric] = []
1616

1717
override
18-
public init(endpoint: URL = defaultOltpHTTPMetricsEndpoint(), useSession: URLSession? = nil) {
19-
super.init(endpoint: endpoint, useSession: useSession)
18+
public init(endpoint: URL = defaultOltpHTTPMetricsEndpoint(), config : OtlpConfiguration = OtlpConfiguration(), useSession: URLSession? = nil, envVarHeaders: [(String,String)]? = EnvVarHeaders.attributes) {
19+
super.init(endpoint: endpoint, config: config, useSession: useSession, envVarHeaders: envVarHeaders)
2020
}
2121

2222
public func export(metrics: [Metric], shouldCancel: (() -> Bool)?) -> MetricExporterResultCode {

Sources/Exporters/OpenTelemetryProtocolHttp/trace/OtlpHttpTraceExporter.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,34 @@ public func defaultOltpHttpTracesEndpoint() -> URL {
1212
}
1313

1414
public class OtlpHttpTraceExporter: OtlpHttpExporterBase, SpanExporter {
15-
var pendingSpans: [SpanData] = []
1615

16+
17+
var pendingSpans: [SpanData] = []
1718
override
18-
public init(endpoint: URL = defaultOltpHttpTracesEndpoint(), useSession: URLSession? = nil) {
19-
super.init(endpoint: endpoint, useSession: useSession)
19+
public init(endpoint: URL = defaultOltpHttpTracesEndpoint(), config: OtlpConfiguration = OtlpConfiguration(),
20+
useSession: URLSession? = nil, envVarHeaders: [(String,String)]? = EnvVarHeaders.attributes) {
21+
super.init(endpoint: endpoint, config: config, useSession: useSession)
2022
}
2123

22-
public func export(spans: [SpanData]) -> SpanExporterResultCode {
24+
public func export(spans: [SpanData], explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
2325
pendingSpans.append(contentsOf: spans)
2426
let sendingSpans = pendingSpans
2527
pendingSpans = []
2628

2729
let body = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with {
2830
$0.resourceSpans = SpanAdapter.toProtoResourceSpans(spanDataList: spans)
2931
}
30-
let request = createRequest(body: body, endpoint: endpoint)
32+
var request = createRequest(body: body, endpoint: endpoint)
33+
if let headers = envVarHeaders {
34+
headers.forEach { (key, value) in
35+
request.addValue(value, forHTTPHeaderField: key)
36+
}
37+
38+
} else if let headers = config.headers {
39+
headers.forEach { (key, value) in
40+
request.addValue(value, forHTTPHeaderField: key)
41+
}
42+
}
3143
httpClient.send(request: request) { [weak self] result in
3244
switch result {
3345
case .success:
@@ -40,7 +52,7 @@ public class OtlpHttpTraceExporter: OtlpHttpExporterBase, SpanExporter {
4052
return .success
4153
}
4254

43-
public func flush() -> SpanExporterResultCode {
55+
public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode {
4456
var resultValue: SpanExporterResultCode = .success
4557
if !pendingSpans.isEmpty {
4658
let body = Opentelemetry_Proto_Collector_Trace_V1_ExportTraceServiceRequest.with {

Sources/Exporters/Persistence/Export/DataExportWorker.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Foundation
88
// a protocol for an exporter of `Data` to which a `DataExportWorker` can delegate persisted
99
// data export
1010
internal protocol DataExporter {
11-
func export(data: Data) -> DataExportStatus
11+
func export(data: Data, explicitTimeout: TimeInterval?) -> DataExportStatus
1212
}
1313

1414
// a protocol needed for mocking `DataExportWorker`
@@ -52,7 +52,7 @@ internal class DataExportWorker: DataExportWorkerProtocol {
5252
let nextBatch = isSystemReady ? self.fileReader.readNextBatch() : nil
5353
if let batch = nextBatch {
5454
// Export batch
55-
let exportStatus = self.dataExporter.export(data: batch.data)
55+
let exportStatus = self.dataExporter.export(data: batch.data, explicitTimeout: nil)
5656

5757
// Delete or keep batch depending on the export status
5858
if exportStatus.needsRetry {
@@ -86,7 +86,7 @@ internal class DataExportWorker: DataExportWorkerProtocol {
8686
internal func flush() -> Bool {
8787
let success = queue.sync {
8888
self.fileReader.onRemainingBatches {
89-
let exportStatus = self.dataExporter.export(data: $0.data)
89+
let exportStatus = self.dataExporter.export(data: $0.data, explicitTimeout: nil)
9090
if !exportStatus.needsRetry {
9191
self.fileReader.markBatchAsRead($0)
9292
}

0 commit comments

Comments
 (0)