D-SafeLogger 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/CHANGELOG.md +16 -0
  2. {d_safelogger-0.2.0/src/D_SafeLogger.egg-info → d_safelogger-0.2.1}/PKG-INFO +5 -5
  3. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/README.md +4 -4
  4. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/README_ja.md +2 -2
  5. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/TESTING.md +10 -5
  6. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__async.md +1 -0
  7. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__pipeline.md +1 -1
  8. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/design/D-SafeLogger_DetailedDesign_v23j.md +4 -4
  9. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/design/D-SafeLogger_TestDesign_v23j.md +1 -1
  10. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/design/D-SafeLogger_v23j_WhitePaper.md +15 -15
  11. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/design/D-SafeLogger_v23j_WhitePaper_en.md +19 -19
  12. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/design/D_SafeLogger_Specification_v23j_full.md +1 -1
  13. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/design/D_SafeLogger_Specification_v23j_full_en.md +1 -1
  14. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/06_web_api_logging.md +2 -2
  15. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/pyproject.toml +1 -1
  16. {d_safelogger-0.2.0 → d_safelogger-0.2.1/src/D_SafeLogger.egg-info}/PKG-INFO +5 -5
  17. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/__init__.py +4 -1
  18. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_async.py +13 -3
  19. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_constants.py +1 -0
  20. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_formatter.py +16 -0
  21. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_pipeline.py +16 -4
  22. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_03_migration_from_stdlib.py +2 -2
  23. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_06_web_api_logging.py +16 -6
  24. d_safelogger-0.2.1/tests/examples/test_07_long_running_service.py +35 -0
  25. d_safelogger-0.2.1/tests/examples/test_08_compliance_audit.py +64 -0
  26. d_safelogger-0.2.1/tests/examples/test_09_debugging_production.py +52 -0
  27. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_11_async_performance.py +15 -15
  28. d_safelogger-0.2.1/tests/examples/test_12_multiprocess_logging.py +68 -0
  29. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_14_cli_operations.py +14 -3
  30. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_15_opentelemetry_logging.py +7 -2
  31. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_16_structlog_coexistence.py +11 -6
  32. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_17_container_collector_coexistence.py +2 -1
  33. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_async.py +31 -0
  34. d_safelogger-0.2.1/tests/test_diagnose.py +188 -0
  35. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_configure.py +16 -0
  36. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/uv.lock +1 -1
  37. d_safelogger-0.2.0/tests/examples/test_07_long_running_service.py +0 -31
  38. d_safelogger-0.2.0/tests/examples/test_08_compliance_audit.py +0 -46
  39. d_safelogger-0.2.0/tests/examples/test_09_debugging_production.py +0 -46
  40. d_safelogger-0.2.0/tests/examples/test_12_multiprocess_logging.py +0 -58
  41. d_safelogger-0.2.0/tests/test_diagnose.py +0 -66
  42. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/BENCHMARK.md +0 -0
  43. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/CONTRIBUTING.md +0 -0
  44. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/LICENSE +0 -0
  45. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/MANIFEST.in +0 -0
  46. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/SECURITY.md +0 -0
  47. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/_benchmark_report.py +0 -0
  48. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmark_20260506_180018/summary.json +0 -0
  49. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmark_20260506_180018/summary.md +0 -0
  50. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmarks_multi_integ_20260506_185947/summary.json +0 -0
  51. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmarks_multi_integ_20260506_185947/summary.md +0 -0
  52. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmarks_multi_perf_20260506_190518/summary.json +0 -0
  53. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmarks_multi_perf_20260506_190518/summary.md +0 -0
  54. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmarks_multi_resilience_20260506_211129/summary.json +0 -0
  55. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/results/benchmarks_multi_resilience_20260506_211129/summary.md +0 -0
  56. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/summary/index.md +0 -0
  57. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/summary/manifest.json +0 -0
  58. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/summary/multiprocess_integrity.md +0 -0
  59. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/summary/multiprocess_performance.md +0 -0
  60. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/summary/multiprocess_resilience.md +0 -0
  61. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/summary/single_process.md +0 -0
  62. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/benchmarks/update_summary.py +0 -0
  63. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger.md +0 -0
  64. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__cli.md +0 -0
  65. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__color.md +0 -0
  66. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__config_validation.md +0 -0
  67. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__constants.md +0 -0
  68. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__context.md +0 -0
  69. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__env_parser.md +0 -0
  70. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__formatter.md +0 -0
  71. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__handler.md +0 -0
  72. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__ini_loader.md +0 -0
  73. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__integrity.md +0 -0
  74. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__levels.md +0 -0
  75. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__logger.md +0 -0
  76. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__mp.md +0 -0
  77. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__mp_attach.md +0 -0
  78. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__mp_control.md +0 -0
  79. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__mp_protocol.md +0 -0
  80. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__mp_queue.md +0 -0
  81. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__mp_runtime.md +0 -0
  82. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__purge.md +0 -0
  83. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__routing.md +0 -0
  84. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__sink.md +0 -0
  85. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__transport.md +0 -0
  86. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__validator.md +0 -0
  87. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/dsafelogger__writer_formatter.md +0 -0
  88. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/docs/api/index.md +0 -0
  89. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/01_quick_start.md +0 -0
  90. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/02_configuration_guide.md +0 -0
  91. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/03_migration_from_stdlib.md +0 -0
  92. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/04_stdlib_ecosystem_coexistence.md +0 -0
  93. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/05_windows_service_and_scheduled_batch.md +0 -0
  94. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/07_long_running_service.md +0 -0
  95. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/08_compliance_audit.md +0 -0
  96. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/09_debugging_production.md +0 -0
  97. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/10_incident_response_bundle.md +0 -0
  98. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/11_async_performance.md +0 -0
  99. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/12_multiprocess_logging.md +0 -0
  100. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/13_external_rotation_reopen.md +0 -0
  101. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/14_cli_operations.md +0 -0
  102. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/15_opentelemetry_logging.md +0 -0
  103. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/16_structlog_coexistence.md +0 -0
  104. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/examples/17_container_collector_coexistence.md +0 -0
  105. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/setup.cfg +0 -0
  106. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/D_SafeLogger.egg-info/SOURCES.txt +0 -0
  107. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/D_SafeLogger.egg-info/dependency_links.txt +0 -0
  108. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/D_SafeLogger.egg-info/entry_points.txt +0 -0
  109. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/D_SafeLogger.egg-info/top_level.txt +0 -0
  110. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_cli.py +0 -0
  111. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_color.py +0 -0
  112. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_config_validation.py +0 -0
  113. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_context.py +0 -0
  114. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_env_parser.py +0 -0
  115. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_handler.py +0 -0
  116. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_ini_loader.py +0 -0
  117. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_integrity.py +0 -0
  118. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_levels.py +0 -0
  119. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_logger.py +0 -0
  120. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_mp_attach.py +0 -0
  121. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_mp_control.py +0 -0
  122. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_mp_protocol.py +0 -0
  123. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_mp_queue.py +0 -0
  124. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_mp_runtime.py +0 -0
  125. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_purge.py +0 -0
  126. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_routing.py +0 -0
  127. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_sink.py +0 -0
  128. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_transport.py +0 -0
  129. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_validator.py +0 -0
  130. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/_writer_formatter.py +0 -0
  131. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/mp/__init__.py +0 -0
  132. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/src/dsafelogger/py.typed +0 -0
  133. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/conftest.py +0 -0
  134. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_04_stdlib_ecosystem_coexistence.py +0 -0
  135. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_05_windows_service_and_scheduled_batch.py +0 -0
  136. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_10_incident_response_bundle.py +0 -0
  137. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/examples/test_13_external_rotation_reopen.py +0 -0
  138. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_cli.py +0 -0
  139. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_color.py +0 -0
  140. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_configure.py +0 -0
  141. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_context.py +0 -0
  142. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_coverage_boost.py +0 -0
  143. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_env_parser.py +0 -0
  144. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_formatter.py +0 -0
  145. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_getlogger.py +0 -0
  146. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_handler.py +0 -0
  147. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_ini_loader.py +0 -0
  148. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_integration.py +0 -0
  149. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_integrity.py +0 -0
  150. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_levels.py +0 -0
  151. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_logger.py +0 -0
  152. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_merge.py +0 -0
  153. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_attach.py +0 -0
  154. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_control.py +0 -0
  155. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_fork.py +0 -0
  156. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_formatter.py +0 -0
  157. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_integration.py +0 -0
  158. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_runtime.py +0 -0
  159. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_mp_spawn_windows.py +0 -0
  160. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_opentelemetry.py +0 -0
  161. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_pipeline.py +0 -0
  162. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_purge.py +0 -0
  163. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_reopen.py +0 -0
  164. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_routing.py +0 -0
  165. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_structlog.py +0 -0
  166. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_transport.py +0 -0
  167. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_validator.py +0 -0
  168. {d_safelogger-0.2.0 → d_safelogger-0.2.1}/tests/test_version.py +0 -0
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.1] - 2026-05-20
9
+
10
+ ### Fixed
11
+ - Apply resolved `sens_kws` / `sens_kws_replace` to diagnostic local-variable snapshots across sync text, sync structured, async snapshot, and multiprocess Writer formatter paths.
12
+ - Preserve async producer-side diagnostic frame snapshots in text diagnostic output.
13
+ - Align daily routing examples with the implemented `YYYYMMDD` filename suffix.
14
+
15
+ ### Changed
16
+ - Updated example tests to match the documented runnable examples for migration, web API, long-running service, compliance audit, production debugging, async performance, multiprocess logging, CLI operations, OpenTelemetry, structlog, and container collector coexistence scenarios.
17
+ - Updated public docs, API docs, and test/coverage baselines for the 0.2.1 patch release.
18
+
19
+ ### Verified
20
+ - Full local validation on Python 3.14.3 / Windows: `658 passed, 3 skipped` (`661` collected).
21
+ - Coverage validation regenerated `coverage.xml`: terminal total `87%`, line-rate `88.97%`, branch-rate `81.46%`.
22
+ - API docs, design-doc sync, and whitespace checks pass; `git diff --check` reports only CRLF/LF warnings.
23
+
8
24
  ## [0.2.0] - 2026-05-05
