Skip to content

Commit 406e31b

Browse files
authored
zstd compression for tonic exporter (#1947)
1 parent a1f02fa commit 406e31b

File tree

4 files changed

+43
-4
lines changed

4 files changed

+43
-4
lines changed

opentelemetry-otlp/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ default = ["grpc-tonic", "trace", "metrics", "logs"]
6565
# grpc using tonic
6666
grpc-tonic = ["tonic", "prost", "http", "tokio", "opentelemetry-proto/gen-tonic"]
6767
gzip-tonic = ["tonic/gzip"]
68+
zstd-tonic = ["tonic/zstd"]
6869
tls = ["tonic/tls"]
6970
tls-roots = ["tls", "tonic/tls-roots"]
7071
tls-webpki-roots = ["tls", "tonic/tls-webpki-roots"]

opentelemetry-otlp/src/exporter/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,15 @@ impl Default for ExportConfig {
9898
pub enum Compression {
9999
/// Compresses data using gzip.
100100
Gzip,
101+
/// Compresses data using zstd.
102+
Zstd,
101103
}
102104

103105
impl Display for Compression {
104106
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
105107
match self {
106108
Compression::Gzip => write!(f, "gzip"),
109+
Compression::Zstd => write!(f, "zstd"),
107110
}
108111
}
109112
}
@@ -114,6 +117,7 @@ impl FromStr for Compression {
114117
fn from_str(s: &str) -> Result<Self, Self::Err> {
115118
match s {
116119
"gzip" => Ok(Compression::Gzip),
120+
"zstd" => Ok(Compression::Zstd),
117121
_ => Err(Error::UnsupportedCompressionAlgorithm(s.to_string())),
118122
}
119123
}

opentelemetry-otlp/src/exporter/tonic/mod.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,16 @@ impl TryFrom<Compression> for tonic::codec::CompressionEncoding {
5252
#[cfg(feature = "gzip-tonic")]
5353
Compression::Gzip => Ok(tonic::codec::CompressionEncoding::Gzip),
5454
#[cfg(not(feature = "gzip-tonic"))]
55-
Compression::Gzip => Err(crate::Error::UnsupportedCompressionAlgorithm(
56-
value.to_string(),
55+
Compression::Gzip => Err(crate::Error::FeatureRequiredForCompressionAlgorithm(
56+
"gzip-tonic",
57+
Compression::Gzip,
58+
)),
59+
#[cfg(feature = "zstd-tonic")]
60+
Compression::Zstd => Ok(tonic::codec::CompressionEncoding::Zstd),
61+
#[cfg(not(feature = "zstd-tonic"))]
62+
Compression::Zstd => Err(crate::Error::FeatureRequiredForCompressionAlgorithm(
63+
"zstd-tonic",
64+
Compression::Zstd,
5765
)),
5866
}
5967
}
@@ -399,7 +407,7 @@ fn parse_headers_from_env(signal_headers_var: &str) -> HeaderMap {
399407
#[cfg(test)]
400408
mod tests {
401409
use crate::exporter::tests::run_env_test;
402-
#[cfg(feature = "gzip-tonic")]
410+
#[cfg(feature = "grpc-tonic")]
403411
use crate::exporter::Compression;
404412
use crate::TonicExporterBuilder;
405413
use crate::{OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TRACES_HEADERS};
@@ -438,14 +446,34 @@ mod tests {
438446

439447
#[test]
440448
#[cfg(feature = "gzip-tonic")]
441-
fn test_with_compression() {
449+
fn test_with_gzip_compression() {
442450
// metadata should merge with the current one with priority instead of just replacing it
443451
let mut metadata = MetadataMap::new();
444452
metadata.insert("foo", "bar".parse().unwrap());
445453
let builder = TonicExporterBuilder::default().with_compression(Compression::Gzip);
446454
assert_eq!(builder.tonic_config.compression.unwrap(), Compression::Gzip);
447455
}
448456

457+
#[test]
458+
#[cfg(feature = "zstd-tonic")]
459+
fn test_with_zstd_compression() {
460+
let builder = TonicExporterBuilder::default().with_compression(Compression::Zstd);
461+
assert_eq!(builder.tonic_config.compression.unwrap(), Compression::Zstd);
462+
}
463+
464+
#[test]
465+
#[cfg(feature = "grpc-tonic")]
466+
fn test_convert_compression() {
467+
#[cfg(feature = "gzip-tonic")]
468+
assert!(tonic::codec::CompressionEncoding::try_from(Compression::Gzip).is_ok());
469+
#[cfg(not(feature = "gzip-tonic"))]
470+
assert!(tonic::codec::CompressionEncoding::try_from(Compression::Gzip).is_err());
471+
#[cfg(feature = "zstd-tonic")]
472+
assert!(tonic::codec::CompressionEncoding::try_from(Compression::Zstd).is_ok());
473+
#[cfg(not(feature = "zstd-tonic"))]
474+
assert!(tonic::codec::CompressionEncoding::try_from(Compression::Zstd).is_err());
475+
}
476+
449477
#[test]
450478
fn test_parse_headers_from_env() {
451479
run_env_test(

opentelemetry-otlp/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
//! For users uses `tonic` as grpc layer:
9898
//! * `grpc-tonic`: Use `tonic` as grpc layer. This is enabled by default.
9999
//! * `gzip-tonic`: Use gzip compression for `tonic` grpc layer.
100+
//! * `zstd-tonic`: Use zstd compression for `tonic` grpc layer.
100101
//! * `tls-tonic`: Enable TLS.
101102
//! * `tls-roots`: Adds system trust roots to rustls-based gRPC clients using the rustls-native-certs crate
102103
//! * `tls-webkpi-roots`: Embeds Mozilla's trust roots to rustls-based gRPC clients using the webkpi-roots crate
@@ -372,6 +373,11 @@ pub enum Error {
372373
/// Unsupported compression algorithm.
373374
#[error("unsupported compression algorithm '{0}'")]
374375
UnsupportedCompressionAlgorithm(String),
376+
377+
/// Feature required to use the specified compression algorithm.
378+
#[cfg(any(not(feature = "gzip-tonic"), not(feature = "zstd-tonic")))]
379+
#[error("feature '{0}' is required to use the compression algorithm '{1}'")]
380+
FeatureRequiredForCompressionAlgorithm(&'static str, Compression),
375381
}
376382

377383
#[cfg(feature = "grpc-tonic")]

0 commit comments

Comments
 (0)