22# SPDX-License-Identifier: Apache-2.0
33# type: ignore
44
5+ from logging import DEBUG , INFO , NullHandler , getLogger
56from unittest import TestCase
67from unittest .mock import Mock , call , patch
78
@@ -198,27 +199,32 @@ def _instrumentation_failed_to_load_call(entry_point, dependency_conflict):
198199 "Skipping instrumentation %s: %s" , entry_point , dependency_conflict
199200 )
200201
201- def test_writes_diagnostic_output_for_debug_levels (self ):
202+ def test_writes_otel_log_level_output_for_debug_levels (self ):
202203 for log_level in ("debug" , "trace" ):
203204 with (
204205 self .subTest (log_level = log_level ),
205206 patch .dict (
206207 "os.environ" , {"OTEL_LOG_LEVEL" : log_level }, clear = True
207208 ),
208- patch (
209- "opentelemetry.instrumentation.auto_instrumentation._load._logger"
210- ) as logger_mock ,
211209 patch (
212210 "opentelemetry.instrumentation.auto_instrumentation._load.stderr"
213211 ) as stderr_mock ,
214212 ):
213+ logger_mock = Mock ()
215214 logger_mock .isEnabledFor .return_value = True
216- logger_mock .hasHandlers .return_value = False
215+ logger_mock .handlers = []
216+ logger_mock .parent = None
217+ logger_mock .propagate = True
218+ logger_mock .name = (
219+ "opentelemetry.instrumentation."
220+ "auto_instrumentation._load"
221+ )
222+ logger = _load ._OtelLogLevelLoggerAdapter (logger_mock , {})
217223
218- _load . _debug ("Instrumented %s" , "requests" )
224+ logger . debug ("Instrumented %s" , "requests" )
219225
220- logger_mock .debug .assert_called_once_with (
221- "Instrumented %s" , "requests"
226+ logger_mock .log .assert_called_once_with (
227+ DEBUG , "Instrumented %s" , "requests" , extra = {}
222228 )
223229 stderr_mock .write .assert_called_once_with (
224230 "DEBUG:"
@@ -227,37 +233,115 @@ def test_writes_diagnostic_output_for_debug_levels(self):
227233 )
228234 stderr_mock .flush .assert_called_once ()
229235
230- def test_does_not_write_diagnostic_output (self ):
236+ def test_does_not_write_otel_log_level_output (self ):
231237 cases = (
232- ("debug" , True ),
238+ ("debug" , DEBUG ),
233239 ("info" , False ),
234240 ("debug2" , False ),
235241 ("debugger" , False ),
236242 )
237243
238- for log_level , logger_has_handlers in cases :
244+ for log_level , handler_level in cases :
239245 with (
240246 self .subTest (log_level = log_level ),
241247 patch .dict (
242248 "os.environ" , {"OTEL_LOG_LEVEL" : log_level }, clear = True
243249 ),
244- patch (
245- "opentelemetry.instrumentation.auto_instrumentation._load._logger"
246- ) as logger_mock ,
247250 patch (
248251 "opentelemetry.instrumentation.auto_instrumentation._load.stderr"
249252 ) as stderr_mock ,
250253 ):
254+ logger_mock = Mock ()
251255 logger_mock .isEnabledFor .return_value = True
252- logger_mock .hasHandlers .return_value = logger_has_handlers
256+ logger_mock .handlers = (
257+ [Mock (level = handler_level )] if handler_level else []
258+ )
259+ logger_mock .parent = None
260+ logger_mock .propagate = True
261+ logger = _load ._OtelLogLevelLoggerAdapter (logger_mock , {})
262+
263+ logger .debug ("Instrumented %s" , "requests" )
264+
265+ logger_mock .log .assert_called_once_with (
266+ DEBUG , "Instrumented %s" , "requests" , extra = {}
267+ )
268+ stderr_mock .write .assert_not_called ()
269+ stderr_mock .flush .assert_not_called ()
270+
271+ @patch .dict ("os.environ" , {"OTEL_LOG_LEVEL" : "debug" }, clear = True )
272+ def test_otel_log_level_output_uses_logger_hierarchy_handlers (self ):
273+ parent_logger = getLogger ("opentelemetry.test.auto_instrumentation" )
274+ logger = getLogger ("opentelemetry.test.auto_instrumentation.loader" )
275+
276+ original_parent_handlers = parent_logger .handlers [:]
277+ original_parent_level = parent_logger .level
278+ original_parent_propagate = parent_logger .propagate
279+ original_logger_handlers = logger .handlers [:]
280+ original_logger_level = logger .level
281+ original_logger_propagate = logger .propagate
282+
283+ try :
284+ parent_logger .handlers = []
285+ parent_logger .setLevel (DEBUG )
286+ parent_logger .propagate = False
287+ logger .handlers = []
288+ logger .setLevel (DEBUG )
289+ logger .propagate = True
290+
291+ otel_log_level_logger = _load ._OtelLogLevelLoggerAdapter (
292+ logger , {}
293+ )
294+
295+ with patch (
296+ "opentelemetry.instrumentation.auto_instrumentation._load.stderr"
297+ ) as stderr_mock :
298+ otel_log_level_logger .debug ("Instrumented %s" , "requests" )
299+
300+ stderr_mock .write .assert_called_once_with (
301+ "DEBUG:"
302+ "opentelemetry.test.auto_instrumentation.loader:"
303+ "Instrumented 'requests'\n "
304+ )
305+ stderr_mock .flush .assert_called_once ()
306+
307+ handler = NullHandler ()
308+ handler .setLevel (INFO )
309+ parent_logger .addHandler (handler )
310+ otel_log_level_logger = _load ._OtelLogLevelLoggerAdapter (
311+ logger , {}
312+ )
253313
254- _load ._debug ("Instrumented %s" , "requests" )
314+ with patch (
315+ "opentelemetry.instrumentation.auto_instrumentation._load.stderr"
316+ ) as stderr_mock :
317+ otel_log_level_logger .debug ("Instrumented %s" , "requests" )
255318
256- logger_mock .debug .assert_called_once_with (
257- "Instrumented %s" , "requests"
319+ stderr_mock .write .assert_called_once_with (
320+ "DEBUG:"
321+ "opentelemetry.test.auto_instrumentation.loader:"
322+ "Instrumented 'requests'\n "
258323 )
324+ stderr_mock .flush .assert_called_once ()
325+
326+ handler .setLevel (DEBUG )
327+ otel_log_level_logger = _load ._OtelLogLevelLoggerAdapter (
328+ logger , {}
329+ )
330+
331+ with patch (
332+ "opentelemetry.instrumentation.auto_instrumentation._load.stderr"
333+ ) as stderr_mock :
334+ otel_log_level_logger .debug ("Instrumented %s" , "requests" )
335+
259336 stderr_mock .write .assert_not_called ()
260337 stderr_mock .flush .assert_not_called ()
338+ finally :
339+ parent_logger .handlers = original_parent_handlers
340+ parent_logger .setLevel (original_parent_level )
341+ parent_logger .propagate = original_parent_propagate
342+ logger .handlers = original_logger_handlers
343+ logger .setLevel (original_logger_level )
344+ logger .propagate = original_logger_propagate
261345
262346 @patch .dict (
263347 "os.environ" ,
0 commit comments