9
25
 
10
26
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: D-SafeLogger
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Zero-dependency, thread-safe, append-only logging library for Python with 3-layer config pipeline
5
5
  Author: D
6
6
  License-Expression: Apache-2.0
@@ -28,8 +28,8 @@ Dynamic: license-file
28
28
  # D-SafeLogger
29
29
 
30
30
  [![CI](https://github.com/nightmarewalker/D-SafeLogger/actions/workflows/ci.yml/badge.svg)](https://github.com/nightmarewalker/D-SafeLogger/actions/workflows/ci.yml)
31
- [![PyPI version](https://img.shields.io/pypi/v/d-safelogger.svg)](https://pypi.org/project/d-safelogger/)
32
- [![Python](https://img.shields.io/pypi/pyversions/d-safelogger.svg)](https://pypi.org/project/d-safelogger/)
31
+ [![PyPI version](https://img.shields.io/pypi/v/d-safelogger.svg?cacheSeconds=3600)](https://pypi.org/project/d-safelogger/)
32
+ [![Python](https://img.shields.io/pypi/pyversions/d-safelogger.svg?cacheSeconds=3600)](https://pypi.org/project/d-safelogger/)
33
33
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
34
34
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](#main-features)
35
35
 
@@ -66,7 +66,7 @@ logger = GetLogger(__name__)
66
66
  logger.info("Application started")
67
67
  ```
68
68
 
69
- `pg_name` is the application name used as the prefix of routed log file names, for example `MyApp_2026-04-03.log`.
69
+ `pg_name` is the application name used as the prefix of routed log file names, for example `MyApp_20260403.log`.
70
70
 
71
71
  Typical text output:
72
72
 
@@ -122,7 +122,7 @@ The "Safe" in the name is a design stance that runs across several dimensions of
122
122
 
123
123
  - **Startup safety:** invalid settings, inconsistent options, and unwritable destinations fail during setup. D-SafeLogger stops a broken logging configuration before the application starts doing real work, instead of silently degrading later.
124
124
  - **File safety:** the routing layer opens the next destination instead of renaming or truncating the active log file, which avoids the common Windows failure mode where active log files cannot be renamed. It also avoids the POSIX case where a successful rename leaves the writer appending to the previous file. Routed files can be paired with SHA-256 sidecars and an optional manifest, so log content is verifiable after the fact.
125
- - **Record and context safety:** request IDs, user IDs, job IDs, and other context are snapshotted on the producer side at hand-off, so listeners and Writers do not depend on live `contextvars`. Sensitive-keyword masking is applied on the Writer side using the keyword set established at configure time.
125
+ - **Record and context safety:** request IDs, user IDs, job IDs, and other context are snapshotted on the producer side at hand-off, so listeners and Writers do not depend on live `contextvars`. Diagnostic local-variable snapshots and Writer-side formatting use the sensitive-keyword set established at configure time.
126
126
  - **Operational control:** environment variables provide explicit runtime overrides for diagnostics, routing, hashing, log levels, and queue/timeout behavior without rebuilding or editing application code.
127
127
  - **Concurrency and multiprocess safety:** multiprocess workers do not open the shared log files themselves. A parent-side Writer owns the sinks and accepts records over IPC, with bounded queues and explicit timeouts that keep the host process from unbounded waits.
128
128
  - **Failure observability:** when records cannot be delivered, the runtime classifies the outcome where it can: `KnownRejected`, `KnownDropped`, or `UnexplainedLost`. Counters and shutdown summaries make abnormal scenarios describable rather than silent.
@@ -1,8 +1,8 @@
1
1
  # D-SafeLogger
2
2
 
3
3
  [![CI](https://github.com/nightmarewalker/D-SafeLogger/actions/workflows/ci.yml/badge.svg)](https://github.com/nightmarewalker/D-SafeLogger/actions/workflows/ci.yml)
4
- [![PyPI version](https://img.shields.io/pypi/v/d-safelogger.svg)](https://pypi.org/project/d-safelogger/)
5
- [![Python](https://img.shields.io/pypi/pyversions/d-safelogger.svg)](https://pypi.org/project/d-safelogger/)
4
+ [![PyPI version](https://img.shields.io/pypi/v/d-safelogger.svg?cacheSeconds=3600)](https://pypi.org/project/d-safelogger/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/d-safelogger.svg?cacheSeconds=3600)](https://pypi.org/project/d-safelogger/)
6
6
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
7
7
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](#main-features)
8
8
 
@@ -39,7 +39,7 @@ logger = GetLogger(__name__)
39
39
  logger.info("Application started")
40
40
  ```
41
41
 
42
- `pg_name` is the application name used as the prefix of routed log file names, for example `MyApp_2026-04-03.log`.
42
+ `pg_name` is the application name used as the prefix of routed log file names, for example `MyApp_20260403.log`.
43
43
 
44
44
  Typical text output:
45
45
 
@@ -95,7 +95,7 @@ The "Safe" in the name is a design stance that runs across several dimensions of
95
95
 
96
96
  - **Startup safety:** invalid settings, inconsistent options, and unwritable destinations fail during setup. D-SafeLogger stops a broken logging configuration before the application starts doing real work, instead of silently degrading later.
97
97
  - **File safety:** the routing layer opens the next destination instead of renaming or truncating the active log file, which avoids the common Windows failure mode where active log files cannot be renamed. It also avoids the POSIX case where a successful rename leaves the writer appending to the previous file. Routed files can be paired with SHA-256 sidecars and an optional manifest, so log content is verifiable after the fact.
98
- - **Record and context safety:** request IDs, user IDs, job IDs, and other context are snapshotted on the producer side at hand-off, so listeners and Writers do not depend on live `contextvars`. Sensitive-keyword masking is applied on the Writer side using the keyword set established at configure time.
98
+ - **Record and context safety:** request IDs, user IDs, job IDs, and other context are snapshotted on the producer side at hand-off, so listeners and Writers do not depend on live `contextvars`. Diagnostic local-variable snapshots and Writer-side formatting use the sensitive-keyword set established at configure time.
99
99
  - **Operational control:** environment variables provide explicit runtime overrides for diagnostics, routing, hashing, log levels, and queue/timeout behavior without rebuilding or editing application code.
100
100
  - **Concurrency and multiprocess safety:** multiprocess workers do not open the shared log files themselves. A parent-side Writer owns the sinks and accepts records over IPC, with bounded queues and explicit timeouts that keep the host process from unbounded waits.
101
101
  - **Failure observability:** when records cannot be delivered, the runtime classifies the outcome where it can: `KnownRejected`, `KnownDropped`, or `UnexplainedLost`. Counters and shutdown summaries make abnormal scenarios describable rather than silent.
@@ -39,7 +39,7 @@ logger = GetLogger(__name__)
39
39
  logger.info("Application started")
40
40
  ```
41
41
 
42
- `pg_name` はルーティング後のログファイル名の接頭辞として使われるアプリケーション名です。例: `MyApp_2026-04-03.log`。
42
+ `pg_name` はルーティング後のログファイル名の接頭辞として使われるアプリケーション名です。例: `MyApp_20260403.log`。
43
43
 
44
44
  標準的なテキスト出力:
45
45
 
@@ -95,7 +95,7 @@ D-SafeLogger は、active file を後から動かす代わりに、書き込み
95
95
 
96
96
  - **起動時の安全性:** 不正な設定値、矛盾したオプション、書き込めない出力先は初期化時に失敗させます。壊れた logging 構成のまま本体処理を進め、あとから気づきにくい形で動作が崩れることを防ぎます。
97
97
  - **ファイルの安全性:** ルーティング層は使用中のログファイルを rename / truncate せず、境界到達時に次の出力先を開きます。これにより active file の rename に起因する Windows 特有の失敗を避けられます。また、POSIX 系で rename が成功しても writer が古い file descriptor へ書き続ける、という世代切り替えのずれも避けられます。ルーティング済みファイルには SHA-256 sidecar と、任意で manifest を付けられ、後からログ内容を検証できます。
98
- - **レコードとコンテキストの安全性:** request ID、user ID、job ID といったコンテキストは producer 側で snapshot を取り、listener / Writer 側では live な `contextvars` を参照しません。機微情報のマスキングは Writer 側で、初期化時に確定したキーワード集合を使って適用されます。
98
+ - **レコードとコンテキストの安全性:** request ID、user ID、job ID といったコンテキストは producer 側で snapshot を取り、listener / Writer 側では live な `contextvars` を参照しません。diagnostic のローカル変数 snapshot と Writer 側 formatting では、初期化時に確定した機微情報キーワード集合を使います。
99
99
  - **運用時の制御:** 環境変数により、コードを変更せずにログレベル、診断出力、モジュール別ルーティング、ハッシュ出力、キュー / timeout 設定を切り替えられます。
100
100
  - **並行性とマルチプロセスの安全性:** マルチプロセスでは worker が共有のログファイルを直接開かず、親プロセス側の Writer が出力先を所有して IPC でレコードを受け付けます。上限つきのキューと明示的な timeout により、本体プロセスが無制限に待ち続けることを避けます。
101
101
  - **失敗の可観測性:** 配送できなかったレコードは、可能な範囲で `KnownRejected` / `KnownDropped` / `UnexplainedLost` のいずれかに分類されます。カウンタと shutdown summary により、異常時のふるまいが見落とされず、説明できる形で残ります。
@@ -29,8 +29,8 @@ uv run pytest tests -v
29
29
  Current v23j local validation on Python 3.14.3 / Windows:
30
30
 
31
31
  ```text
32
- 651 passed, 3 skipped
33
- 654 collected
32
+ 658 passed, 3 skipped
33
+ 661 collected
34
34
  ```
35
35
 
36
36
  The collected test count is the baseline. The number of skipped tests is platform-dependent because fork E2E tests are POSIX-only and Windows spawn E2E tests are Windows-only.
@@ -38,9 +38,9 @@ The collected test count is the baseline. The number of skipped tests is platfor
38
38
  Latest coverage validation generated `coverage.xml` on Python 3.14.3 / Windows:
39
39
 
40
40
  ```text
41
- TOTAL coverage: 86%
42
- XML line-rate: 88.49%
43
- XML branch-rate: 80.53%
41
+ TOTAL coverage: 87%
42
+ XML line-rate: 88.97%
43
+ XML branch-rate: 81.46%
44
44
  ```
45
45
 
46
46
  `coverage.xml`, `.coverage`, and `htmlcov/` are local/CI artifacts and are ignored by `.gitignore`; keep coverage numbers in documentation, not the generated files themselves.
@@ -112,6 +112,11 @@ uv run pytest tests -x -v
112
112
  | Third-party coexistence | `tests/test_opentelemetry.py`, `tests/test_structlog.py` |
113
113
  | Branch coverage edge cases | `tests/test_coverage_boost.py` |
114
114
 
115
+ Diagnostic masking coverage must include both component-level checks and
116
+ configuration-to-output integration checks. In particular, `sens_kws` and
117
+ `sens_kws_replace` are validated through `ConfigureLogger(...)` into sync text,
118
+ sync structured, async snapshot, and multiprocess Writer formatter paths.
119
+
115
120
  ## Multiprocess Test Policy
116
121
 
117
122
  `dsafelogger.mp` is a formal feature, so multiprocess tests are part of the standard quality gate.
@@ -33,5 +33,6 @@ Public methods:
33
33
 
34
34
  | Name | Type | Value |
35
35
  |---|---|---|
36
+ | `MASK_STRING` | `str` | `'*** MASKED ***'` |
36
37
  | `QUEUE_DRAIN_TIMEOUT_SEC` | `float` | `10.0` |
37
38
  | `WORKER_JOIN_TIMEOUT_SEC` | `float` | `5.0` |
@@ -41,6 +41,6 @@ Public methods:
41
41
 
42
42
  - `build(self, config: 'ResolvedConfig') -> 'Pipeline'`
43
43
 
44
- ### `ResolvedConfig(pg_name: 'str', log_dir: 'Path', file_fmt: 'str | FormatterConfigDict | logging.Formatter', console_fmt: 'str | FormatterConfigDict | logging.Formatter', routing_mode: 'str', routing_kwargs: 'dict', backup_count: 'int', archive_mode: 'bool', enable_hash: 'bool', manifest_path: 'Path | None', encoding: 'str', diagnose: 'bool', max_level: 'str', console: 'bool', is_async: 'bool', queue_size: 'int', log_level: 'str', color_stream: 'bool', module_configs: 'dict[str, dict]', color_overrides: 'dict[str, str]') -> None`
44
+ ### `ResolvedConfig(pg_name: 'str', log_dir: 'Path', file_fmt: 'str | FormatterConfigDict | logging.Formatter', console_fmt: 'str | FormatterConfigDict | logging.Formatter', routing_mode: 'str', routing_kwargs: 'dict', backup_count: 'int', archive_mode: 'bool', enable_hash: 'bool', manifest_path: 'Path | None', encoding: 'str', diagnose: 'bool', max_level: 'str', console: 'bool', is_async: 'bool', queue_size: 'int', log_level: 'str', color_stream: 'bool', module_configs: 'dict[str, dict]', color_overrides: 'dict[str, str]', sensitive_keywords: 'frozenset[str]' = <factory>) -> None`
45
45
 
46
46
  Resolved configuration holding 3-layer merged parameters.
@@ -3328,10 +3328,10 @@ def write_sidecar(file_path: Path, hash_value: str | None = None) -> None:
3328
3328
  #### 出力例
3329
3329
 
3330
3330
  ```
3331
- a1b2c3d4e5f6789...(64文字の16進SHA-256ハッシュ) MyApp_2026-03-28.log
3331
+ a1b2c3d4e5f6789...(64文字の16進SHA-256ハッシュ) MyApp_20260328.log
3332
3332
  ```
3333
3333
 
3334
- 検証: `sha256sum -c MyApp_2026-03-28.log.sha256`
3334
+ 検証: `sha256sum -c MyApp_20260328.log.sha256`
3335
3335
 
3336
3336
  ### 15.4. マニフェスト追記
3337
3337
 
@@ -3365,8 +3365,8 @@ def append_manifest(file_path: Path, manifest_path: Path, hash_value: str | None
3365
3365
  #### マニフェストフォーマット
3366
3366
 
3367
3367
  ```
3368
- [2026-03-28T23:59:59.123] a1b2c3d4e5f6789... MyApp_2026-03-28.log
3369
- [2026-03-29T23:59:59.456] b2c3d4e5f6789a1... MyApp_2026-03-29.log
3368
+ [2026-03-28T23:59:59.123] a1b2c3d4e5f6789... MyApp_20260328.log
3369
+ [2026-03-29T23:59:59.456] b2c3d4e5f6789a1... MyApp_20260329.log
3370
3370
  ```
3371
3371
 
3372
3372
  各行の構成: `[ISO8601タイムスタンプ] SHA-256ハッシュ ファイル名`
@@ -9,7 +9,7 @@
9
9
 
10
10
  v23j は v23h 完了時点の OSS 公開前指摘に対するユーザー判断に基づく修正版である。v23h の sink 分類 / bounded shutdown 契約を維持した上で、公開前のテスト契約・MP E2E・benchmark 成果物管理を確定する。
11
11
 
12
- 現行 v23j のローカル検証 baseline は Python 3.14.3 / Windows 上の結果であり、`651 passed, 3 skipped`(`654` collected)である。fork E2E は POSIX-only、Windows spawn E2E は Windows-only であるため、OS によって skipped 数は変動し得る。
12
+ 現行 v23j のローカル検証 baseline は Python 3.14.3 / Windows 上の結果であり、`658 passed, 3 skipped`(`661` collected)である。fork E2E は POSIX-only、Windows spawn E2E は Windows-only であるため、OS によって skipped 数は変動し得る。
13
13
 
14
14
  v23h から継続する動作変更は以下:
15
15
 
@@ -16,7 +16,7 @@ SPDX-FileCopyrightText: 2026 D-SafeLogger contributors
16
16
  | 文書バージョン | 1.0 |
17
17
  | 発行日 | 2026-05-09 |
18
18
  | 対象ライブラリ | **D-SafeLogger v23j** |
19
- | pyproject バージョン | `0.2.0` |
19
+ | pyproject バージョン | `0.2.1` |
20
20
  | import name | `dsafelogger` |
21
21
  | distribution name | `d-safelogger` |
22
22
  | ライセンス | Apache License 2.0 |
@@ -879,7 +879,7 @@ class DSafeFormatter(logging.Formatter):
879
879
 
880
880
  - `is_async=True` 時、producer thread 側で:
881
881
  - `contextualize()` 情報を `LogRecord` の private 属性 (`_ds_context`) へスナップショット
882
- - `diagnose=True` かつ `exc_info` ありの場合のみ `f_locals` repr 済みスナップショットに変換 (`_ds_diag_frames`)
882
+ - `diagnose=True` かつ `exc_info` ありの場合のみ `f_locals` をマスク済み repr スナップショットに変換 (`_ds_diag_frames`)
883
883
  - consumer thread 側では live `contextvars` を参照せず、producer 側 snapshot を優先使用。
884
884
  - multiprocess 版で `is_async=True` を併用すると **process-local async queue + multiprocess log queue + Writer dispatch の二重キューイング**になる。通常は `is_async=False` で十分。
885
885
 
@@ -1390,7 +1390,7 @@ bounded wait → visible reject/drop → process survives
1390
1390
 
1391
1391
  free-threaded build では実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。
1392
1392
 
1393
- - queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を**安全な repr 済みスナップショット**に変換。
1393
+ - queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を**安全なマスク済み repr スナップショット**に変換。
1394
1394
  - consumer thread 側では live 参照を行わない。
1395
1395
 
1396
1396
  フォールバック規則:
@@ -2370,7 +2370,7 @@ auth, credential, private, cert
2370
2370
 
2371
2371
  設計書 §9.4:
2372
2372
 
2373
- > free-threaded build では、実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。したがって、queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を**安全な repr 済みスナップショット**に変換し、consumer thread 側では live 参照を行わない。
2373
+ > free-threaded build では、実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。したがって、queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を**安全なマスク済み repr スナップショット**に変換し、consumer thread 側では live 参照を行わない。
2374
2374
  > (`docs/design/D_SafeLogger_Specification_v23j_full.md` §9.4)
2375
2375
 
2376
2376
  これは security ではなく correctness の話であるが、free-threaded 環境での「他スレッドの内部状態を意図せず参照してしまう」事故を排除する点で、データ漏洩リスクの低減にもつながる。
@@ -3467,7 +3467,7 @@ class QueueTransport(Transport):
3467
3467
  producer thread 側の責務:
3468
3468
 
3469
3469
  - `contextualize()` 情報を `LogRecord` の private 属性 `_ds_context` へ snapshot
3470
- - `diagnose=True` かつ `exc_info` ありの場合のみ `f_locals` repr 済みスナップショットに変換 (`_ds_diag_frames`)
3470
+ - `diagnose=True` かつ `exc_info` ありの場合のみ `f_locals` をマスク済み repr スナップショットに変換 (`_ds_diag_frames`)
3471
3471
  - 通常ログでは copy + context snapshot の軽量 hand-off
3472
3472
 
3473
3473
  #### 5.9.3 安全な終了の保証レベル
@@ -4099,7 +4099,7 @@ dsafelogger init | less
4099
4099
 
4100
4100
  設計書 §9.4:
4101
4101
 
4102
- > free-threaded build では、実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。したがって、queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を**安全な repr 済みスナップショット**に変換し、consumer thread 側では live 参照を行わない。
4102
+ > free-threaded build では、実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。したがって、queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を**安全なマスク済み repr スナップショット**に変換し、consumer thread 側では live 参照を行わない。
4103
4103
  > (`docs/design/D_SafeLogger_Specification_v23j_full.md` §9.4)
4104
4104
 
4105
4105
  #### 5.19.4 thread 境界の意味論
@@ -5103,7 +5103,7 @@ stdlib 公式が明文化している Windows rename 不能制約に対し、Pyt
5103
5103
  - 設計書 §1 が **Python 3.13 以上の free-threaded build を設計対象として明示**
5104
5104
  - 設計書 §2 が「`_configure_state`、`_active_pipeline`、`_active_workers`、`_custom_levels` 等の共有状態は GIL の存在を前提にせず、明示ロックにより保護する。`list` / `dict` の実装依存の原子性には依存しない」と規定
5105
5105
  - v21 改訂で `ConfigureLogger` 全体を `_lifecycle_lock` 保持下で実行
5106
- - `f_locals` を producer thread repr 済みスナップショットに変換(cross-thread 安全性、§9.4)
5106
+ - `f_locals` を producer thread でマスク済み repr スナップショットに変換(cross-thread 安全性、§9.4)
5107
5107
  - 内部 thread を空 `Context` で開始(§9.5)
5108
5108
  - ピュア Python 実装のため `Py_mod_gil` 対応(C 拡張側)の必要がない
5109
5109
  - `TESTING.md` に手動テスト手順掲載: `PYTHON_GIL=0 uvx --python cpython-3.13+freethreaded --from pytest pytest tests -v`
@@ -5338,9 +5338,9 @@ OSS 公開時には国内・海外双方からの評価軸が想定されるが
5338
5338
  #### 7.10.3 品質ゲート
5339
5339
 
5340
5340
  `TESTING.md` および公開検証手順:
5341
- - v23j ローカル検証(Python 3.14.3 / Windows): **651 passed, 3 skipped**(収集 654、`uv run pytest tests -v`)
5341
+ - v23j ローカル検証(Python 3.14.3 / Windows): **658 passed, 3 skipped**(収集 661、`uv run pytest tests -v`)
5342
5342
  - skipped 数は OS 依存。fork E2E は POSIX-only、Windows spawn E2E は Windows-only であるため、CI matrix では OS により skipped 数が変動し得る。
5343
- - カバレッジ: terminal total **86%**, XML line-rate **88.49%**, branch-rate **80.53%**
5343
+ - カバレッジ: terminal total **87%**, XML line-rate **88.97%**, branch-rate **81.46%**
5344
5344
  - multiprocess tests / OTel・structlog coexistence tests は公式品質ゲートに含まれる
5345
5345
  - free-threaded build テスト: `PYTHON_GIL=0 uvx --python cpython-3.13+freethreaded --from pytest pytest tests -v`
5346
5346
 
@@ -5355,7 +5355,7 @@ OSS 公開時には国内・海外双方からの評価軸が想定されるが
5355
5355
  #### 7.10.5 公開時のステータス
5356
5356
 
5357
5357
  公開前レビュー記録(2026-05-07 時点):
5358
- - 現在の公開対象バージョン: `0.2.0`
5358
+ - 現在の公開対象バージョン: `0.2.1`
5359
5359
  - 最新公開前レビュー結果: **GO-with-fixes**
5360
5360
  - 公開前必須修正項目(release blocker)が列挙されている
5361
5361
 
@@ -5429,7 +5429,7 @@ OSS 公開時には国内・海外双方からの評価軸が想定されるが
5429
5429
  7. **海外特有の対応軸**: PEP 703 先行採用傾向 / Executive Order 14028 等のサプライチェーン規制要件化 / 大規模 microservice 構成。examples / README 英語、Apache 2.0、依存ゼロが対応軸。
5430
5430
  8. **設計目的が「広範な普及」ではないことが明示されている**: 設計書 §1 は「広く普及させる目的よりも、D エコシステムの共通基盤として運用することを最優先とする」と宣言しており、これは「特定の運用要件を持つ subset 組織への対応」を優先する設計姿勢として観測される。
5431
5431
  9. **失敗の境界を能動的に明示するドキュメント運用**: `examples/08_compliance_audit.md` の Threat Model / `examples/12_multiprocess_logging.md` の Writer does not guarantee / `BENCHMARK.md` の What Not To Claim / 設計書 §7.6.7 の HMAC スコープ外宣言 / 設計書 §11.2 の remote aggregation スコープ外宣言。これらは「過剰な期待による誤用を防ぐ」運用姿勢として一貫している。
5432
- 10. **品質ゲートの透明性**: Python 3.14.3 / Windows で 651 passed / 3 skipped(収集 654)、カバレッジ 86% terminal、free-threaded build テスト手順、`scripts/check_design_docs_sync.py` および `scripts/generate_api_docs.py --check` による内部同期検証、`benchmarks/summary/manifest.json` による benchmark セッション固定。skipped 数は OS 依存で変動し得る。これらは導入候補ライブラリの評価時に観測可能な品質指標として記録される。
5432
+ 10. **品質ゲートの透明性**: Python 3.14.3 / Windows で 658 passed / 3 skipped(収集 661)、カバレッジ 87% terminal、free-threaded build テスト手順、`scripts/check_design_docs_sync.py` および `scripts/generate_api_docs.py --check` による内部同期検証、`benchmarks/summary/manifest.json` による benchmark セッション固定。skipped 数は OS 依存で変動し得る。これらは導入候補ライブラリの評価時に観測可能な品質指標として記録される。
5433
5433
  11. **配布構造の明確性**: wheel は runtime package files のみを含み、`py.typed` を同梱する。sdist は公開検証・再現性のため docs / examples / tests / benchmark summaries / selected benchmark summaries を含む。private planning materials と一時作業ファイルは含めない。
5434
5434
  12. **competitor との関係は競合ではなく責務分離**: structlog(フロントエンド)/ OTel(emission)/ Loguru(DX 置換)/ picologging(速度差別化)/ logfire(SaaS)/ Eliot(causal)は責務軸が異なり、本ライブラリと共存または並走する。Loguru の 23.9k stars 等の知名度指標は、設計軸の比較とは独立した文脈である。
5435
5435
 
@@ -5706,8 +5706,8 @@ structlog(2 パターンで共存)/ OpenTelemetry Python(`LoggingHandler`
5706
5706
 
5707
5707
  #### 8.7.2 品質ゲート
5708
5708
 
5709
- - 公式テスト baseline: 651 passed / 3 skipped(収集 654、`uv run pytest tests -v`、Python 3.14.3 / Windows)。fork E2E は POSIX-only、Windows spawn E2E は Windows-only のため、OS によって skipped 数は変動し得る。
5710
- - カバレッジ: terminal total 86%, XML line-rate 88.49%, branch-rate 80.53%
5709
+ - 公式テスト baseline: 658 passed / 3 skipped(収集 661、`uv run pytest tests -v`、Python 3.14.3 / Windows)。fork E2E は POSIX-only、Windows spawn E2E は Windows-only のため、OS によって skipped 数は変動し得る。
5710
+ - カバレッジ: terminal total 87%, XML line-rate 88.97%, branch-rate 81.46%
5711
5711
  - multiprocess tests / OTel・structlog coexistence tests は公式品質ゲートに含まれる
5712
5712
  - free-threaded build テスト手順あり(`PYTHON_GIL=0 uvx ...`)
5713
5713
  - `scripts/check_design_docs_sync.py` および `scripts/generate_api_docs.py --check` で内部同期検証
@@ -5722,7 +5722,7 @@ structlog(2 パターンで共存)/ OpenTelemetry Python(`LoggingHandler`
5722
5722
  - `pyproject.toml` ランタイム依存ゼロ
5723
5723
  - wheel は `src/dsafelogger/` 配下の runtime package files のみを含む
5724
5724
  - sdist は docs / examples / tests / benchmark summaries / selected benchmark summaries を含み、private planning materials と一時作業ファイルは含めない
5725
- - 公開対象バージョン: 0.2.0
5725
+ - 公開対象バージョン: 0.2.1
5726
5726
  - 最新公開前レビュー結果: GO-with-fixes(2026-05-07)
5727
5727
 
5728
5728
  #### 8.7.4 ドキュメント運用の特徴
@@ -5760,7 +5760,7 @@ structlog(2 パターンで共存)/ OpenTelemetry Python(`LoggingHandler`
5760
5760
 
5761
5761
  #### 8.8.5 ドキュメント・品質運用
5762
5762
 
5763
- 10. **品質ゲートと内部同期検証スクリプトが整備されている**: Python 3.14.3 / Windows で 651 passed / 3 skipped(収集 654)、カバレッジ 86%、`scripts/check_design_docs_sync.py` と `scripts/generate_api_docs.py --check` による内部同期検証、`benchmarks/summary/manifest.json` による公開代表セッション固定。skipped 数は OS 依存で変動し得る。これらは導入候補ライブラリの評価時に観測可能な品質指標として記録される。
5763
+ 10. **品質ゲートと内部同期検証スクリプトが整備されている**: Python 3.14.3 / Windows で 658 passed / 3 skipped(収集 661)、カバレッジ 87%、`scripts/check_design_docs_sync.py` と `scripts/generate_api_docs.py --check` による内部同期検証、`benchmarks/summary/manifest.json` による公開代表セッション固定。skipped 数は OS 依存で変動し得る。これらは導入候補ライブラリの評価時に観測可能な品質指標として記録される。
5764
5764
 
5765
5765
  ---
5766
5766
 
@@ -15,7 +15,7 @@ SPDX-FileCopyrightText: 2026 D-SafeLogger contributors
15
15
  | Document version | 1.0 |
16
16
  | Publication date | 2026-05-09 |
17
17
  | Target library | **D-SafeLogger v23j** |
18
- | pyproject version | `0.2.0` |
18
+ | pyproject version | `0.2.1` |
19
19
  | import name | `dsafelogger` |
20
20
  | distribution name | `d-safelogger` |
21
21
  | License | Apache License 2.0 |
@@ -242,7 +242,7 @@ The `README.md` Overview section organizes Safe into six operational dimensions.
242
242
  |---|---|
243
243
  | **Startup safety** | Invalid settings, inconsistent options, and non-writable destinations cause **setup to fail** instead of letting the application enter production with broken logging. |
244
244
  | **File safety** | The routing layer does not rename or truncate the active log file. It switches output by opening the next append-only destination, avoiding common Windows rename failures and POSIX-style stale-FD failure modes while enabling post-mortem verification with SHA-256 sidecars and manifests. |
245
- | **Record / context safety** | Request ID, user ID, job ID, and similar context are **snapshotted** at producer-side hand-off. Listeners and writers do not depend on live `contextvars`, and sensitive keyword masking is applied on the Writer side. |
245
+ | **Record / context safety** | Request ID, user ID, job ID, and similar context are **snapshotted** at producer-side hand-off. Listeners and writers do not depend on live `contextvars`; diagnostic snapshots and Writer-side formatting use the sensitive-keyword set established at configure time. |
246
246
  | **Operational control** | Diagnostics, routing, hashing, log level, queue/timeout can be overwritten with environment variables without rebuilding or editing. |
247
247
  | **Concurrency / multiprocess safety** | Multiprocess workers **do not open shared log files directly**. The parent-side Writer owns the sink and accepts records via IPC. Bounded queues and explicit timeouts prevent the host process from waiting indefinitely. |
248
248
  | **Failure observability** | Delivery failures are **classified** as `KnownRejected` / `KnownDropped` / `UnexplainedLost`, making log loss describable as counters and shutdown summaries instead of invisible gaps in a file. |
@@ -696,7 +696,7 @@ Detailed design document §15a stipulates. The Transport layer is an abstraction
696
696
  Design documents §9.3 and §11.17:
697
697
  - At `is_async=True`, on the producer thread side:
698
698
  - Snapshot `contextualize()` information to private attribute (`_ds_context`) of `LogRecord`
699
- - Convert `f_locals` to repr-converted snapshot only when `diagnose=True` and `exc_info` are present (`_ds_diag_frames`)
699
+ - Convert `f_locals` to a masked, repr-converted snapshot only when `diagnose=True` and `exc_info` are present (`_ds_diag_frames`)
700
700
  - The consumer thread side does not refer to live `contextvars`, and preferentially uses the producer side snapshot.
701
701
  - When used with `is_async=True` in the multiprocess version, it becomes double queuing of **process-local async queue + multiprocess log queue + Writer dispatch**. Usually `is_async=False` is sufficient.
702
702
  #### 2.5.3 No-Copy Snapshot (FrozenContext)
@@ -1061,7 +1061,7 @@ The design document clearly states the policy of not relying on the existence of
1061
1061
  - The independent `self._lock` of `AppendOnlyFileHandler` has been abolished in v21 and unified to the `acquire()` / `release()` API of the parent class `logging.Handler` (double lock overhead eliminated).
1062
1062
  #### 2.10.2 cross-thread safety (§9.4)
1063
1063
  In a free-threaded build, a `f_locals` live reference to the frame of another running thread is unsafe.
1064
- - If a cross-queue hand-off occurs, traceback and `f_locals` are converted to a **safe repr-converted snapshot** on the producer thread side.
1064
+ - If a cross-queue hand-off occurs, traceback and `f_locals` are converted to a **safe masked, repr-converted snapshot** on the producer thread side.
1065
1065
  - No live references are made on the consumer thread side.
1066
1066
  Fallback rules:
1067
1067
  1. Use queue hand-off diagnostic snapshot if available
@@ -1620,7 +1620,7 @@ These points are revisited in the next chapter, “4. Security,” as safety asp
1620
1620
  |---|---|
1621
1621
  | **Startup safety** | Reject invalid settings and unwritable paths during setup → Structurally eliminate situations where "it appears to be working with broken settings" |
1622
1622
  | **File safety** | Do not rename/truncate → Structurally avoids the problem of not being able to rename Windows active logs + Post-mortem verification possible with SHA-256 sidecar |
1623
- | **Record/context safety** | Eliminate dependence on snapshot → live `contextvars` during hand-off on the producer side. Apply sens_kws masking on Writer side |
1623
+ | **Record/context safety** | Eliminate dependence on snapshot → live `contextvars` during hand-off on the producer side. Apply `sens_kws` masking during diagnostic snapshots and Writer-side formatting |
1624
1624
  | **Operational control** | Diagnostics, routing, and hashes can be overwritten with environment variables without rebuilding |
1625
1625
  | **Concurrency/multiprocess safety** | Workers do not directly open shared log files, and the parent Writer owns the sink. Eliminate unlimited waiting for host process with bounded queue + explicit timeout |
1626
1626
  | **Failure observability** | Classify delivery failures by `KnownRejected` / `KnownDropped` / `UnexplainedLost` → silent loss is not allowed structurally |
@@ -1774,7 +1774,7 @@ Design document §9.4:
1774
1774
  This functions as an indirect defense against ``attacker-induced `__repr__` exceptions'' and ``log size attacks using large objects.''
1775
1775
  #### 4.4.8 cross-thread safety
1776
1776
  Design document §9.4:
1777
- > In a free-threaded build, a `f_locals` live reference to frame of another running thread is unsafe. Therefore, when a hand-off across queues occurs, the traceback and `f_locals` are converted to a **safe repr-converted snapshot** on the producer thread side, and no live reference is made on the consumer thread side.
1777
+ > In a free-threaded build, a `f_locals` live reference to frame of another running thread is unsafe. Therefore, when a hand-off across queues occurs, the traceback and `f_locals` are converted to a **safe masked, repr-converted snapshot** on the producer thread side, and no live reference is made on the consumer thread side.
1778
1778
  > (`docs/design/D_SafeLogger_Specification_v23j_full.md` §9.4)
1779
1779
  Although this is a matter of correctness rather than security, it also helps reduce the risk of data leakage by eliminating accidents in which the internal state of other threads is unintentionally referenced in a free-threaded environment.
1780
1780
  ---
@@ -2537,7 +2537,7 @@ Design document §9.3:
2537
2537
  - Reason: To separate stdlib differences between Python 3.11 / 3.13 / 3.14 from semantics.
2538
2538
  Responsibilities on the producer thread side:
2539
2539
  - `contextualize()` information to private attribute `_ds_context` of `LogRecord` snapshot
2540
- - Convert `f_locals` to repr-converted snapshot only if `diagnose=True` and `exc_info` are present (`_ds_diag_frames`)
2540
+ - Convert `f_locals` to a masked, repr-converted snapshot only if `diagnose=True` and `exc_info` are present (`_ds_diag_frames`)
2541
2541
  - Lightweight hand-off of copy + context snapshot in normal logs
2542
2542
  #### 5.9.3 Safe Termination Assurance Level
2543
2543
  Design document §9.3:
@@ -2982,7 +2982,7 @@ Design document §2 / §9.2:
2982
2982
  > (`docs/design/D_SafeLogger_Specification_v23j_full.md` §2)
2983
2983
  #### 5.19.3 cross-thread safety
2984
2984
  Design document §9.4:
2985
- > In a free-threaded build, a `f_locals` live reference to frame of another running thread is unsafe. Therefore, when a hand-off across queues occurs, the traceback and `f_locals` are converted to a **safe repr-converted snapshot** on the producer thread side, and no live reference is made on the consumer thread side.
2985
+ > In a free-threaded build, a `f_locals` live reference to frame of another running thread is unsafe. Therefore, when a hand-off across queues occurs, the traceback and `f_locals` are converted to a **safe masked, repr-converted snapshot** on the producer thread side, and no live reference is made on the consumer thread side.
2986
2986
  > (`docs/design/D_SafeLogger_Specification_v23j_full.md` §9.4)
2987
2987
  #### 5.19.4 thread boundary semantics
2988
2988
  Design document §9.5:
@@ -2995,7 +2995,7 @@ Design document §2 v21 revised:
2995
2995
  - Eliminate double lock overhead by abolishing the independent `self._lock` of `AppendOnlyFileHandler` and unifying it with the lock API (`self.acquire()/release()`) of the parent class `logging.Handler`
2996
2996
  #### 5.19.6 Functional Observation
2997
2997
  - Structurally eliminates shared state destruction in free-threaded builds by using an explicit locking design that does not assume the existence of GIL.
2998
- - Eliminate the risk of live reference to other thread frames in free-threaded build by making `f_locals` a repr-converted snapshot.
2998
+ - Eliminate the risk of live reference to other thread frames in free-threaded build by making `f_locals` a masked, repr-converted snapshot.
2999
2999
  - Eliminate accidents where the user's request context is leaked to the internal thread by starting an empty Context in the internal thread.
3000
3000
  ---
3001
3001
 
@@ -3026,7 +3026,7 @@ formatter falls back in the following order:
3026
3026
  #### 5.20.6 Functional Observation
3027
3027
  - The diagnostic function is positioned as an ``operation tool during production'' rather than a ``useful function during development'' (only environment variables enabled, intentional operation by the operator).
3028
3028
  - repr Defensive implementation against failures and large objects.
3029
- - Maintains safety in a free-threaded environment because hand-off is performed using repr-converted snapshots even via async/multiprocess.
3029
+ - Maintains safety in a free-threaded environment because hand-off is performed using masked, repr-converted snapshots even via async/multiprocess.
3030
3030
  ---
3031
3031
 
3032
3032
  ### 5.21 sens_kws masking
@@ -3868,9 +3868,9 @@ Facts that can be confirmed from `pyproject.toml` and `MANIFEST.in`:
3868
3868
  - Operation guide: `TESTING.md` / `BENCHMARK.md` / `CONTRIBUTING.md` / `CHANGELOG.md`
3869
3869
  #### 7.10.3 Quality Gate
3870
3870
  `TESTING.md` and public validation procedures:
3871
- - v23j local validation on Python 3.14.3 / Windows: **651 passed, 3 skipped** (654 collected, `uv run pytest tests -v`)
3871
+ - v23j local validation on Python 3.14.3 / Windows: **658 passed, 3 skipped** (661 collected, `uv run pytest tests -v`)
3872
3872
  - The skipped count is platform-dependent because fork E2E tests are POSIX-only and Windows spawn E2E tests are Windows-only.
3873
- - Coverage: terminal total **86%**, XML line-rate **88.49%**, branch-rate **80.53%**
3873
+ - Coverage: terminal total **87%**, XML line-rate **88.97%**, branch-rate **81.46%**
3874
3874
  - multiprocess tests / OTel/structlog coexistence tests are included in the official quality gate
3875
3875
  - free-threaded build test: `PYTHON_GIL=0 uvx --python cpython-3.13+freethreaded --from pytest pytest tests -v`
3876
3876
  #### 7.10.4 Release Management
@@ -3881,7 +3881,7 @@ Public validation procedures:
3881
3881
  - `BENCHMARK.md` is an interpretation of manual editing and will not be regenerated from benchmark runner
3882
3882
  #### 7.10.5 Status at time of publication
3883
3883
  Pre-publication review record (as of 2026-05-07):
3884
- - Current release target version: `0.2.0`
3884
+ - Current release target version: `0.2.1`
3885
3885
  - Latest pre-release review results: **GO-with-fixes**
3886
3886
  - Required correction items before publication (release blockers) are listed
3887
3887
  Although these indicate the existence of a ``prepared release operation flow,'' this chapter does not consider this to be the ``reason for popularity,'' but only records it as the technical structure of the distribution.
@@ -3935,7 +3935,7 @@ The observed facts referenced in this chapter can be summarized as follows. This
3935
3935
  7. **International-market perspective**: Trend in early adoption of PEP 703 / Supply chain regulatory requirements such as Executive Order 14028 / Large-scale microservice configuration. examples / README English, Apache 2.0, zero dependencies are supported.
3936
3936
  8. **The design purpose is clearly not “wide dissemination”**: §1 of the design document declares that the “top priority is to operate as a common foundation for the D ecosystem rather than to pursue wide adoption.” This reflects a design stance that prioritizes fit for organizations with specific operational requirements.
3937
3937
  9. **Document operations that actively specify failure boundaries**: Threat Model of `examples/08_compliance_audit.md` / Writer does not guarantee of `examples/12_multiprocess_logging.md` / What Not To Claim of `BENCHMARK.md` / HMAC out-of-scope declaration in design document §7.6.7 / remote aggregation out-of-scope declaration in design document §11.2. These are consistent with the operational stance of ``preventing misuse due to excessive expectations.''
3938
- 10. **Quality gate transparency**: 651 passed / 3 skipped on Python 3.14.3 / Windows (654 collected), coverage 86% terminal, free-threaded build test procedure, internal synchronization verification by `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`, benchmark session fixation by `benchmarks/summary/manifest.json`. The skipped count can vary by OS. These are recorded as observable quality indicators when evaluating candidate libraries for introduction.
3938
+ 10. **Quality gate transparency**: 658 passed / 3 skipped on Python 3.14.3 / Windows (661 collected), coverage 87% terminal, free-threaded build test procedure, internal synchronization verification by `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`, benchmark session fixation by `benchmarks/summary/manifest.json`. The skipped count can vary by OS. These are recorded as observable quality indicators when evaluating candidate libraries for introduction.
3939
3939
  11. **Clear distribution structure**: The wheel contains runtime package files only and includes `py.typed`. The sdist includes docs / examples / tests / benchmark summaries / selected benchmark summaries for public validation and reproducibility. Private planning materials and temporary working files are excluded.
3940
3940
  12. **Relationship with competitors is not competition but separation of responsibilities**: structlog (front end) / OTel (emission) / Loguru (DX replacement) / picologging (speed differentiation) / logfire (SaaS) / Eliot (causal) have different responsibility axes and coexist or run in parallel with this library. Popularity indicators such as Loguru's 23.9k stars are a context independent of comparison of design dimensions.
3941
3941
  ---
@@ -4131,8 +4131,8 @@ Boundaries that public bench analysis actively enumerates:
4131
4131
  | API | `docs/api/dsafelogger*.md` | Automatically generated |
4132
4132
  | Operation | `TESTING.md` / `BENCHMARK.md` / `CONTRIBUTING.md` / `CHANGELOG.md` | — |
4133
4133
  #### 8.7.2 Quality Gate
4134
- - Official test baseline: 651 passed / 3 skipped (654 collected, `uv run pytest tests -v`, Python 3.14.3 / Windows). The skipped count can vary by OS because fork E2E tests are POSIX-only and Windows spawn E2E tests are Windows-only.
4135
- - Coverage: terminal total 86%, XML line-rate 88.49%, branch-rate 80.53%
4134
+ - Official test baseline: 658 passed / 3 skipped (661 collected, `uv run pytest tests -v`, Python 3.14.3 / Windows). The skipped count can vary by OS because fork E2E tests are POSIX-only and Windows spawn E2E tests are Windows-only.
4135
+ - Coverage: terminal total 87%, XML line-rate 88.97%, branch-rate 81.46%
4136
4136
  - multiprocess tests / OTel/structlog coexistence tests are included in the official quality gate
4137
4137
  - free-threaded build test procedure included (`PYTHON_GIL=0 uvx ...`)
4138
4138
  - Internal synchronization verification on `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`
@@ -4144,7 +4144,7 @@ Boundaries that public bench analysis actively enumerates:
4144
4144
  - `py.typed` included
4145
4145
  - `pyproject.toml` Zero runtime dependency
4146
4146
  - Distribution target is only under `src/dsafelogger/`
4147
- - Release target version: 0.2.0
4147
+ - Release target version: 0.2.1
4148
4148
  - Latest pre-release review results: GO-with-fixes (2026-05-07)
4149
4149
  #### 8.7.4 Characteristics of document operation
4150
4150
  - Multilingual: README in Japanese and English, design document in Japanese, examples/API/operation guide in English
@@ -4168,7 +4168,7 @@ Based on the observed facts in this report as a whole, we have summarized the ob
4168
4168
  8. **Multiprocess raw throughput is led by stdlib logging**: In `root_p8`, D-SafeLogger reaches 63-75% of stdlib throughput. `BENCHMARK.md` states this clearly as a design tradeoff reflecting fixed costs in the specification (IPC + Writer dispatch). The multiprocess value of this library is not raw throughput, but delivery-state observability.
4169
4169
  9. **Classifies and explains 12/12 rows in the multiprocess resilience profile**: stdlib / loguru rows are marked with `observability_gap`. Delivery-state explainability is recorded as observability specific to this library.
4170
4170
  #### 8.8.5 Documentation/quality operations
4171
- 10. **Quality gate and internal synchronization verification scripts are in place**: 651 passed / 3 skipped on Python 3.14.3 / Windows (654 collected), coverage 86%, internal synchronization verification by `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`, public representative session fixation by `benchmarks/summary/manifest.json`. The skipped count can vary by OS. These are recorded as observable quality indicators when evaluating candidate libraries for introduction.
4171
+ 10. **Quality gate and internal synchronization verification scripts are in place**: 658 passed / 3 skipped on Python 3.14.3 / Windows (661 collected), coverage 87%, internal synchronization verification by `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`, public representative session fixation by `benchmarks/summary/manifest.json`. The skipped count can vary by OS. These are recorded as observable quality indicators when evaluating candidate libraries for introduction.
4172
4172
  ---
4173
4173
 
4174
4174
  ### 8.9 Summary of this chapter
@@ -4336,7 +4336,7 @@ We will organize the D-SafeLogger-specific terms that frequently appear in this
4336
4336
  |---|---|
4337
4337
  | **Startup safety** | Reject invalid settings and unwritable paths during setup |
4338
4338
  | **File safety** | append-only routing without rename/truncate + SHA-256 sidecar |
4339
- | **Record / context safety** | Snapshot at hand-off on the producer side, sens_kws masking on the Writer side |
4339
+ | **Record / context safety** | Snapshot at hand-off on the producer side; `sens_kws` masking during diagnostic snapshots and Writer-side formatting |
4340
4340
  | **Operational control** | Overriding without rebuilding with environment variables |
4341
4341
  | **Concurrency / multiprocess safety** | parent-side Writer owns sink, bounded queue + explicit timeout |
4342
4342
  | **Failure observability** | Classification of `KnownRejected` / `KnownDropped` / `UnexplainedLost` |
@@ -1103,7 +1103,7 @@ INIファイルで指定されたモジュール別の `path` についても同
1103
1103
  * **`sens_kws_replace` による完全置換**: `sens_kws_replace=True` を明示的に指定した場合、ビルトインキーワードは破棄され、`sens_kws` で指定したキーワード**のみ**がマスキング対象となる。これにより「ビルトインの `key` が広すぎてマスキングされすぎる」等の問題をユーザーが完全に制御可能。
1104
1104
  * **マッチング**: 変数名に対する部分一致(大文字小文字不問)で判定する。例えば `password` は `user_password`, `PASSWORD_HASH`, `my_password_field` のいずれにもマッチする。
1105
1105
  * **巨大reprの抑制**: 個々のローカル変数の `repr()` は一定長で打ち切り、巨大オブジェクトや過度に冗長なデータがログを汚染しないようにする。`repr()` 自体に失敗した場合も診断ログ全体を壊さず、失敗した旨をプレースホルダとして出力する。
1106
- * **cross-thread 安全性**: free-threaded build では、実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。したがって、queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を安全な repr 済みスナップショットへ変換し、consumer thread 側では live 参照を行わない。
1106
+ * **cross-thread 安全性**: free-threaded build では、実行中の他 thread の frame に対する `f_locals` live 参照は unsafe である。したがって、queue を跨ぐ hand-off が発生する場合は producer thread 側で traceback と `f_locals` を安全なマスク済み repr スナップショットへ変換し、consumer thread 側では live 参照を行わない。
1107
1107
  * **フォールバック規則**: formatter は (1) queue hand-off 済みの診断スナップショットがあればそれを使用、(2) 同一 thread 内で `exc_info` が保持されている場合のみ live 参照を許可、(3) それ以外は standard traceback のみを出力する。
1108
1108
  * **[実装方針]**: diagnose の有効/無効は `ConfigureLogger` 実行時に `{prefix}_DIAGNOSE` から解決し、formatter / queue hand-off / diagnostic snapshot へ一貫して伝搬させる。heavy path は `exc_info` の存在時にのみ通す。
1109
1109
 
@@ -1095,7 +1095,7 @@ If `manifest_path` is specified, the writability of that directory is also verif
1095
1095
  * **Complete replacement by `sens_kws_replace`**: If `sens_kws_replace=True` is explicitly specified, the built-in keyword will be discarded and only the keyword** specified by `sens_kws` will be masked. This gives the user complete control over problems such as "built-in `key` is too wide and is masked too much".
1096
1096
  * **Matching**: Determine by partial match (case does not matter) for the variable name. For example, `password` matches `user_password`, `PASSWORD_HASH`, `my_password_field`.
1097
1097
  * **Suppressing large reprs**: Truncate `repr()` of individual local variables to a fixed length to prevent large objects or excessively redundant data from polluting the log. Even if `repr()` fails, the entire diagnostic log is not destroyed, but the failure is output as a placeholder.
1098
- * **Cross-thread safety**: In a free-threaded build, live `f_locals` references to frames in other running threads are unsafe. Therefore, when a hand-off across queues occurs, the traceback and `f_locals` are converted to safe repr snapshots on the producer thread side, and live references are not performed on the consumer thread side.
1098
+ * **Cross-thread safety**: In a free-threaded build, live `f_locals` references to frames in other running threads are unsafe. Therefore, when a hand-off across queues occurs, the traceback and `f_locals` are converted to safe masked repr snapshots on the producer thread side, and live references are not performed on the consumer thread side.
1099
1099
  * **Fallback rules**: The formatter (1) uses a queue hand-off diagnostic snapshot if available, (2) allows live references only if `exc_info` is held in the same thread, and (3) otherwise outputs only a standard traceback.
1100
1100
  * **[Implementation policy]**: The enable/disable of diagnose is resolved from `{prefix}_DIAGNOSE` during `ConfigureLogger` execution, and consistently propagated to formatter / queue hand-off / diagnostic snapshot. Heavy path is passed only when `exc_info` exists.
1101
1101
 
@@ -88,7 +88,7 @@ def handle_order(request_id: str, user: str, amount: float):
88
88
 
89
89
  ## The Output
90
90
 
91
- ### Main Log (`./logs/OrderAPI.log`)
91
+ ### Main Log (`./logs/OrderAPI_20260403.log`)
92
92
 
93
93
  Every JSON line includes the context keys set by `contextualize()`:
94
94
 
@@ -120,7 +120,7 @@ Because the output is structured JSON, you can filter by any field:
120
120
  cat logs/*.log | jq -s 'sort_by(.timestamp) | .[] | select(.request_id == "req-a1b2")'
121
121
 
122
122
  # Show only warnings and errors
123
- cat logs/OrderAPI_2026-04-03.log | jq 'select(.level == "WAR" or .level == "ERR")'
123
+ cat logs/OrderAPI_20260403.log | jq 'select(.level == "WAR" or .level == "ERR")'
124
124
 
125
125
  # List unique request IDs that hit the payment module
126
126
  cat logs/payment_alerts.log | jq -r '.request_id' | sort -u
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "D-SafeLogger"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "Zero-dependency, thread-safe, append-only logging library for Python with 3-layer config pipeline"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: D-SafeLogger
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Zero-dependency, thread-safe, append-only logging library for Python with 3-layer config pipeline
5
5
  Author: D
6
6
  License-Expression: Apache-2.0
@@ -28,8 +28,8 @@ Dynamic: license-file
28
28
  # D-SafeLogger
29
29
 
30
30
  [![CI](https://github.com/nightmarewalker/D-SafeLogger/actions/workflows/ci.yml/badge.svg)](https://github.com/nightmarewalker/D-SafeLogger/actions/workflows/ci.yml)
31
- [![PyPI version](https://img.shields.io/pypi/v/d-safelogger.svg)](https://pypi.org/project/d-safelogger/)
32
- [![Python](https://img.shields.io/pypi/pyversions/d-safelogger.svg)](https://pypi.org/project/d-safelogger/)
31
+ [![PyPI version](https://img.shields.io/pypi/v/d-safelogger.svg?cacheSeconds=3600)](https://pypi.org/project/d-safelogger/)
32
+ [![Python](https://img.shields.io/pypi/pyversions/d-safelogger.svg?cacheSeconds=3600)](https://pypi.org/project/d-safelogger/)
33
33
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
34
34
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](#main-features)
35
35
 
@@ -66,7 +66,7 @@ logger = GetLogger(__name__)
66
66
  logger.info("Application started")
67
67
  ```
68
68
 
69
- `pg_name` is the application name used as the prefix of routed log file names, for example `MyApp_2026-04-03.log`.
69
+ `pg_name` is the application name used as the prefix of routed log file names, for example `MyApp_20260403.log`.
70
70
 
71
71
  Typical text output:
72
72
 
@@ -122,7 +122,7 @@ The "Safe" in the name is a design stance that runs across several dimensions of
122
122
 
123
123
  - **Startup safety:** invalid settings, inconsistent options, and unwritable destinations fail during setup. D-SafeLogger stops a broken logging configuration before the application starts doing real work, instead of silently degrading later.
124
124
  - **File safety:** the routing layer opens the next destination instead of renaming or truncating the active log file, which avoids the common Windows failure mode where active log files cannot be renamed. It also avoids the POSIX case where a successful rename leaves the writer appending to the previous file. Routed files can be paired with SHA-256 sidecars and an optional manifest, so log content is verifiable after the fact.
125
- - **Record and context safety:** request IDs, user IDs, job IDs, and other context are snapshotted on the producer side at hand-off, so listeners and Writers do not depend on live `contextvars`. Sensitive-keyword masking is applied on the Writer side using the keyword set established at configure time.
125
+ - **Record and context safety:** request IDs, user IDs, job IDs, and other context are snapshotted on the producer side at hand-off, so listeners and Writers do not depend on live `contextvars`. Diagnostic local-variable snapshots and Writer-side formatting use the sensitive-keyword set established at configure time.
126
126
  - **Operational control:** environment variables provide explicit runtime overrides for diagnostics, routing, hashing, log levels, and queue/timeout behavior without rebuilding or editing application code.
127
127
  - **Concurrency and multiprocess safety:** multiprocess workers do not open the shared log files themselves. A parent-side Writer owns the sinks and accepts records over IPC, with bounded queues and explicit timeouts that keep the host process from unbounded waits.
128
128
  - **Failure observability:** when records cannot be delivered, the runtime classifies the outcome where it can: `KnownRejected`, `KnownDropped`, or `UnexplainedLost`. Counters and shutdown summaries make abnormal scenarios describable rather than silent.