4343 OTEL_TRACES_SAMPLER_ARG ,
4444)
4545from opentelemetry import trace
46+ from opentelemetry .sdk ._logs import LoggingHandler
4647from opentelemetry .sdk .trace import sampling
4748from opentelemetry ._opamp .proto import opamp_pb2 as opamp_pb2
4849from opentelemetry .util ._once import Once
@@ -408,7 +409,102 @@ def test_configurator_does_not_log_otel_env_vars_by_default(self, logger_mock):
408409 logger_mock .assert_not_called ()
409410
410411
412+ class TestConfig (TestCase ):
413+ def tearDown (self ):
414+ for _logger in Config ._get_loggers ():
415+ for handler in _logger .handlers :
416+ _logger .removeHandler (handler )
417+ _logger .propagate = True
418+
419+ def test_constructor (self ):
420+ config = Config ()
421+
422+ self .assertEqual (config .sampling_rate .value , "1.0" )
423+ self .assertEqual (config .logging_level .value , "warn" )
424+
425+ def test_logging_setup_add_handlers_only_once (self ):
426+ config = Config ()
427+
428+ self .assertTrue (logging .root .handlers )
429+
430+ config ._setup_logging ()
431+
432+ for _logger in config ._get_loggers ():
433+ with self .subTest (logger = _logger ):
434+ self .assertEqual (len (_logger .handlers ), 1 )
435+ self .assertFalse (_logger .propagate )
436+
437+ config ._setup_logging ()
438+
439+ for _logger in config ._get_loggers ():
440+ with self .subTest (logger = _logger ):
441+ self .assertEqual (len (_logger .handlers ), 1 )
442+ self .assertFalse (_logger .propagate )
443+
444+ # cleanup
445+ _logger .removeHandler (_logger .handlers [0 ])
446+
447+ def test_logging_setup_set_propagate_true_if_sdk_logging_handler_found (self ):
448+ root_logger = logging .getLogger ()
449+ handler = LoggingHandler (logger_provider = mock .Mock ())
450+ root_logger .addHandler (handler )
451+
452+ config = Config ()
453+
454+ config ._setup_logging ()
455+
456+ for _logger in config ._get_loggers ():
457+ with self .subTest (logger = _logger ):
458+ self .assertEqual (len (_logger .handlers ), 1 )
459+ self .assertTrue (_logger .propagate )
460+
461+ # cleanup
462+ _logger .removeHandler (_logger .handlers [0 ])
463+ _logger .propagate = True
464+
465+ root_logger .removeHandler (handler )
466+
467+ @mock .patch .dict (os .environ , {"OTEL_ENV" : "otel" , "ELASTIC_OTEL_ENV" : "elastic_otel" , "FOO" : "foo" })
468+ def test_log_env_vars_logs_configuration (self ):
469+ config = Config ()
470+ with self .assertLogs ("elasticotel.distro.config" , level = "INFO" ) as cm :
471+ config .log_env_vars ()
472+ self .assertEqual (
473+ cm .output ,
474+ [
475+ "INFO:elasticotel.distro.config:EDOT Configuration" ,
476+ "INFO:elasticotel.distro.config:ELASTIC_OTEL_ENV: elastic_otel" ,
477+ "INFO:elasticotel.distro.config:OTEL_ENV: otel" ,
478+ ],
479+ )
480+
481+ def test_to_dict (self ):
482+ config = Config ()
483+ self .assertEqual (config .to_dict (), {"logging_level" : "warn" , "sampling_rate" : "1.0" })
484+
485+ @mock .patch .object (logging , "getLogger" )
486+ def test_update_loggers (self , get_logger_mock ):
487+ config = Config ()
488+
489+ config .update_loggers (logging .WARNING )
490+
491+ get_logger_mock .assert_has_calls (
492+ [
493+ mock .call ("opentelemetry" ),
494+ mock .call ("elasticotel" ),
495+ mock .call ().setLevel (logging .WARNING ),
496+ mock .call ().setLevel (logging .WARNING ),
497+ ]
498+ )
499+
500+
411501class TestOpAMPHandler (TestCase ):
502+ def tearDown (self ):
503+ for _logger in Config ._get_loggers ():
504+ for handler in _logger .handlers :
505+ _logger .removeHandler (handler )
506+ _logger .propagate = True
507+
412508 @mock .patch .object (logging , "getLogger" )
413509 def test_does_nothing_without_remote_config (self , get_logger_mock ):
414510 message = opamp_pb2 .ServerToAgent ()
@@ -419,20 +515,20 @@ def test_does_nothing_without_remote_config(self, get_logger_mock):
419515 get_logger_mock .assert_not_called ()
420516
421517 @mock .patch ("elasticotel.distro.config._get_config" )
422- @ mock . patch . object ( Config , "_handle_logging" )
423- @ mock . patch . object ( logging , "getLogger" )
424- def test_ignores_non_elastic_filename ( self , get_logger_mock , handle_logging_mock , get_config_mock ):
425- get_config_mock .return_value = Config ()
518+ def test_ignores_non_elastic_filename ( self , get_config_mock ):
519+ config = Config ( )
520+ config . update_loggers = mock . Mock ()
521+ get_config_mock .return_value = config
426522 agent = mock .Mock ()
427523 client = mock .Mock ()
428- config = opamp_pb2 .AgentConfigMap ()
429- config .config_map ["non-elastic" ].body = json .dumps ({"logging_level" : "trace" }).encode ()
430- config .config_map ["non-elastic" ].content_type = "application/json"
431- remote_config = opamp_pb2 .AgentRemoteConfig (config = config , config_hash = b"1234" )
524+ agent_config = opamp_pb2 .AgentConfigMap ()
525+ agent_config .config_map ["non-elastic" ].body = json .dumps ({"logging_level" : "trace" }).encode ()
526+ agent_config .config_map ["non-elastic" ].content_type = "application/json"
527+ remote_config = opamp_pb2 .AgentRemoteConfig (config = agent_config , config_hash = b"1234" )
432528 message = opamp_pb2 .ServerToAgent (remote_config = remote_config )
433529 opamp_handler (agent , client , message )
434530
435- get_logger_mock .assert_not_called ()
531+ config . update_loggers .assert_not_called ()
436532
437533 client ._update_remote_config_status .assert_called_once_with (
438534 remote_config_hash = b"1234" , status = opamp_pb2 .RemoteConfigStatuses_APPLIED , error_message = ""
@@ -503,21 +599,20 @@ def test_fails_if_elastic_config_is_not_json(self, logger_mock, get_config_mock)
503599 client ._build_full_state_message .assert_not_called ()
504600
505601 @mock .patch ("elasticotel.distro.config._get_config" )
506- @mock .patch .object (logging , "getLogger" )
507- def test_sets_matching_logging_level (self , get_logger_mock , get_config_mock ):
508- get_config_mock .return_value = Config ()
602+ def test_sets_matching_logging_level (self , get_config_mock ):
603+ config = Config ()
604+ config .update_loggers = mock .Mock ()
605+ get_config_mock .return_value = config
509606 agent = mock .Mock ()
510607 client = mock .Mock ()
511- config = opamp_pb2 .AgentConfigMap ()
512- config .config_map ["elastic" ].body = json .dumps ({"logging_level" : "trace" }).encode ()
513- config .config_map ["elastic" ].content_type = "application/json"
514- remote_config = opamp_pb2 .AgentRemoteConfig (config = config , config_hash = b"1234" )
608+ agent_config = opamp_pb2 .AgentConfigMap ()
609+ agent_config .config_map ["elastic" ].body = json .dumps ({"logging_level" : "trace" }).encode ()
610+ agent_config .config_map ["elastic" ].content_type = "application/json"
611+ remote_config = opamp_pb2 .AgentRemoteConfig (config = agent_config , config_hash = b"1234" )
515612 message = opamp_pb2 .ServerToAgent (remote_config = remote_config )
516613 opamp_handler (agent , client , message )
517614
518- get_logger_mock .assert_has_calls (
519- [mock .call ("opentelemetry" ), mock .call ().setLevel (5 ), mock .call ("elasticotel" ), mock .call ().setLevel (5 )]
520- )
615+ config .update_loggers .assert_called_once_with (5 )
521616
522617 client ._update_remote_config_status .assert_called_once_with (
523618 remote_config_hash = b"1234" , status = opamp_pb2 .RemoteConfigStatuses_APPLIED , error_message = ""
@@ -532,26 +627,20 @@ def test_sets_matching_logging_level(self, get_logger_mock, get_config_mock):
532627 client ._build_full_state_message .assert_not_called ()
533628
534629 @mock .patch ("elasticotel.distro.config._get_config" )
535- @mock .patch .object (logging , "getLogger" )
536- def test_sets_logging_to_default_info_without_logging_level_entry_in_config (self , get_logger_mock , get_config_mock ):
537- get_config_mock .return_value = Config ()
630+ def test_sets_logging_to_default_info_without_logging_level_entry_in_config (self , get_config_mock ):
631+ config = Config ()
632+ config .update_loggers = mock .Mock ()
633+ get_config_mock .return_value = config
538634 agent = mock .Mock ()
539635 client = mock .Mock ()
540- config = opamp_pb2 .AgentConfigMap ()
541- config .config_map ["elastic" ].body = json .dumps ({}).encode ()
542- config .config_map ["elastic" ].content_type = "application/json"
543- remote_config = opamp_pb2 .AgentRemoteConfig (config = config , config_hash = b"1234" )
636+ agent_config = opamp_pb2 .AgentConfigMap ()
637+ agent_config .config_map ["elastic" ].body = json .dumps ({}).encode ()
638+ agent_config .config_map ["elastic" ].content_type = "application/json"
639+ remote_config = opamp_pb2 .AgentRemoteConfig (config = agent_config , config_hash = b"1234" )
544640 message = opamp_pb2 .ServerToAgent (remote_config = remote_config )
545641 opamp_handler (agent , client , message )
546642
547- get_logger_mock .assert_has_calls (
548- [
549- mock .call ("opentelemetry" ),
550- mock .call ().setLevel (logging .WARNING ),
551- mock .call ("elasticotel" ),
552- mock .call ().setLevel (logging .WARNING ),
553- ]
554- )
643+ config .update_loggers .assert_called_once_with (logging .WARNING )
555644
556645 client ._update_remote_config_status .assert_called_once_with (
557646 remote_config_hash = b"1234" , status = opamp_pb2 .RemoteConfigStatuses_APPLIED , error_message = ""
0 commit comments