@@ -45,7 +45,7 @@ pub fn span_exporter(
45
45
endpoint : & str ,
46
46
headers : Option < HashMap < String , String > > ,
47
47
) -> Result < impl SpanExporter + use < > , ConfigureError > {
48
- let ( source, protocol) = protocol_from_env ( "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" ) ?;
48
+ let ( source, protocol) = protocol_from_env ( "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" , endpoint ) ?;
49
49
50
50
let builder = opentelemetry_otlp:: SpanExporter :: builder ( ) ;
51
51
@@ -63,6 +63,10 @@ pub fn span_exporter(
63
63
builder
64
64
. with_tonic( )
65
65
. with_channel(
66
+ // FIXME: .connect_lazy() requires a tokio runtime. A workaround (which
67
+ // may complicate things is to create a tokio runtime in a background
68
+ // thread and use that to drive the channel. This is the same as the
69
+ // way that reqwest does a "blocking" client on top of the sync one.
66
70
tonic:: transport:: Channel :: builder( endpoint. try_into( ) . map_err(
67
71
|e: http:: uri:: InvalidUri | ConfigureError :: Other ( e. into( ) ) ,
68
72
) ?)
@@ -116,7 +120,7 @@ pub fn metric_exporter(
116
120
endpoint : & str ,
117
121
headers : Option < HashMap < String , String > > ,
118
122
) -> Result < impl PushMetricExporter + use < > , ConfigureError > {
119
- let ( source, protocol) = protocol_from_env ( "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL" ) ?;
123
+ let ( source, protocol) = protocol_from_env ( "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL" , endpoint ) ?;
120
124
121
125
let builder =
122
126
MetricExporter :: builder ( ) . with_temporality ( opentelemetry_sdk:: metrics:: Temporality :: Delta ) ;
@@ -188,9 +192,6 @@ fn build_metadata_from_headers(
188
192
Ok ( tonic:: metadata:: MetadataMap :: from_headers ( header_map) )
189
193
}
190
194
191
- // current default logfire protocol is to export over HTTP in binary format
192
- const DEFAULT_LOGFIRE_PROTOCOL : Protocol = Protocol :: HttpBinary ;
193
-
194
195
// standard OTLP protocol values in configuration
195
196
const OTEL_EXPORTER_OTLP_PROTOCOL_GRPC : & str = "grpc" ;
196
197
const OTEL_EXPORTER_OTLP_PROTOCOL_HTTP_PROTOBUF : & str = "http/protobuf" ;
@@ -210,7 +211,12 @@ fn protocol_from_str(value: &str) -> Result<Protocol, ConfigureError> {
210
211
211
212
/// Get a protocol from the environment (or default value), returning a string describing the source
212
213
/// plus the parsed protocol.
213
- fn protocol_from_env ( data_env_var : & str ) -> Result < ( String , Protocol ) , ConfigureError > {
214
+ ///
215
+ /// If the env var is not set, the default protocol is inferred from the endpoint.
216
+ fn protocol_from_env (
217
+ data_env_var : & str ,
218
+ endpoint : & str ,
219
+ ) -> Result < ( String , Protocol ) , ConfigureError > {
214
220
// try both data-specific env var and general protocol
215
221
[ data_env_var, "OTEL_EXPORTER_OTLP_PROTOCOL" ]
216
222
. into_iter ( )
@@ -221,12 +227,20 @@ fn protocol_from_env(data_env_var: &str) -> Result<(String, Protocol), Configure
221
227
} )
222
228
. transpose ( ) ?
223
229
. map_or_else (
224
- || {
225
- Ok ( (
226
- "the default logfire export protocol" . to_string ( ) ,
227
- DEFAULT_LOGFIRE_PROTOCOL ,
228
- ) )
229
- } ,
230
+ || protocol_from_endpoint ( endpoint) ,
230
231
|( var_name, value) | Ok ( ( format ! ( "`{var_name}={value}`" ) , protocol_from_str ( & value) ?) ) ,
231
232
)
232
233
}
234
+
235
+ fn protocol_from_endpoint ( endpoint : & str ) -> Result < ( String , Protocol ) , ConfigureError > {
236
+ let protocol = if endpoint. starts_with ( "http://" ) || endpoint. starts_with ( "https://" ) {
237
+ Protocol :: HttpBinary
238
+ } else if endpoint. starts_with ( "grpc://" ) {
239
+ Protocol :: Grpc
240
+ } else {
241
+ return Err ( ConfigureError :: Other (
242
+ format ! ( "unsupported scheme: {endpoint}" ) . into ( ) ,
243
+ ) ) ;
244
+ } ;
245
+ Ok ( ( format ! ( "the inferred protocol from {endpoint}" ) , protocol) )
246
+ }
0 commit comments