1
1
use std:: env;
2
2
use std:: fmt:: { Debug , Formatter } ;
3
+ #[ cfg( feature = "tls" ) ]
4
+ use std:: fs;
3
5
use std:: str:: FromStr ;
4
6
use std:: time:: Duration ;
5
7
@@ -9,7 +11,7 @@ use tonic::metadata::{KeyAndValueRef, MetadataMap};
9
11
use tonic:: service:: Interceptor ;
10
12
use tonic:: transport:: Channel ;
11
13
#[ cfg( feature = "tls" ) ]
12
- use tonic:: transport:: ClientTlsConfig ;
14
+ use tonic:: transport:: { Certificate , ClientTlsConfig , Identity } ;
13
15
14
16
use super :: { default_headers, parse_header_string, OTEL_EXPORTER_OTLP_GRPC_ENDPOINT_DEFAULT } ;
15
17
use crate :: exporter:: Compression ;
@@ -18,6 +20,12 @@ use crate::{
18
20
OTEL_EXPORTER_OTLP_HEADERS , OTEL_EXPORTER_OTLP_TIMEOUT ,
19
21
} ;
20
22
23
+ #[ cfg( feature = "tls" ) ]
24
+ use crate :: {
25
+ OTEL_EXPORTER_OTLP_CERTIFICATE , OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE ,
26
+ OTEL_EXPORTER_OTLP_CLIENT_KEY , OTEL_EXPORTER_OTLP_INSECURE ,
27
+ } ;
28
+
21
29
#[ cfg( feature = "logs" ) ]
22
30
mod logs;
23
31
@@ -144,12 +152,17 @@ impl Default for TonicExporterBuilder {
144
152
}
145
153
146
154
impl TonicExporterBuilder {
155
+ #[ allow( clippy:: too_many_arguments) ]
147
156
fn build_channel (
148
157
self ,
149
158
signal_endpoint_var : & str ,
150
159
signal_timeout_var : & str ,
151
160
signal_compression_var : & str ,
152
161
signal_headers_var : & str ,
162
+ #[ cfg( feature = "tls" ) ] signal_insecure_var : & str ,
163
+ #[ cfg( feature = "tls" ) ] signal_certificate_var : & str ,
164
+ #[ cfg( feature = "tls" ) ] signal_client_cert_var : & str ,
165
+ #[ cfg( feature = "tls" ) ] signal_client_key_var : & str ,
153
166
) -> Result < ( Channel , BoxInterceptor , Option < CompressionEncoding > ) , crate :: Error > {
154
167
let compression = self . resolve_compression ( signal_compression_var) ?;
155
168
@@ -203,19 +216,107 @@ impl TonicExporterBuilder {
203
216
} ;
204
217
205
218
#[ cfg( feature = "tls" ) ]
206
- let channel = match self . tonic_config . tls_config {
207
- Some ( tls_config) => endpoint
208
- . tls_config ( tls_config)
209
- . map_err ( crate :: Error :: from) ?,
210
- None => endpoint,
219
+ {
220
+ let insecure = config. insecure . unwrap_or_else ( || {
221
+ env:: var ( signal_insecure_var)
222
+ . or_else ( |_| env:: var ( OTEL_EXPORTER_OTLP_INSECURE ) )
223
+ . map_or ( false , |x| {
224
+ if x == "1" {
225
+ true
226
+ } else if x == "0" || x != "true" || x != "false" {
227
+ false
228
+ } else {
229
+ bool:: from_str ( & x) . unwrap_or ( false )
230
+ }
231
+ } )
232
+ } ) ;
233
+
234
+ let channel = match self . tonic_config . tls_config {
235
+ Some ( tls_config) => endpoint
236
+ . tls_config ( tls_config)
237
+ . map_err ( crate :: Error :: from) ?,
238
+ None => {
239
+ if !insecure {
240
+ let tls_config = Self :: resolve_tls_config (
241
+ signal_certificate_var,
242
+ signal_client_cert_var,
243
+ signal_client_key_var,
244
+ self . tonic_config . tls_config ,
245
+ config. certificate ,
246
+ config. client_certificate ,
247
+ config. client_key ,
248
+ ) ?;
249
+ endpoint
250
+ . tls_config ( tls_config)
251
+ . map_err ( crate :: Error :: from) ?
252
+ } else {
253
+ endpoint
254
+ }
255
+ }
256
+ }
257
+ . timeout ( timeout)
258
+ . connect_lazy ( ) ;
259
+ println ! ( "{:?}" , channel) ;
260
+ Ok ( ( channel, interceptor, compression) )
211
261
}
212
- . timeout ( timeout)
213
- . connect_lazy ( ) ;
214
262
215
263
#[ cfg( not( feature = "tls" ) ) ]
216
- let channel = endpoint. timeout ( timeout) . connect_lazy ( ) ;
264
+ {
265
+ let channel = endpoint. timeout ( timeout) . connect_lazy ( ) ;
266
+ Ok ( ( channel, interceptor, compression) )
267
+ }
268
+ }
217
269
218
- Ok ( ( channel, interceptor, compression) )
270
+ #[ cfg( feature = "tls" ) ]
271
+ fn resolve_tls_config (
272
+ signal_certificate_var : & str ,
273
+ signal_client_cert_var : & str ,
274
+ signal_client_key_var : & str ,
275
+ tls_config : Option < ClientTlsConfig > ,
276
+ provided_certificate : Option < String > ,
277
+ provided_client_cert : Option < String > ,
278
+ provided_client_key : Option < String > ,
279
+ ) -> Result < ClientTlsConfig , crate :: Error > {
280
+ // User provided tls config. Use it.
281
+ if let Some ( tls_config) = tls_config {
282
+ return Ok ( tls_config) ;
283
+ }
284
+
285
+ // No user provided tls config. Try to build one from env vars.
286
+ let mut client_tls_config = ClientTlsConfig :: new ( ) ;
287
+
288
+ let ca_file = provided_certificate. or_else ( || {
289
+ env:: var ( signal_certificate_var)
290
+ . or_else ( |_| env:: var ( OTEL_EXPORTER_OTLP_CERTIFICATE ) )
291
+ . ok ( )
292
+ } ) ;
293
+ let client_cert_file = provided_client_cert. or_else ( || {
294
+ env:: var ( signal_client_cert_var)
295
+ . or_else ( |_| env:: var ( OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE ) )
296
+ . ok ( )
297
+ } ) ;
298
+ let client_key_file = provided_client_key. or_else ( || {
299
+ env:: var ( signal_client_key_var)
300
+ . or_else ( |_| env:: var ( OTEL_EXPORTER_OTLP_CLIENT_KEY ) )
301
+ . ok ( )
302
+ } ) ;
303
+ if let Some ( ca_path) = ca_file {
304
+ let ca_cert =
305
+ std:: fs:: read ( ca_path) . map_err ( |x| crate :: Error :: TLSConfigError ( x. to_string ( ) ) ) ?;
306
+ client_tls_config = client_tls_config. ca_certificate ( Certificate :: from_pem ( ca_cert) ) ;
307
+ }
308
+
309
+ if let ( Some ( cert_path) , Some ( key_path) ) = ( client_cert_file, client_key_file) {
310
+ let cert =
311
+ fs:: read ( cert_path) . map_err ( |x| crate :: Error :: TLSConfigError ( x. to_string ( ) ) ) ?;
312
+ let key =
313
+ fs:: read ( key_path) . map_err ( |x| crate :: Error :: TLSConfigError ( x. to_string ( ) ) ) ?;
314
+
315
+ let identity = Identity :: from_pem ( cert, key) ;
316
+ client_tls_config = client_tls_config. identity ( identity) ;
317
+ }
318
+ println ! ( "{:?}" , client_tls_config) ;
319
+ Ok ( client_tls_config)
219
320
}
220
321
221
322
fn resolve_endpoint ( default_endpoint_var : & str , provided_endpoint : Option < String > ) -> String {
@@ -257,16 +358,37 @@ impl TonicExporterBuilder {
257
358
) -> Result < crate :: logs:: LogExporter , opentelemetry_sdk:: logs:: LogError > {
258
359
use crate :: exporter:: tonic:: logs:: TonicLogsClient ;
259
360
260
- let ( channel, interceptor, compression) = self . build_channel (
261
- crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ,
262
- crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT ,
263
- crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION ,
264
- crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_HEADERS ,
265
- ) ?;
361
+ #[ cfg( not( feature = "tls" ) ) ]
362
+ {
363
+ let ( channel, interceptor, compression) = self . build_channel (
364
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ,
365
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT ,
366
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION ,
367
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_HEADERS ,
368
+ ) ?;
369
+
370
+ let client = TonicLogsClient :: new ( channel, interceptor, compression) ;
266
371
267
- let client = TonicLogsClient :: new ( channel, interceptor, compression) ;
372
+ Ok ( crate :: logs:: LogExporter :: new ( client) )
373
+ }
268
374
269
- Ok ( crate :: logs:: LogExporter :: new ( client) )
375
+ #[ cfg( feature = "tls" ) ]
376
+ {
377
+ let ( channel, interceptor, compression) = self . build_channel (
378
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ,
379
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT ,
380
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION ,
381
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_HEADERS ,
382
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_INSECURE ,
383
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE ,
384
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE ,
385
+ crate :: logs:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY ,
386
+ ) ?;
387
+
388
+ let client = TonicLogsClient :: new ( channel, interceptor, compression) ;
389
+
390
+ Ok ( crate :: logs:: LogExporter :: new ( client) )
391
+ }
270
392
}
271
393
272
394
/// Build a new tonic metrics exporter
@@ -278,16 +400,37 @@ impl TonicExporterBuilder {
278
400
use crate :: MetricExporter ;
279
401
use metrics:: TonicMetricsClient ;
280
402
281
- let ( channel, interceptor, compression) = self . build_channel (
282
- crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ,
283
- crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT ,
284
- crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_COMPRESSION ,
285
- crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_HEADERS ,
286
- ) ?;
403
+ #[ cfg( not( feature = "tls" ) ) ]
404
+ {
405
+ let ( channel, interceptor, compression) = self . build_channel (
406
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ,
407
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT ,
408
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_COMPRESSION ,
409
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_HEADERS ,
410
+ ) ?;
287
411
288
- let client = TonicMetricsClient :: new ( channel, interceptor, compression) ;
412
+ let client = TonicMetricsClient :: new ( channel, interceptor, compression) ;
413
+
414
+ Ok ( MetricExporter :: new ( client, temporality) )
415
+ }
289
416
290
- Ok ( MetricExporter :: new ( client, temporality) )
417
+ #[ cfg( feature = "tls" ) ]
418
+ {
419
+ let ( channel, interceptor, compression) = self . build_channel (
420
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ,
421
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT ,
422
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_COMPRESSION ,
423
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_HEADERS ,
424
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_INSECURE ,
425
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE ,
426
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE ,
427
+ crate :: metric:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY ,
428
+ ) ?;
429
+
430
+ let client = TonicMetricsClient :: new ( channel, interceptor, compression) ;
431
+
432
+ Ok ( MetricExporter :: new ( client, temporality) )
433
+ }
291
434
}
292
435
293
436
/// Build a new tonic span exporter
@@ -297,16 +440,37 @@ impl TonicExporterBuilder {
297
440
) -> Result < crate :: SpanExporter , opentelemetry:: trace:: TraceError > {
298
441
use crate :: exporter:: tonic:: trace:: TonicTracesClient ;
299
442
300
- let ( channel, interceptor, compression) = self . build_channel (
301
- crate :: span:: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ,
302
- crate :: span:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT ,
303
- crate :: span:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION ,
304
- crate :: span:: OTEL_EXPORTER_OTLP_TRACES_HEADERS ,
305
- ) ?;
443
+ #[ cfg( not( feature = "tls" ) ) ]
444
+ {
445
+ let ( channel, interceptor, compression) = self . build_channel (
446
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ,
447
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT ,
448
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION ,
449
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_HEADERS ,
450
+ ) ?;
451
+
452
+ let client = TonicTracesClient :: new ( channel, interceptor, compression) ;
306
453
307
- let client = TonicTracesClient :: new ( channel, interceptor, compression) ;
454
+ Ok ( crate :: SpanExporter :: new ( client) )
455
+ }
308
456
309
- Ok ( crate :: SpanExporter :: new ( client) )
457
+ #[ cfg( feature = "tls" ) ]
458
+ {
459
+ let ( channel, interceptor, compression) = self . build_channel (
460
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ,
461
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT ,
462
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION ,
463
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_HEADERS ,
464
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_INSECURE ,
465
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE ,
466
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE ,
467
+ crate :: span:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY ,
468
+ ) ?;
469
+
470
+ let client = TonicTracesClient :: new ( channel, interceptor, compression) ;
471
+
472
+ Ok ( crate :: SpanExporter :: new ( client) )
473
+ }
310
474
}
311
475
}
312
476
0 commit comments