@@ -29,26 +29,12 @@ pub const OTEL_EXPORTER_OTLP_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_PROTOCOL";
2929/// Compression algorithm to use, defaults to none.
3030pub const OTEL_EXPORTER_OTLP_COMPRESSION : & str = "OTEL_EXPORTER_OTLP_COMPRESSION" ;
3131
32- #[ cfg( feature = "http-json" ) ]
33- /// Default protocol, using http-json.
34- pub const OTEL_EXPORTER_OTLP_PROTOCOL_DEFAULT : & str = OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_JSON ;
35- #[ cfg( all( feature = "http-proto" , not( feature = "http-json" ) ) ) ]
36- /// Default protocol, using http-proto.
37- pub const OTEL_EXPORTER_OTLP_PROTOCOL_DEFAULT : & str = OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_PROTOBUF ;
38- #[ cfg( all(
39- feature = "grpc-tonic" ,
40- not( any( feature = "http-proto" , feature = "http-json" ) )
41- ) ) ]
42- /// Default protocol, using grpc
43- pub const OTEL_EXPORTER_OTLP_PROTOCOL_DEFAULT : & str = OTEL_EXPORTER_OTLP_PROTOCOL_GRPC ;
44-
45- #[ cfg( not( any( feature = "grpc-tonic" , feature = "http-proto" , feature = "http-json" ) ) ) ]
46- /// Default protocol if no features are enabled.
47- pub const OTEL_EXPORTER_OTLP_PROTOCOL_DEFAULT : & str = "" ;
48-
49- const OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_PROTOBUF : & str = "http/protobuf" ;
50- const OTEL_EXPORTER_OTLP_PROTOCOL_GRPC : & str = "grpc" ;
51- const OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_JSON : & str = "http/json" ;
32+ /// Protocol value for HTTP with protobuf encoding
33+ pub const OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_PROTOBUF : & str = "http/protobuf" ;
34+ /// Protocol value for gRPC
35+ pub const OTEL_EXPORTER_OTLP_PROTOCOL_GRPC : & str = "grpc" ;
36+ /// Protocol value for HTTP with JSON encoding
37+ pub const OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_JSON : & str = "http/json" ;
5238
5339/// Max waiting time for the backend to process each signal batch, defaults to 10 seconds.
5440pub const OTEL_EXPORTER_OTLP_TIMEOUT : & str = "OTEL_EXPORTER_OTLP_TIMEOUT" ;
@@ -84,9 +70,10 @@ pub struct ExportConfig {
8470 pub timeout : Option < Duration > ,
8571}
8672
73+ #[ cfg( any( feature = "grpc-tonic" , feature = "http-proto" , feature = "http-json" ) ) ]
8774impl Default for ExportConfig {
8875 fn default ( ) -> Self {
89- let protocol = default_protocol ( ) ;
76+ let protocol = Protocol :: default ( ) ;
9077
9178 Self {
9279 endpoint : None ,
@@ -190,13 +177,33 @@ fn resolve_compression_from_env(
190177 }
191178}
192179
193- /// default protocol based on enabled features
194- fn default_protocol ( ) -> Protocol {
195- match OTEL_EXPORTER_OTLP_PROTOCOL_DEFAULT {
196- OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_PROTOBUF => Protocol :: HttpBinary ,
197- OTEL_EXPORTER_OTLP_PROTOCOL_GRPC => Protocol :: Grpc ,
198- OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_JSON => Protocol :: HttpJson ,
199- _ => Protocol :: HttpBinary ,
180+ /// Returns the default protocol based on environment variable or enabled features.
181+ ///
182+ /// Priority order (first available wins):
183+ /// 1. OTEL_EXPORTER_OTLP_PROTOCOL environment variable (if set and feature is enabled)
184+ /// 2. http-json (if enabled)
185+ /// 3. http-proto (if enabled)
186+ /// 4. grpc-tonic (if enabled)
187+ #[ cfg( any( feature = "grpc-tonic" , feature = "http-proto" , feature = "http-json" ) ) ]
188+ impl Default for Protocol {
189+ fn default ( ) -> Self {
190+ // Check environment variable first
191+ if let Some ( protocol) = Protocol :: from_env ( ) {
192+ return protocol;
193+ }
194+
195+ // Fall back to feature-based defaults
196+ #[ cfg( feature = "http-json" ) ]
197+ return Protocol :: HttpJson ;
198+
199+ #[ cfg( all( feature = "http-proto" , not( feature = "http-json" ) ) ) ]
200+ return Protocol :: HttpBinary ;
201+
202+ #[ cfg( all(
203+ feature = "grpc-tonic" ,
204+ not( any( feature = "http-proto" , feature = "http-json" ) )
205+ ) ) ]
206+ return Protocol :: Grpc ;
200207 }
201208}
202209
@@ -460,21 +467,15 @@ mod tests {
460467 not( any( feature = "grpc-tonic" , feature = "http-proto" ) )
461468 ) ) ]
462469 {
463- assert_eq ! (
464- crate :: exporter:: default_protocol( ) ,
465- crate :: Protocol :: HttpJson
466- ) ;
470+ assert_eq ! ( crate :: Protocol :: default ( ) , crate :: Protocol :: HttpJson ) ;
467471 }
468472
469473 #[ cfg( all(
470474 feature = "http-proto" ,
471475 not( any( feature = "grpc-tonic" , feature = "http-json" ) )
472476 ) ) ]
473477 {
474- assert_eq ! (
475- crate :: exporter:: default_protocol( ) ,
476- crate :: Protocol :: HttpBinary
477- ) ;
478+ assert_eq ! ( crate :: Protocol :: default ( ) , crate :: Protocol :: HttpBinary ) ;
478479 }
479480
480481 #[ cfg( all(
@@ -486,6 +487,58 @@ mod tests {
486487 }
487488 }
488489
490+ #[ test]
491+ fn test_protocol_from_env ( ) {
492+ use crate :: { Protocol , OTEL_EXPORTER_OTLP_PROTOCOL } ;
493+
494+ // Test with no env var set - should return None
495+ temp_env:: with_var_unset ( OTEL_EXPORTER_OTLP_PROTOCOL , || {
496+ assert_eq ! ( Protocol :: from_env( ) , None ) ;
497+ } ) ;
498+
499+ // Test with grpc protocol
500+ #[ cfg( feature = "grpc-tonic" ) ]
501+ run_env_test ( vec ! [ ( OTEL_EXPORTER_OTLP_PROTOCOL , "grpc" ) ] , || {
502+ assert_eq ! ( Protocol :: from_env( ) , Some ( Protocol :: Grpc ) ) ;
503+ } ) ;
504+
505+ // Test with http/protobuf protocol
506+ #[ cfg( feature = "http-proto" ) ]
507+ run_env_test ( vec ! [ ( OTEL_EXPORTER_OTLP_PROTOCOL , "http/protobuf" ) ] , || {
508+ assert_eq ! ( Protocol :: from_env( ) , Some ( Protocol :: HttpBinary ) ) ;
509+ } ) ;
510+
511+ // Test with http/json protocol
512+ #[ cfg( feature = "http-json" ) ]
513+ run_env_test ( vec ! [ ( OTEL_EXPORTER_OTLP_PROTOCOL , "http/json" ) ] , || {
514+ assert_eq ! ( Protocol :: from_env( ) , Some ( Protocol :: HttpJson ) ) ;
515+ } ) ;
516+
517+ // Test with invalid protocol - should return None
518+ run_env_test ( vec ! [ ( OTEL_EXPORTER_OTLP_PROTOCOL , "invalid" ) ] , || {
519+ assert_eq ! ( Protocol :: from_env( ) , None ) ;
520+ } ) ;
521+ }
522+
523+ #[ test]
524+ fn test_default_protocol_respects_env ( ) {
525+ // Test that env var takes precedence over feature-based defaults
526+ #[ cfg( all( feature = "http-json" , feature = "http-proto" ) ) ]
527+ run_env_test (
528+ vec ! [ ( crate :: OTEL_EXPORTER_OTLP_PROTOCOL , "http/protobuf" ) ] ,
529+ || {
530+ // Even though http-json would be the default, env var should override
531+ assert_eq ! ( crate :: Protocol :: default ( ) , crate :: Protocol :: HttpBinary ) ;
532+ } ,
533+ ) ;
534+
535+ #[ cfg( all( feature = "grpc-tonic" , feature = "http-json" ) ) ]
536+ run_env_test ( vec ! [ ( crate :: OTEL_EXPORTER_OTLP_PROTOCOL , "grpc" ) ] , || {
537+ // Even though http-json would be the default, env var should override
538+ assert_eq ! ( crate :: Protocol :: default ( ) , crate :: Protocol :: Grpc ) ;
539+ } ) ;
540+ }
541+
489542 #[ test]
490543 fn test_url_decode ( ) {
491544 let test_cases = vec ! [
0 commit comments