Skip to content

Commit cfb53e9

Browse files
shuheiktgwguilload
andauthored
Support configurable OTLP exporter protocol for traces and logs (#6254)
* Support configurable OTLP exporter protocol for traces and logs * Refactor --------- Co-authored-by: Adrien Guillo <adrien.guillo@datadoghq.com>
1 parent 0b69ddd commit cfb53e9

File tree

6 files changed

+124
-13
lines changed

6 files changed

+124
-13
lines changed

LICENSE-3rdparty.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ concurrent-queue,https://github.com/smol-rs/concurrent-queue,Apache-2.0 OR MIT,"
154154
console,https://github.com/console-rs/console,MIT,The console Authors
155155
console-api,https://github.com/tokio-rs/console,MIT,"Eliza Weisman <eliza@buoyant.io>, Tokio Contributors <team@tokio.rs>"
156156
console-subscriber,https://github.com/tokio-rs/console,MIT,"Eliza Weisman <eliza@buoyant.io>, Tokio Contributors <team@tokio.rs>"
157+
const-hex,https://github.com/danipopes/const-hex,MIT OR Apache-2.0,DaniPopes <57450786+DaniPopes@users.noreply.github.com>
157158
const-oid,https://github.com/RustCrypto/formats/tree/master/const-oid,Apache-2.0 OR MIT,RustCrypto Developers
158159
const-random,https://github.com/tkaitchuck/constrandom,MIT OR Apache-2.0,Tom Kaitchuck <Tom.Kaitchuck@gmail.com>
159160
const-random-macro,https://github.com/tkaitchuck/constrandom,MIT OR Apache-2.0,Tom Kaitchuck <Tom.Kaitchuck@gmail.com>
@@ -545,6 +546,7 @@ proc-macro2-diagnostics,https://github.com/SergioBenitez/proc-macro2-diagnostics
545546
procfs,https://github.com/eminence/procfs,MIT OR Apache-2.0,Andrew Chin <achin@eminence32.net>
546547
procfs-core,https://github.com/eminence/procfs,MIT OR Apache-2.0,Andrew Chin <achin@eminence32.net>
547548
prometheus,https://github.com/tikv/rust-prometheus,Apache-2.0,"overvenus@gmail.com, siddontang@gmail.com, vistaswx@gmail.com"
549+
proptest,https://github.com/proptest-rs/proptest,MIT OR Apache-2.0,Jason Lingle
548550
prost,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert <dan@danburkert.com>, Lucio Franco <luciofranco14@gmail.com>, Casper Meijn <casper@meijn.net>, Tokio Contributors <team@tokio.rs>"
549551
prost-build,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert <dan@danburkert.com>, Lucio Franco <luciofranco14@gmail.com>, Casper Meijn <casper@meijn.net>, Tokio Contributors <team@tokio.rs>"
550552
prost-derive,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert <dan@danburkert.com>, Lucio Franco <luciofranco14@gmail.com>, Casper Meijn <casper@meijn.net>, Tokio Contributors <team@tokio.rs>"

quickwit/Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ openssl-probe = "0.1"
169169
opentelemetry = "0.31"
170170
opentelemetry-appender-tracing = "0.31"
171171
opentelemetry_sdk = { version = "0.31", features = ["rt-tokio"] }
172-
opentelemetry-otlp = { version = "0.31", features = ["grpc-tonic"] }
172+
opentelemetry-otlp = { version = "0.31", features = ["grpc-tonic", "http-json"] }
173173
ouroboros = "0.18"
174174
parquet = { version = "57", default-features = false, features = ["arrow", "zstd", "snap", "variant_experimental"] }
175175
percent-encoding = "2.3"

quickwit/quickwit-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ quickwit-actors = { workspace = true, features = ["testsuite"] }
7979
quickwit-common = { workspace = true, features = ["testsuite"] }
8080
quickwit-config = { workspace = true, features = ["testsuite"] }
8181
quickwit-metastore = { workspace = true, features = ["testsuite"] }
82+
quickwit-proto = { workspace = true, features = ["testsuite"] }
8283
quickwit-storage = { workspace = true, features = ["testsuite"] }
8384

8485
[features]

quickwit/quickwit-cli/src/logger.rs

Lines changed: 102 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::str::FromStr;
1516
use std::sync::Arc;
1617
use std::{env, fmt};
1718

1819
use anyhow::Context;
1920
use opentelemetry::trace::TracerProvider;
2021
use opentelemetry::{KeyValue, global};
2122
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
23+
use opentelemetry_otlp::{
24+
LogExporter, Protocol as OtlpWireProtocol, SpanExporter, WithExportConfig,
25+
};
2226
use opentelemetry_sdk::logs::SdkLoggerProvider;
2327
use opentelemetry_sdk::propagation::TraceContextPropagator;
2428
use opentelemetry_sdk::trace::{BatchConfigBuilder, SdkTracerProvider};
2529
use opentelemetry_sdk::{Resource, trace};
26-
use quickwit_common::{get_bool_from_env, get_from_env_opt};
30+
use quickwit_common::{get_bool_from_env, get_from_env, get_from_env_opt};
2731
use quickwit_serve::{BuildInfo, EnvFilterReloadFn};
2832
use time::format_description::BorrowedFormatItem;
2933
use tracing::{Event, Level, Subscriber};
@@ -39,6 +43,67 @@ use tracing_subscriber::prelude::*;
3943
use tracing_subscriber::registry::LookupSpan;
4044

4145
use crate::QW_ENABLE_OPENTELEMETRY_OTLP_EXPORTER_ENV_KEY;
46+
47+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48+
enum OtlpProtocol {
49+
Grpc,
50+
HttpProtobuf,
51+
HttpJson,
52+
}
53+
54+
impl OtlpProtocol {
55+
fn log_exporter(&self) -> anyhow::Result<LogExporter> {
56+
match self {
57+
OtlpProtocol::Grpc => LogExporter::builder().with_tonic().build(),
58+
OtlpProtocol::HttpProtobuf => LogExporter::builder()
59+
.with_http()
60+
.with_protocol(OtlpWireProtocol::HttpBinary)
61+
.build(),
62+
OtlpProtocol::HttpJson => LogExporter::builder()
63+
.with_http()
64+
.with_protocol(OtlpWireProtocol::HttpJson)
65+
.build(),
66+
}
67+
.context("failed to initialize OTLP logs exporter")
68+
}
69+
70+
fn span_exporter(&self) -> anyhow::Result<SpanExporter> {
71+
match self {
72+
OtlpProtocol::Grpc => SpanExporter::builder().with_tonic().build(),
73+
OtlpProtocol::HttpProtobuf => SpanExporter::builder()
74+
.with_http()
75+
.with_protocol(OtlpWireProtocol::HttpBinary)
76+
.build(),
77+
OtlpProtocol::HttpJson => SpanExporter::builder()
78+
.with_http()
79+
.with_protocol(OtlpWireProtocol::HttpJson)
80+
.build(),
81+
}
82+
.context("failed to initialize OTLP traces exporter")
83+
}
84+
}
85+
86+
impl FromStr for OtlpProtocol {
87+
type Err = anyhow::Error;
88+
89+
fn from_str(protocol_str: &str) -> anyhow::Result<Self> {
90+
const OTLP_PROTOCOL_GRPC: &str = "grpc";
91+
const OTLP_PROTOCOL_HTTP_PROTOBUF: &str = "http/protobuf";
92+
const OTLP_PROTOCOL_HTTP_JSON: &str = "http/json";
93+
94+
match protocol_str {
95+
OTLP_PROTOCOL_GRPC => Ok(OtlpProtocol::Grpc),
96+
OTLP_PROTOCOL_HTTP_PROTOBUF => Ok(OtlpProtocol::HttpProtobuf),
97+
OTLP_PROTOCOL_HTTP_JSON => Ok(OtlpProtocol::HttpJson),
98+
other => anyhow::bail!(
99+
"unsupported OTLP protocol `{other}`, supported values are \
100+
`{OTLP_PROTOCOL_GRPC}`, `{OTLP_PROTOCOL_HTTP_PROTOBUF}` and \
101+
`{OTLP_PROTOCOL_HTTP_JSON}`"
102+
),
103+
}
104+
}
105+
}
106+
42107
#[cfg(feature = "tokio-console")]
43108
use crate::QW_ENABLE_TOKIO_CONSOLE_ENV_KEY;
44109

@@ -98,10 +163,19 @@ pub fn setup_logging_and_tracing(
98163
// Note on disabling ANSI characters: setting the ansi boolean on event format is insufficient.
99164
// It is thus set on layers, see https://github.com/tokio-rs/tracing/issues/1817
100165
let provider_opt = if get_bool_from_env(QW_ENABLE_OPENTELEMETRY_OTLP_EXPORTER_ENV_KEY, false) {
101-
let span_exporter = opentelemetry_otlp::SpanExporter::builder()
102-
.with_tonic()
103-
.build()
104-
.context("failed to initialize OpenTelemetry OTLP exporter")?;
166+
let global_protocol_str =
167+
get_from_env("OTEL_EXPORTER_OTLP_PROTOCOL", "grpc".to_string(), false);
168+
let global_protocol = OtlpProtocol::from_str(&global_protocol_str)?;
169+
170+
let traces_protocol_opt =
171+
get_from_env_opt::<String>("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", false);
172+
let traces_protocol = traces_protocol_opt
173+
.as_deref()
174+
.map(OtlpProtocol::from_str)
175+
.transpose()?
176+
.unwrap_or(global_protocol);
177+
178+
let span_exporter = traces_protocol.span_exporter()?;
105179
let span_processor = trace::BatchSpanProcessor::builder(span_exporter)
106180
.with_batch_config(
107181
BatchConfigBuilder::default()
@@ -117,14 +191,17 @@ pub fn setup_logging_and_tracing(
117191
.with_attribute(KeyValue::new("service.version", build_info.version.clone()))
118192
.build();
119193

120-
let logs_exporter = opentelemetry_otlp::LogExporter::builder()
121-
.with_tonic()
122-
.build()
123-
.context("failed to initialize OpenTelemetry OTLP logs")?;
124-
194+
let logs_protocol_opt =
195+
get_from_env_opt::<String>("OTEL_EXPORTER_OTLP_LOGS_PROTOCOL", false);
196+
let logs_protocol = logs_protocol_opt
197+
.as_deref()
198+
.map(OtlpProtocol::from_str)
199+
.transpose()?
200+
.unwrap_or(global_protocol);
201+
let log_exporter = logs_protocol.log_exporter()?;
125202
let logger_provider = SdkLoggerProvider::builder()
126203
.with_resource(resource.clone())
127-
.with_batch_exporter(logs_exporter)
204+
.with_batch_exporter(log_exporter)
128205
.build();
129206

130207
let tracing_provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
@@ -430,6 +507,20 @@ mod tests {
430507

431508
use super::*;
432509

510+
#[test]
511+
fn test_otlp_protocol_from_str() {
512+
assert_eq!(OtlpProtocol::from_str("grpc").unwrap(), OtlpProtocol::Grpc);
513+
assert_eq!(
514+
OtlpProtocol::from_str("http/protobuf").unwrap(),
515+
OtlpProtocol::HttpProtobuf
516+
);
517+
assert_eq!(
518+
OtlpProtocol::from_str("http/json").unwrap(),
519+
OtlpProtocol::HttpJson
520+
);
521+
assert!(OtlpProtocol::from_str("http/xml").is_err());
522+
}
523+
433524
/// A shared buffer writer for capturing log output in tests.
434525
#[derive(Clone, Default)]
435526
struct TestMakeWriter(Arc<Mutex<Vec<u8>>>);

quickwit/quickwit-config/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ quickwit-proto = { workspace = true }
4242
[dev-dependencies]
4343
tokio = { workspace = true }
4444

45-
quickwit-proto = { workspace = true, features = ["testsuite"] }
4645
quickwit-common = { workspace = true, features = ["testsuite"] }
46+
quickwit-proto = { workspace = true, features = ["testsuite"] }
4747

4848
[features]
4949
testsuite = []

0 commit comments

Comments
 (0)