|
15 | 15 | from os import environ
|
16 | 16 | from unittest import TestCase
|
17 | 17 | from unittest.mock import patch
|
| 18 | +from logging import Formatter |
18 | 19 |
|
19 | 20 | from opentelemetry.instrumentation.environment_variables import (
|
20 | 21 | OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
|
|
23 | 24 | SAMPLING_RATIO_ENV_VAR,
|
24 | 25 | _get_configurations,
|
25 | 26 | )
|
| 27 | +from azure.monitor.opentelemetry._constants import LOGGER_NAME_ENV_ARG, LOGGING_FORMAT_ENV_ARG |
26 | 28 | from opentelemetry.environment_variables import (
|
27 | 29 | OTEL_LOGS_EXPORTER,
|
28 | 30 | OTEL_METRICS_EXPORTER,
|
29 | 31 | OTEL_TRACES_EXPORTER,
|
30 | 32 | )
|
31 | 33 | from opentelemetry.sdk.environment_variables import OTEL_EXPERIMENTAL_RESOURCE_DETECTORS
|
32 |
| -from opentelemetry.sdk.resources import Resource, Attributes |
| 34 | +from opentelemetry.sdk.resources import Resource |
33 | 35 |
|
34 | 36 | from azure.monitor.opentelemetry._version import VERSION
|
35 | 37 |
|
@@ -260,3 +262,112 @@ def test_merge_instrumentation_options_extra_args(self, resource_create_mock):
|
260 | 262 | "urllib3": {"enabled": True},
|
261 | 263 | },
|
262 | 264 | )
|
| 265 | + |
| 266 | + @patch.dict( |
| 267 | + "os.environ", |
| 268 | + { |
| 269 | + LOGGER_NAME_ENV_ARG: "test_env_logger", |
| 270 | + }, |
| 271 | + clear=True, |
| 272 | + ) |
| 273 | + def test_get_configurations_logger_name_env_var(self): |
| 274 | + configurations = _get_configurations() |
| 275 | + |
| 276 | + self.assertEqual(configurations["logger_name"], "test_env_logger") |
| 277 | + |
| 278 | + @patch.dict( |
| 279 | + "os.environ", |
| 280 | + { |
| 281 | + LOGGER_NAME_ENV_ARG: "test_env_logger", |
| 282 | + }, |
| 283 | + clear=True, |
| 284 | + ) |
| 285 | + def test_get_configurations_logger_name_param_overrides_env_var(self): |
| 286 | + configurations = _get_configurations(logger_name="test_param_logger") |
| 287 | + |
| 288 | + self.assertEqual(configurations["logger_name"], "test_param_logger") |
| 289 | + |
| 290 | + @patch.dict( |
| 291 | + "os.environ", |
| 292 | + { |
| 293 | + LOGGING_FORMAT_ENV_ARG: "%(asctime)s - %(name)s - %(levelname)s - %(message)s", |
| 294 | + }, |
| 295 | + clear=True, |
| 296 | + ) |
| 297 | + def test_get_configurations_logging_format_env_var(self): |
| 298 | + configurations = _get_configurations() |
| 299 | + |
| 300 | + formatter = configurations["logging_formatter"] |
| 301 | + self.assertIsNotNone(formatter) |
| 302 | + self.assertIsInstance(formatter, Formatter) |
| 303 | + # Test that the formatter works correctly with a sample log record |
| 304 | + import logging |
| 305 | + record = logging.LogRecord( |
| 306 | + name="test_logger", |
| 307 | + level=logging.INFO, |
| 308 | + pathname="test.py", |
| 309 | + lineno=1, |
| 310 | + msg="test message", |
| 311 | + args=(), |
| 312 | + exc_info=None, |
| 313 | + ) |
| 314 | + # Type assertion for mypy |
| 315 | + assert isinstance(formatter, Formatter) |
| 316 | + formatted = formatter.format(record) |
| 317 | + self.assertIn("test_logger", formatted) |
| 318 | + self.assertIn("INFO", formatted) |
| 319 | + self.assertIn("test message", formatted) |
| 320 | + |
| 321 | + @patch.dict( |
| 322 | + "os.environ", |
| 323 | + { |
| 324 | + LOGGING_FORMAT_ENV_ARG: "invalid format %(nonexistent)z", |
| 325 | + }, |
| 326 | + clear=True, |
| 327 | + ) |
| 328 | + @patch("azure.monitor.opentelemetry._utils.configurations._logger") |
| 329 | + def test_get_configurations_logging_format_env_var_invalid_format(self, mock_logger): |
| 330 | + configurations = _get_configurations() |
| 331 | + |
| 332 | + # Should be None when format is invalid |
| 333 | + self.assertIsNone(configurations["logging_formatter"]) |
| 334 | + # Should log a warning |
| 335 | + mock_logger.warning.assert_called_once() |
| 336 | + call_args = mock_logger.warning.call_args[0] |
| 337 | + self.assertIn("Exception occurred when creating logging Formatter", call_args[0]) |
| 338 | + self.assertIn("invalid format %(nonexistent)z", call_args[1]) |
| 339 | + |
| 340 | + @patch.dict( |
| 341 | + "os.environ", |
| 342 | + { |
| 343 | + LOGGING_FORMAT_ENV_ARG: "%(asctime)s - %(message)s", |
| 344 | + }, |
| 345 | + clear=True, |
| 346 | + ) |
| 347 | + def test_get_configurations_logging_format_param_overrides_env_var(self): |
| 348 | + from logging import Formatter |
| 349 | + custom_formatter = Formatter("%(levelname)s: %(message)s") |
| 350 | + configurations = _get_configurations(logging_formatter=custom_formatter) |
| 351 | + |
| 352 | + # Parameter should override environment variable |
| 353 | + self.assertEqual(configurations["logging_formatter"], custom_formatter) |
| 354 | + |
| 355 | + @patch.dict( |
| 356 | + "os.environ", |
| 357 | + { |
| 358 | + LOGGING_FORMAT_ENV_ARG: "%(asctime)s - %(message)s", |
| 359 | + }, |
| 360 | + clear=True, |
| 361 | + ) |
| 362 | + def test_get_configurations_logging_format_invalid_param_uses_env_var(self): |
| 363 | + configurations = _get_configurations(logging_formatter="not_a_formatter") |
| 364 | + |
| 365 | + # Invalid parameter should be set to None, but env var should still be used |
| 366 | + self.assertIsNone(configurations["logging_formatter"]) |
| 367 | + |
| 368 | + @patch.dict("os.environ", {}, clear=True) |
| 369 | + def test_get_configurations_logging_format_no_env_var(self): |
| 370 | + configurations = _get_configurations() |
| 371 | + |
| 372 | + # Should not have logging_formatter key when no env var is set |
| 373 | + self.assertNotIn("logging_formatter", configurations) |
0 commit comments