Skip to content

Commit 60f9260

Browse files
authored
Added data compression support for HTTP exporter (#631)
1 parent 0cd4a4c commit 60f9260

File tree

14 files changed

+386
-31
lines changed

14 files changed

+386
-31
lines changed

Package.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ let package = Package(
2929
.library(name: "DatadogExporter", type: .static, targets: ["DatadogExporter"]),
3030
.library(name: "NetworkStatus", type: .static, targets: ["NetworkStatus"]),
3131
.library(name: "OTelSwiftLog", type: .static, targets: ["OTelSwiftLog"]),
32+
.library(name: "DataCompression", type: .static, targets: ["DataCompression"]),
3233
.executable(name: "simpleExporter", targets: ["SimpleExporter"]),
3334
.executable(name: "OTLPExporter", targets: ["OTLPExporter"]),
3435
.executable(name: "OTLPHTTPExporter", targets: ["OTLPHTTPExporter"]),
@@ -110,14 +111,18 @@ let package = Package(
110111
"OpenTelemetryProtocolExporterCommon",
111112
.product(name: "GRPC", package: "grpc-swift")],
112113
path: "Sources/Exporters/OpenTelemetryProtocolGrpc"),
114+
.target(name: "DataCompression",
115+
dependencies: [],
116+
path: "Sources/Exporters/DataCompression"),
113117
.target(name: "StdoutExporter",
114118
dependencies: ["OpenTelemetrySdk"],
115119
path: "Sources/Exporters/Stdout"),
116120
.target(name: "InMemoryExporter",
117121
dependencies: ["OpenTelemetrySdk"],
118122
path: "Sources/Exporters/InMemory"),
119123
.target(name: "DatadogExporter",
120-
dependencies: ["OpenTelemetrySdk"],
124+
dependencies: ["OpenTelemetrySdk",
125+
"DataCompression"],
121126
path: "Sources/Exporters/DatadogExporter",
122127
exclude: ["NOTICE", "README.md"]),
123128
.target(name: "PersistenceExporter",
@@ -163,6 +168,7 @@ let package = Package(
163168
.testTarget(name: "OpenTelemetryProtocolExporterTests",
164169
dependencies: ["OpenTelemetryProtocolExporterGrpc",
165170
"OpenTelemetryProtocolExporterHttp",
171+
"DataCompression",
166172
.product(name: "NIO", package: "swift-nio"),
167173
.product(name: "NIOHTTP1", package: "swift-nio"),
168174
.product(name: "NIOTestUtils", package: "swift-nio")],
@@ -190,7 +196,7 @@ let package = Package(
190196
path: "Examples/OTLP Exporter",
191197
exclude: ["README.md"]),
192198
.target(name: "OTLPHTTPExporter",
193-
dependencies: ["OpenTelemetryProtocolExporterHttp", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration"],
199+
dependencies: ["OpenTelemetryProtocolExporterHttp", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration", "DataCompression"],
194200
path: "Examples/OTLP HTTP Exporter",
195201
exclude: ["README.md"]),
196202
.target(name: "PrometheusSample",

[email protected]

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ let package = Package(
3030
.library(name: "DatadogExporter", type: .static, targets: ["DatadogExporter"]),
3131
.library(name: "NetworkStatus", type: .static, targets: ["NetworkStatus"]),
3232
.library(name: "OTelSwiftLog", type: .static, targets: ["OTelSwiftLog"]),
33+
.library(name: "DataCompression", type: .static, targets: ["DataCompression"]),
3334
.executable(name: "simpleExporter", targets: ["SimpleExporter"]),
3435
.executable(name: "OTLPExporter", targets: ["OTLPExporter"]),
3536
.executable(name: "OTLPHTTPExporter", targets: ["OTLPHTTPExporter"]),
@@ -115,14 +116,18 @@ let package = Package(
115116
"OpenTelemetryProtocolExporterCommon",
116117
.product(name: "GRPC", package: "grpc-swift")],
117118
path: "Sources/Exporters/OpenTelemetryProtocolGrpc"),
119+
.target(name: "DataCompression",
120+
dependencies: [],
121+
path: "Sources/Exporters/DataCompression"),
118122
.target(name: "StdoutExporter",
119123
dependencies: ["OpenTelemetrySdk"],
120124
path: "Sources/Exporters/Stdout"),
121125
.target(name: "InMemoryExporter",
122126
dependencies: ["OpenTelemetrySdk"],
123127
path: "Sources/Exporters/InMemory"),
124128
.target(name: "DatadogExporter",
125-
dependencies: ["OpenTelemetrySdk"],
129+
dependencies: ["OpenTelemetrySdk",
130+
"DataCompression"],
126131
path: "Sources/Exporters/DatadogExporter",
127132
exclude: ["NOTICE", "README.md"]),
128133
.target(name: "PersistenceExporter",
@@ -173,6 +178,7 @@ let package = Package(
173178
.testTarget(name: "OpenTelemetryProtocolExporterTests",
174179
dependencies: ["OpenTelemetryProtocolExporterGrpc",
175180
"OpenTelemetryProtocolExporterHttp",
181+
"DataCompression",
176182
.product(name: "NIO", package: "swift-nio"),
177183
.product(name: "NIOHTTP1", package: "swift-nio"),
178184
.product(name: "NIOTestUtils", package: "swift-nio")],
@@ -207,7 +213,7 @@ let package = Package(
207213
),
208214
.executableTarget(
209215
name: "OTLPHTTPExporter",
210-
dependencies: ["OpenTelemetrySdk", "OpenTelemetryProtocolExporterHttp", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration"],
216+
dependencies: ["OpenTelemetrySdk", "OpenTelemetryProtocolExporterHttp", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration", "DataCompression"],
211217
path: "Examples/OTLP HTTP Exporter",
212218
exclude: ["README.md"]
213219
),

[email protected]

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ let package = Package(
2323
.library(name: "PersistenceExporter", targets: ["PersistenceExporter"]),
2424
.library(name: "InMemoryExporter", targets: ["InMemoryExporter"]),
2525
.library(name: "OTelSwiftLog", targets: ["OTelSwiftLog"]),
26+
.library(name: "DataCompression", type: .static, targets: ["DataCompression"]),
2627
.executable(name: "ConcurrencyContext", targets: ["ConcurrencyContext"]),
2728
.executable(name: "loggingTracer", targets: ["LoggingTracer"]),
2829
],
@@ -70,6 +71,9 @@ let package = Package(
7071
"OpenTelemetryProtocolExporterCommon",
7172
.product(name: "GRPC", package: "grpc-swift")],
7273
path: "Sources/Exporters/OpenTelemetryProtocolGrpc"),
74+
.target(name: "DataCompression",
75+
dependencies: [],
76+
path: "Sources/Exporters/DataCompression"),
7377
.target(name: "StdoutExporter",
7478
dependencies: ["OpenTelemetrySdk"],
7579
path: "Sources/Exporters/Stdout"),
@@ -100,6 +104,7 @@ let package = Package(
100104
.testTarget(name: "OpenTelemetryProtocolExporterTests",
101105
dependencies: ["OpenTelemetryProtocolExporterGrpc",
102106
"OpenTelemetryProtocolExporterHttp",
107+
"DataCompression",
103108
.product(name: "NIO", package: "swift-nio"),
104109
.product(name: "NIOHTTP1", package: "swift-nio"),
105110
.product(name: "NIOTestUtils", package: "swift-nio")],
@@ -240,7 +245,7 @@ extension Package {
240245
),
241246
.executableTarget(
242247
name: "OTLPHTTPExporter",
243-
dependencies: ["OpenTelemetrySdk", "OpenTelemetryProtocolExporterHttp", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration"],
248+
dependencies: ["OpenTelemetrySdk", "OpenTelemetryProtocolExporterHttp", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration", "DataCompression"],
244249
path: "Examples/OTLP HTTP Exporter",
245250
exclude: ["README.md"]
246251
),
@@ -256,7 +261,8 @@ extension Package {
256261
dependencies: ["ResourceExtension", "OpenTelemetrySdk"],
257262
path: "Tests/InstrumentationTests/SDKResourceExtensionTests"),
258263
.target(name: "DatadogExporter",
259-
dependencies: ["OpenTelemetrySdk"],
264+
dependencies: ["OpenTelemetrySdk",
265+
"DataCompression"],
260266
path: "Sources/Exporters/DatadogExporter",
261267
exclude: ["NOTICE", "README.md"]),
262268
.testTarget(name: "DatadogExporterTests",
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828

2929

3030
import Foundation
31+
32+
#if canImport(Compression)
3133
import Compression
3234

33-
extension Data
35+
public extension Data
3436
{
3537
/// Compresses the data.
3638
/// - parameter withAlgorithm: Compression algorithm to use. See the `CompressionAlgorithm` type
@@ -247,7 +249,7 @@ extension Data
247249

248250
/// Calculate the Adler32 checksum of the data.
249251
/// - returns: Adler32 checksum type. Can still be further advanced.
250-
func adler32() -> Adler32
252+
internal func adler32() -> Adler32
251253
{
252254
var res = Adler32()
253255
res.advance(withChunk: self)
@@ -256,7 +258,7 @@ extension Data
256258

257259
/// Calculate the Crc32 checksum of the data.
258260
/// - returns: Crc32 checksum type. Can still be further advanced.
259-
func crc32() -> Crc32
261+
internal func crc32() -> Crc32
260262
{
261263
var res = Crc32()
262264
res.advance(withChunk: self)
@@ -514,3 +516,4 @@ fileprivate func perform(_ config: Config, source: UnsafePointer<UInt8>, sourceS
514516
}
515517
}
516518
}
519+
#endif

Sources/Exporters/DatadogExporter/Upload/RequestBuilder.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6+
#if canImport(Compression)
7+
import DataCompression
8+
#endif
69
import Foundation
710

811
/// Builds `URLRequest` for sending data to Datadog.

Sources/Exporters/OpenTelemetryProtocolCommon/common/OtlpConfiguration.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55

66
import Foundation
77

8+
public enum CompressionType {
9+
case gzip
10+
case deflate
11+
case none
12+
}
13+
814
public struct OtlpConfiguration {
915
public static let DefaultTimeoutInterval : TimeInterval = TimeInterval(10)
1016

@@ -23,9 +29,15 @@ public struct OtlpConfiguration {
2329
// let compression
2430
public let headers : [(String,String)]?
2531
public let timeout : TimeInterval
32+
public let compression: CompressionType
2633

27-
public init(timeout : TimeInterval = OtlpConfiguration.DefaultTimeoutInterval, headers: [(String,String)]? = nil) {
34+
public init(
35+
timeout : TimeInterval = OtlpConfiguration.DefaultTimeoutInterval,
36+
compression: CompressionType = .gzip,
37+
headers: [(String,String)]? = nil
38+
) {
2839
self.headers = headers
2940
self.timeout = timeout
41+
self.compression = compression
3042
}
3143
}

Sources/Exporters/OpenTelemetryProtocolHttp/OtlpHttpExporterBase.swift

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// SPDX-License-Identifier: Apache-2.0
44
//
55

6+
#if canImport(Compression)
7+
import DataCompression
8+
#endif
69
import Foundation
710
import SwiftProtobuf
811
import OpenTelemetryProtocolExporterCommon
@@ -28,20 +31,44 @@ public class OtlpHttpExporterBase {
2831
}
2932
}
3033

31-
public func createRequest(body: Message, endpoint: URL) -> URLRequest {
32-
var request = URLRequest(url: endpoint)
33-
34-
do {
35-
request.httpMethod = "POST"
36-
request.httpBody = try body.serializedData()
37-
request.setValue(Headers.getUserAgentHeader(), forHTTPHeaderField: Constants.HTTP.userAgent)
38-
request.setValue("application/x-protobuf", forHTTPHeaderField: "Content-Type")
39-
} catch {
40-
print("Error serializing body: \(error)")
34+
public func createRequest(body: Message, endpoint: URL) -> URLRequest {
35+
var request = URLRequest(url: endpoint)
36+
37+
do {
38+
let rawData = try body.serializedData()
39+
request.httpMethod = "POST"
40+
request.setValue(Headers.getUserAgentHeader(), forHTTPHeaderField: Constants.HTTP.userAgent)
41+
request.setValue("application/x-protobuf", forHTTPHeaderField: "Content-Type")
42+
43+
var compressedData = rawData
44+
45+
#if canImport(Compression)
46+
switch config.compression {
47+
case .gzip:
48+
if let data = rawData.gzip() {
49+
compressedData = data
50+
request.setValue("gzip", forHTTPHeaderField: "Content-Encoding")
51+
}
52+
53+
case .deflate:
54+
if let data = rawData.deflate() {
55+
compressedData = data
56+
request.setValue("deflate", forHTTPHeaderField: "Content-Encoding")
57+
}
58+
59+
case .none:
60+
break
61+
}
62+
#endif
63+
// Apply final data. Could be compressed or raw
64+
// but it doesn't matter here
65+
request.httpBody = compressedData
66+
} catch {
67+
print("Error serializing body: \(error)")
68+
}
69+
70+
return request
4171
}
42-
43-
return request
44-
}
4572

4673
public func shutdown(explicitTimeout: TimeInterval? = nil) {
4774

Sources/Exporters/OpenTelemetryProtocolHttp/StableOtlpHTTPExporterBase.swift

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// SPDX-License-Identifier: Apache-2.0
44
//
55

6+
#if canImport(Compression)
7+
import DataCompression
8+
#endif
69
import Foundation
710
import OpenTelemetryProtocolExporterCommon
811
import SwiftProtobuf
@@ -44,14 +47,38 @@ public class StableOtlpHTTPExporterBase {
4447
}
4548

4649
do {
50+
let rawData = try body.serializedData()
4751
request.httpMethod = "POST"
48-
request.httpBody = try body.serializedData()
4952
request.setValue(Headers.getUserAgentHeader(), forHTTPHeaderField: Constants.HTTP.userAgent)
5053
request.setValue("application/x-protobuf", forHTTPHeaderField: "Content-Type")
54+
55+
var compressedData = rawData
56+
57+
#if canImport(Compression)
58+
switch config.compression {
59+
case .gzip:
60+
if let data = rawData.gzip() {
61+
compressedData = data
62+
request.setValue("gzip", forHTTPHeaderField: "Content-Encoding")
63+
}
64+
65+
case .deflate:
66+
if let data = rawData.deflate() {
67+
compressedData = data
68+
request.setValue("deflate", forHTTPHeaderField: "Content-Encoding")
69+
}
70+
71+
case .none:
72+
break
73+
}
74+
#endif
75+
76+
// Apply final data. Could be compressed or raw
77+
// but it doesn't matter here
78+
request.httpBody = compressedData
5179
} catch {
5280
print("Error serializing body: \(error)")
5381
}
54-
5582
return request
5683
}
5784

0 commit comments

Comments
 (0)