|
25 | 25 | LogData,
|
26 | 26 | LoggerProvider,
|
27 | 27 | LoggingHandler,
|
28 |
| - LogLimits, |
29 | 28 | LogRecordProcessor,
|
30 | 29 | )
|
| 30 | +from opentelemetry.sdk._logs._internal import LogLimits, _UnsetLogLimits |
31 | 31 | from opentelemetry.sdk.environment_variables import OTEL_ATTRIBUTE_COUNT_LIMIT
|
32 | 32 | from opentelemetry.semconv._incubating.attributes import code_attributes
|
33 | 33 | from opentelemetry.semconv.attributes import exception_attributes
|
@@ -372,60 +372,99 @@ def test_handler_root_logger_with_disabled_sdk_does_not_go_into_recursion_error(
|
372 | 372 | @patch.dict(os.environ, {OTEL_ATTRIBUTE_COUNT_LIMIT: "3"})
|
373 | 373 | def test_otel_attribute_count_limit_respected_in_logging_handler(self):
|
374 | 374 | """Test that OTEL_ATTRIBUTE_COUNT_LIMIT is properly respected by LoggingHandler."""
|
375 |
| - processor, logger = set_up_test_logging(logging.WARNING) |
376 |
| - |
377 |
| - # Create a log record with many extra attributes |
378 |
| - extra_attrs = {f"custom_attr_{i}": f"value_{i}" for i in range(10)} |
| 375 | + # Store original values to restore later |
| 376 | + original_max_attributes = _UnsetLogLimits.max_attributes |
| 377 | + original_max_attribute_length = _UnsetLogLimits.max_attribute_length |
379 | 378 |
|
380 |
| - with self.assertLogs(level=logging.WARNING): |
381 |
| - logger.warning( |
382 |
| - "Test message with many attributes", extra=extra_attrs |
| 379 | + try: |
| 380 | + # Force _UnsetLogLimits to re-read the environment variable |
| 381 | + _UnsetLogLimits.max_attributes = ( |
| 382 | + _UnsetLogLimits._from_env_if_absent( |
| 383 | + LogLimits.UNSET, OTEL_ATTRIBUTE_COUNT_LIMIT |
| 384 | + ) |
383 | 385 | )
|
384 | 386 |
|
385 |
| - log_record = processor.get_log_record(0) |
| 387 | + processor, logger = set_up_test_logging(logging.WARNING) |
386 | 388 |
|
387 |
| - # With OTEL_ATTRIBUTE_COUNT_LIMIT=3, should have exactly 3 attributes |
388 |
| - total_attrs = len(log_record.attributes) |
389 |
| - self.assertEqual( |
390 |
| - total_attrs, |
391 |
| - 3, |
392 |
| - f"Should have exactly 3 attributes due to limit, got {total_attrs}", |
393 |
| - ) |
| 389 | + # Create a log record with many extra attributes |
| 390 | + extra_attrs = {f"custom_attr_{i}": f"value_{i}" for i in range(10)} |
394 | 391 |
|
395 |
| - # Should have 10 dropped attributes (10 custom + 3 code - 3 kept = 10 dropped) |
396 |
| - self.assertEqual( |
397 |
| - log_record.dropped_attributes, |
398 |
| - 10, |
399 |
| - f"Should have 10 dropped attributes, got {log_record.dropped_attributes}", |
400 |
| - ) |
| 392 | + with self.assertLogs(level=logging.WARNING): |
| 393 | + logger.warning( |
| 394 | + "Test message with many attributes", extra=extra_attrs |
| 395 | + ) |
| 396 | + |
| 397 | + log_record = processor.get_log_record(0) |
| 398 | + |
| 399 | + # With OTEL_ATTRIBUTE_COUNT_LIMIT=3, should have exactly 3 attributes |
| 400 | + total_attrs = len(log_record.attributes) |
| 401 | + self.assertEqual( |
| 402 | + total_attrs, |
| 403 | + 3, |
| 404 | + f"Should have exactly 3 attributes due to limit, got {total_attrs}", |
| 405 | + ) |
| 406 | + |
| 407 | + # Should have 10 dropped attributes (10 custom + 3 code - 3 kept = 10 dropped) |
| 408 | + self.assertEqual( |
| 409 | + log_record.dropped_attributes, |
| 410 | + 10, |
| 411 | + f"Should have 10 dropped attributes, got {log_record.dropped_attributes}", |
| 412 | + ) |
| 413 | + finally: |
| 414 | + # Restore original values |
| 415 | + _UnsetLogLimits.max_attributes = original_max_attributes |
| 416 | + _UnsetLogLimits.max_attribute_length = ( |
| 417 | + original_max_attribute_length |
| 418 | + ) |
401 | 419 |
|
402 | 420 | @patch.dict(os.environ, {OTEL_ATTRIBUTE_COUNT_LIMIT: "5"})
|
403 | 421 | def test_otel_attribute_count_limit_includes_code_attributes(self):
|
404 | 422 | """Test that OTEL_ATTRIBUTE_COUNT_LIMIT applies to all attributes including code attributes."""
|
405 |
| - processor, logger = set_up_test_logging(logging.WARNING) |
| 423 | + # Import _UnsetLogLimits directly |
406 | 424 |
|
407 |
| - # Create a log record with some extra attributes |
408 |
| - extra_attrs = {f"user_attr_{i}": f"value_{i}" for i in range(8)} |
| 425 | + # Store original values to restore later |
| 426 | + original_max_attributes = _UnsetLogLimits.max_attributes |
| 427 | + original_max_attribute_length = _UnsetLogLimits.max_attribute_length |
409 | 428 |
|
410 |
| - with self.assertLogs(level=logging.WARNING): |
411 |
| - logger.warning("Test message", extra=extra_attrs) |
| 429 | + try: |
| 430 | + # Force _UnsetLogLimits to re-read the environment variable |
| 431 | + _UnsetLogLimits.max_attributes = ( |
| 432 | + _UnsetLogLimits._from_env_if_absent( |
| 433 | + LogLimits.UNSET, OTEL_ATTRIBUTE_COUNT_LIMIT |
| 434 | + ) |
| 435 | + ) |
412 | 436 |
|
413 |
| - log_record = processor.get_log_record(0) |
| 437 | + # Now proceed with the test |
| 438 | + processor, logger = set_up_test_logging(logging.WARNING) |
414 | 439 |
|
415 |
| - # With OTEL_ATTRIBUTE_COUNT_LIMIT=5, should have exactly 5 attributes |
416 |
| - total_attrs = len(log_record.attributes) |
417 |
| - self.assertEqual( |
418 |
| - total_attrs, |
419 |
| - 5, |
420 |
| - f"Should have exactly 5 attributes due to limit, got {total_attrs}", |
421 |
| - ) |
| 440 | + # Create a log record with some extra attributes |
| 441 | + extra_attrs = {f"user_attr_{i}": f"value_{i}" for i in range(8)} |
422 | 442 |
|
423 |
| - # Should have 6 dropped attributes (8 user + 3 code - 5 kept = 6 dropped) |
424 |
| - self.assertEqual( |
425 |
| - log_record.dropped_attributes, |
426 |
| - 6, |
427 |
| - f"Should have 6 dropped attributes, got {log_record.dropped_attributes}", |
428 |
| - ) |
| 443 | + with self.assertLogs(level=logging.WARNING): |
| 444 | + logger.warning("Test message", extra=extra_attrs) |
| 445 | + |
| 446 | + log_record = processor.get_log_record(0) |
| 447 | + |
| 448 | + # With OTEL_ATTRIBUTE_COUNT_LIMIT=5, should have exactly 5 attributes |
| 449 | + total_attrs = len(log_record.attributes) |
| 450 | + self.assertEqual( |
| 451 | + total_attrs, |
| 452 | + 5, |
| 453 | + f"Should have exactly 5 attributes due to limit, got {total_attrs}", |
| 454 | + ) |
| 455 | + |
| 456 | + # Should have 6 dropped attributes (8 user + 3 code - 5 kept = 6 dropped) |
| 457 | + self.assertEqual( |
| 458 | + log_record.dropped_attributes, |
| 459 | + 6, |
| 460 | + f"Should have 6 dropped attributes, got {log_record.dropped_attributes}", |
| 461 | + ) |
| 462 | + finally: |
| 463 | + # Restore original values |
| 464 | + _UnsetLogLimits.max_attributes = original_max_attributes |
| 465 | + _UnsetLogLimits.max_attribute_length = ( |
| 466 | + original_max_attribute_length |
| 467 | + ) |
429 | 468 |
|
430 | 469 | def test_logging_handler_without_env_var_uses_default_limit(self):
|
431 | 470 | """Test that without OTEL_ATTRIBUTE_COUNT_LIMIT, default limit (128) should apply."""
|
@@ -456,38 +495,6 @@ def test_logging_handler_without_env_var_uses_default_limit(self):
|
456 | 495 | f"Should have 25 dropped attributes, got {log_record.dropped_attributes}",
|
457 | 496 | )
|
458 | 497 |
|
459 |
| - @patch.dict(os.environ, {OTEL_ATTRIBUTE_COUNT_LIMIT: "2"}) |
460 |
| - def test_otel_attribute_count_limit_with_exception_attributes(self): |
461 |
| - """Test that OTEL_ATTRIBUTE_COUNT_LIMIT applies even with exception attributes.""" |
462 |
| - processor, logger = set_up_test_logging(logging.ERROR) |
463 |
| - |
464 |
| - try: |
465 |
| - raise ValueError("test exception") |
466 |
| - except ValueError: |
467 |
| - with self.assertLogs(level=logging.ERROR): |
468 |
| - logger.exception( |
469 |
| - "Exception occurred", extra={"custom_attr": "value"} |
470 |
| - ) |
471 |
| - |
472 |
| - log_record = processor.get_log_record(0) |
473 |
| - |
474 |
| - # With OTEL_ATTRIBUTE_COUNT_LIMIT=2, should have exactly 2 attributes |
475 |
| - # Total available: 3 code + 3 exception + 1 custom = 7 attributes |
476 |
| - # But limited to 2, so 5 should be dropped |
477 |
| - total_attrs = len(log_record.attributes) |
478 |
| - self.assertEqual( |
479 |
| - total_attrs, |
480 |
| - 2, |
481 |
| - f"Should have exactly 2 attributes due to limit, got {total_attrs}", |
482 |
| - ) |
483 |
| - |
484 |
| - # Should have 5 dropped attributes (7 total - 2 kept = 5 dropped) |
485 |
| - self.assertEqual( |
486 |
| - log_record.dropped_attributes, |
487 |
| - 5, |
488 |
| - f"Should have 5 dropped attributes, got {log_record.dropped_attributes}", |
489 |
| - ) |
490 |
| - |
491 | 498 | def test_custom_log_limits_from_logger_provider(self):
|
492 | 499 | """Test that LoggingHandler uses custom LogLimits from LoggerProvider."""
|
493 | 500 | # Create a LoggerProvider with custom LogLimits (max_attributes=4)
|
|
0 commit comments