@@ -13,22 +13,38 @@ thread_local! { static EBW: RefCell<EventBuilder> = RefCell::new(EventBuilder::n
1313/// UserEventsExporter is a log exporter that exports logs in EventHeader format to user_events tracepoint.
1414pub ( crate ) struct UserEventsExporter {
1515 provider : Mutex < Provider > ,
16+ name : String ,
1617 event_sets : Vec < Arc < EventSet > > ,
1718}
1819
1920const EVENT_ID : & str = "event_id" ;
2021
2122impl UserEventsExporter {
2223 /// Create instance of the exporter
23- pub ( crate ) fn new ( provider_name : & str ) -> Self {
24+ pub ( crate ) fn new ( provider_name : & str ) -> Result < Self , String > {
25+ // Validate provider_name
26+ if provider_name. len ( ) >= 234 {
27+ return Err ( "Provider name must be less than 234 characters." . to_string ( ) ) ;
28+ }
29+ if !provider_name
30+ . chars ( )
31+ . all ( |c| c. is_ascii_alphanumeric ( ) || c == '_' )
32+ {
33+ return Err (
34+ "Provider name must contain only ASCII letters, digits, and '_'." . to_string ( ) ,
35+ ) ;
36+ }
37+
2438 let mut eventheader_provider: Provider =
2539 Provider :: new ( provider_name, & Provider :: new_options ( ) ) ;
2640 let event_sets = Self :: register_events ( & mut eventheader_provider) ;
2741 otel_debug ! ( name: "UserEvents.Created" , provider_name = provider_name) ;
28- UserEventsExporter {
42+ let name = eventheader_provider. name ( ) . to_string ( ) ;
43+ Ok ( UserEventsExporter {
2944 provider : Mutex :: new ( eventheader_provider) ,
45+ name,
3046 event_sets,
31- }
47+ } )
3248 }
3349
3450 fn register_events (
@@ -298,7 +314,7 @@ impl UserEventsExporter {
298314
299315impl Debug for UserEventsExporter {
300316 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
301- f . write_str ( "user_events log exporter" )
317+ write ! ( f , "user_events log exporter (provider: {})" , self . name )
302318 }
303319}
304320
@@ -335,3 +351,95 @@ impl opentelemetry_sdk::logs::LogExporter for UserEventsExporter {
335351 }
336352 }
337353}
354+
355+ #[ cfg( test) ]
356+ mod tests {
357+ use super :: * ;
358+ #[ test]
359+ fn exporter_debug ( ) {
360+ let exporter = UserEventsExporter :: new ( "test_provider" ) ;
361+ assert_eq ! (
362+ format!( "{:?}" , exporter. expect( "Failed to create exporter" ) ) ,
363+ "user_events log exporter (provider: test_provider)"
364+ ) ;
365+ }
366+
367+ #[ test]
368+ fn valid_provider_name ( ) {
369+ let valid_names = vec ! [
370+ "ValidName" ,
371+ "valid_name" ,
372+ "Valid123" ,
373+ "valid_123" ,
374+ "_valid_name" ,
375+ "VALID_NAME" ,
376+ ] ;
377+
378+ for valid_name in valid_names {
379+ let result = UserEventsExporter :: new ( valid_name) ;
380+ assert ! (
381+ result. is_ok( ) ,
382+ "Expected '{}' to be valid, but it was rejected" ,
383+ valid_name
384+ ) ;
385+ }
386+ }
387+
388+ #[ test]
389+ fn provider_name_too_long ( ) {
390+ let long_name = "a" . repeat ( 234 ) ;
391+ let result = UserEventsExporter :: new ( & long_name) ;
392+ assert ! ( result. is_err( ) ) ;
393+ assert_eq ! (
394+ result. err( ) . unwrap( ) ,
395+ "Provider name must be less than 234 characters." . to_string( )
396+ ) ;
397+ }
398+
399+ #[ test]
400+ fn provider_name_contains_invalid_characters ( ) {
401+ // Define a vector of invalid provider names to test
402+ let invalid_names = vec ! [
403+ "Invalid Name" , // space
404+ "Invalid:Name" , // colon
405+ "Invalid\0 Name" , // null character
406+ "Invalid-Name" , // hyphen
407+ "InvalidName!" , // exclamation mark
408+ "InvalidName@" , // at symbol
409+ "Invalid+Name" , // plus
410+ "Invalid&Name" , // ampersand
411+ "Invalid#Name" , // hash
412+ "Invalid%Name" , // percent
413+ "Invalid/Name" , // slash
414+ "Invalid\\ Name" , // backslash
415+ "Invalid=Name" , // equals
416+ "Invalid?Name" , // question mark
417+ "Invalid;Name" , // semicolon
418+ "Invalid,Name" , // comma
419+ ] ;
420+
421+ // Expected error message
422+ let expected_error =
423+ "Provider name must contain only ASCII letters, digits, and '_'." . to_string ( ) ;
424+
425+ // Test each invalid name
426+ for invalid_name in invalid_names {
427+ let result = UserEventsExporter :: new ( invalid_name) ;
428+
429+ // Assert that the result is an error
430+ assert ! (
431+ result. is_err( ) ,
432+ "Expected '{}' to be invalid, but it was accepted" ,
433+ invalid_name
434+ ) ;
435+
436+ // Assert that the error message is as expected
437+ assert_eq ! (
438+ result. err( ) . unwrap( ) ,
439+ expected_error,
440+ "Wrong error message for invalid name: '{}'" ,
441+ invalid_name
442+ ) ;
443+ }
444+ }
445+ }
0 commit comments