crawlo 1.3.4__tar.gz → 1.3.5__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.

Potentially problematic release.


This version of crawlo might be problematic. Click here for more details.

Files changed (298) hide show
  1. {crawlo-1.3.4/crawlo.egg-info → crawlo-1.3.5}/PKG-INFO +1 -1
  2. crawlo-1.3.5/crawlo/__version__.py +1 -0
  3. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/mysql_pipeline.py +7 -0
  4. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/run.py.tmpl +2 -2
  5. crawlo-1.3.5/crawlo/utils/log.py +80 -0
  6. {crawlo-1.3.4 → crawlo-1.3.5/crawlo.egg-info}/PKG-INFO +1 -1
  7. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo.egg-info/SOURCES.txt +10 -0
  8. crawlo-1.3.5/tests/debug_log_config.py +127 -0
  9. crawlo-1.3.5/tests/detailed_log_test.py +234 -0
  10. crawlo-1.3.5/tests/final_log_test.py +261 -0
  11. crawlo-1.3.5/tests/fix_log_test.py +143 -0
  12. crawlo-1.3.5/tests/log_buffering_test.py +112 -0
  13. crawlo-1.3.5/tests/log_generation_timing_test.py +154 -0
  14. crawlo-1.3.5/tests/simple_log_test2.py +138 -0
  15. crawlo-1.3.5/tests/spider_log_timing_test.py +178 -0
  16. crawlo-1.3.5/tests/test_get_component_logger.py +84 -0
  17. crawlo-1.3.5/tests/test_logging_system.py +283 -0
  18. crawlo-1.3.4/crawlo/__version__.py +0 -1
  19. crawlo-1.3.4/crawlo/utils/log.py +0 -44
  20. {crawlo-1.3.4 → crawlo-1.3.5}/LICENSE +0 -0
  21. {crawlo-1.3.4 → crawlo-1.3.5}/MANIFEST.in +0 -0
  22. {crawlo-1.3.4 → crawlo-1.3.5}/README.md +0 -0
  23. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/__init__.py +0 -0
  24. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/cli.py +0 -0
  25. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/__init__.py +0 -0
  26. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/check.py +0 -0
  27. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/genspider.py +0 -0
  28. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/help.py +0 -0
  29. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/list.py +0 -0
  30. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/run.py +0 -0
  31. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/startproject.py +0 -0
  32. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/stats.py +0 -0
  33. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/commands/utils.py +0 -0
  34. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/config.py +0 -0
  35. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/config_validator.py +0 -0
  36. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/core/__init__.py +0 -0
  37. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/core/engine.py +0 -0
  38. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/core/processor.py +0 -0
  39. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/core/scheduler.py +0 -0
  40. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/crawler.py +0 -0
  41. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/data/__init__.py +0 -0
  42. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/data/user_agents.py +0 -0
  43. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/__init__.py +0 -0
  44. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/aiohttp_downloader.py +0 -0
  45. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/cffi_downloader.py +0 -0
  46. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/httpx_downloader.py +0 -0
  47. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/hybrid_downloader.py +0 -0
  48. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/playwright_downloader.py +0 -0
  49. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/downloader/selenium_downloader.py +0 -0
  50. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/event.py +0 -0
  51. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/exceptions.py +0 -0
  52. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/__init__.py +0 -0
  53. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/health_check.py +0 -0
  54. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/log_interval.py +0 -0
  55. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/log_stats.py +0 -0
  56. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/logging_extension.py +0 -0
  57. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/memory_monitor.py +0 -0
  58. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/performance_profiler.py +0 -0
  59. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/extension/request_recorder.py +0 -0
  60. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/factories/__init__.py +0 -0
  61. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/factories/base.py +0 -0
  62. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/factories/crawler.py +0 -0
  63. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/factories/registry.py +0 -0
  64. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/filters/__init__.py +0 -0
  65. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/filters/aioredis_filter.py +0 -0
  66. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/filters/memory_filter.py +0 -0
  67. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/framework.py +0 -0
  68. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/initialization/__init__.py +0 -0
  69. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/initialization/built_in.py +0 -0
  70. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/initialization/context.py +0 -0
  71. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/initialization/core.py +0 -0
  72. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/initialization/phases.py +0 -0
  73. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/initialization/registry.py +0 -0
  74. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/items/__init__.py +0 -0
  75. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/items/base.py +0 -0
  76. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/items/fields.py +0 -0
  77. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/items/items.py +0 -0
  78. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/logging/__init__.py +0 -0
  79. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/logging/config.py +0 -0
  80. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/logging/factory.py +0 -0
  81. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/logging/manager.py +0 -0
  82. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/__init__.py +0 -0
  83. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/default_header.py +0 -0
  84. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/download_delay.py +0 -0
  85. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/middleware_manager.py +0 -0
  86. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/offsite.py +0 -0
  87. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/proxy.py +0 -0
  88. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/request_ignore.py +0 -0
  89. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/response_code.py +0 -0
  90. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/response_filter.py +0 -0
  91. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/retry.py +0 -0
  92. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/middleware/simple_proxy.py +0 -0
  93. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/mode_manager.py +0 -0
  94. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/network/__init__.py +0 -0
  95. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/network/request.py +0 -0
  96. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/network/response.py +0 -0
  97. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/__init__.py +0 -0
  98. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/bloom_dedup_pipeline.py +0 -0
  99. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/console_pipeline.py +0 -0
  100. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/csv_pipeline.py +0 -0
  101. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/database_dedup_pipeline.py +0 -0
  102. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/json_pipeline.py +0 -0
  103. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/memory_dedup_pipeline.py +0 -0
  104. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/mongo_pipeline.py +0 -0
  105. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/pipeline_manager.py +0 -0
  106. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/pipelines/redis_dedup_pipeline.py +0 -0
  107. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/project.py +0 -0
  108. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/queue/__init__.py +0 -0
  109. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/queue/pqueue.py +0 -0
  110. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/queue/queue_manager.py +0 -0
  111. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/queue/redis_priority_queue.py +0 -0
  112. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/settings/__init__.py +0 -0
  113. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/settings/default_settings.py +0 -0
  114. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/settings/setting_manager.py +0 -0
  115. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/spider/__init__.py +0 -0
  116. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/stats_collector.py +0 -0
  117. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/subscriber.py +0 -0
  118. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/task_manager.py +0 -0
  119. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/crawlo.cfg.tmpl +0 -0
  120. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/__init__.py.tmpl +0 -0
  121. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/items.py.tmpl +0 -0
  122. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/middlewares.py.tmpl +0 -0
  123. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/pipelines.py.tmpl +0 -0
  124. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/settings.py.tmpl +0 -0
  125. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/settings_distributed.py.tmpl +0 -0
  126. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/settings_gentle.py.tmpl +0 -0
  127. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/settings_high_performance.py.tmpl +0 -0
  128. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/settings_minimal.py.tmpl +0 -0
  129. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/settings_simple.py.tmpl +0 -0
  130. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/project/spiders/__init__.py.tmpl +0 -0
  131. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/spider/spider.py.tmpl +0 -0
  132. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/templates/spiders_init.py.tmpl +0 -0
  133. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/__init__.py +0 -0
  134. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/anti_crawler.py +0 -0
  135. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/authenticated_proxy.py +0 -0
  136. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/data_formatter.py +0 -0
  137. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/data_validator.py +0 -0
  138. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/date_tools.py +0 -0
  139. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/distributed_coordinator.py +0 -0
  140. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/encoding_converter.py +0 -0
  141. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/network_diagnostic.py +0 -0
  142. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/request_tools.py +0 -0
  143. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/retry_mechanism.py +0 -0
  144. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/scenario_adapter.py +0 -0
  145. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/tools/text_cleaner.py +0 -0
  146. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/__init__.py +0 -0
  147. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/batch_processor.py +0 -0
  148. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/class_loader.py +0 -0
  149. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/controlled_spider_mixin.py +0 -0
  150. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/db_helper.py +0 -0
  151. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/enhanced_error_handler.py +0 -0
  152. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/env_config.py +0 -0
  153. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/error_handler.py +0 -0
  154. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/func_tools.py +0 -0
  155. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/large_scale_config.py +0 -0
  156. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/large_scale_helper.py +0 -0
  157. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/performance_monitor.py +0 -0
  158. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/queue_helper.py +0 -0
  159. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/redis_connection_pool.py +0 -0
  160. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/redis_key_validator.py +0 -0
  161. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/request.py +0 -0
  162. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/request_serializer.py +0 -0
  163. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/spider_loader.py +0 -0
  164. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/system.py +0 -0
  165. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/tools.py +0 -0
  166. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo/utils/url.py +0 -0
  167. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo.egg-info/dependency_links.txt +0 -0
  168. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo.egg-info/entry_points.txt +0 -0
  169. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo.egg-info/requires.txt +0 -0
  170. {crawlo-1.3.4 → crawlo-1.3.5}/crawlo.egg-info/top_level.txt +0 -0
  171. {crawlo-1.3.4 → crawlo-1.3.5}/examples/__init__.py +0 -0
  172. {crawlo-1.3.4 → crawlo-1.3.5}/pyproject.toml +0 -0
  173. {crawlo-1.3.4 → crawlo-1.3.5}/requirements.txt +0 -0
  174. {crawlo-1.3.4 → crawlo-1.3.5}/setup.cfg +0 -0
  175. {crawlo-1.3.4 → crawlo-1.3.5}/tests/__init__.py +0 -0
  176. {crawlo-1.3.4 → crawlo-1.3.5}/tests/advanced_tools_example.py +0 -0
  177. {crawlo-1.3.4 → crawlo-1.3.5}/tests/authenticated_proxy_example.py +0 -0
  178. {crawlo-1.3.4 → crawlo-1.3.5}/tests/baidu_performance_test.py +0 -0
  179. {crawlo-1.3.4 → crawlo-1.3.5}/tests/baidu_test.py +0 -0
  180. {crawlo-1.3.4 → crawlo-1.3.5}/tests/cleaners_example.py +0 -0
  181. {crawlo-1.3.4 → crawlo-1.3.5}/tests/comprehensive_framework_test.py +0 -0
  182. {crawlo-1.3.4 → crawlo-1.3.5}/tests/comprehensive_test.py +0 -0
  183. {crawlo-1.3.4 → crawlo-1.3.5}/tests/comprehensive_testing_summary.md +0 -0
  184. {crawlo-1.3.4 → crawlo-1.3.5}/tests/config_validation_demo.py +0 -0
  185. {crawlo-1.3.4 → crawlo-1.3.5}/tests/controlled_spider_example.py +0 -0
  186. {crawlo-1.3.4 → crawlo-1.3.5}/tests/date_tools_example.py +0 -0
  187. {crawlo-1.3.4 → crawlo-1.3.5}/tests/debug_configure.py +0 -0
  188. {crawlo-1.3.4 → crawlo-1.3.5}/tests/debug_framework_logger.py +0 -0
  189. {crawlo-1.3.4 → crawlo-1.3.5}/tests/debug_log_levels.py +0 -0
  190. {crawlo-1.3.4 → crawlo-1.3.5}/tests/debug_pipelines.py +0 -0
  191. {crawlo-1.3.4 → crawlo-1.3.5}/tests/distributed_test.py +0 -0
  192. {crawlo-1.3.4 → crawlo-1.3.5}/tests/distributed_test_debug.py +0 -0
  193. {crawlo-1.3.4 → crawlo-1.3.5}/tests/dynamic_loading_example.py +0 -0
  194. {crawlo-1.3.4 → crawlo-1.3.5}/tests/dynamic_loading_test.py +0 -0
  195. {crawlo-1.3.4 → crawlo-1.3.5}/tests/env_config_example.py +0 -0
  196. {crawlo-1.3.4 → crawlo-1.3.5}/tests/error_handling_example.py +0 -0
  197. {crawlo-1.3.4 → crawlo-1.3.5}/tests/final_command_test_report.md +0 -0
  198. {crawlo-1.3.4 → crawlo-1.3.5}/tests/final_comprehensive_test.py +0 -0
  199. {crawlo-1.3.4 → crawlo-1.3.5}/tests/final_validation_test.py +0 -0
  200. {crawlo-1.3.4 → crawlo-1.3.5}/tests/framework_performance_test.py +0 -0
  201. {crawlo-1.3.4 → crawlo-1.3.5}/tests/optimized_performance_test.py +0 -0
  202. {crawlo-1.3.4 → crawlo-1.3.5}/tests/performance_comparison.py +0 -0
  203. {crawlo-1.3.4 → crawlo-1.3.5}/tests/queue_blocking_test.py +0 -0
  204. {crawlo-1.3.4 → crawlo-1.3.5}/tests/queue_test.py +0 -0
  205. {crawlo-1.3.4 → crawlo-1.3.5}/tests/redis_key_validation_demo.py +0 -0
  206. {crawlo-1.3.4 → crawlo-1.3.5}/tests/request_params_example.py +0 -0
  207. {crawlo-1.3.4 → crawlo-1.3.5}/tests/response_improvements_example.py +0 -0
  208. {crawlo-1.3.4 → crawlo-1.3.5}/tests/scrapy_comparison/ofweek_scrapy.py +0 -0
  209. {crawlo-1.3.4 → crawlo-1.3.5}/tests/scrapy_comparison/scrapy_test.py +0 -0
  210. {crawlo-1.3.4 → crawlo-1.3.5}/tests/simple_command_test.py +0 -0
  211. {crawlo-1.3.4 → crawlo-1.3.5}/tests/simple_crawlo_test.py +0 -0
  212. {crawlo-1.3.4 → crawlo-1.3.5}/tests/simple_log_test.py +0 -0
  213. {crawlo-1.3.4 → crawlo-1.3.5}/tests/simple_optimization_test.py +0 -0
  214. {crawlo-1.3.4 → crawlo-1.3.5}/tests/simple_spider_test.py +0 -0
  215. {crawlo-1.3.4 → crawlo-1.3.5}/tests/simple_test.py +0 -0
  216. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_advanced_tools.py +0 -0
  217. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_all_commands.py +0 -0
  218. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_all_redis_key_configs.py +0 -0
  219. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_authenticated_proxy.py +0 -0
  220. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_batch_processor.py +0 -0
  221. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_cleaners.py +0 -0
  222. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_component_factory.py +0 -0
  223. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_comprehensive.py +0 -0
  224. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_config_consistency.py +0 -0
  225. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_config_merge.py +0 -0
  226. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_config_validator.py +0 -0
  227. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_controlled_spider_mixin.py +0 -0
  228. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_crawlo_proxy_integration.py +0 -0
  229. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_date_tools.py +0 -0
  230. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_default_header_middleware.py +0 -0
  231. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_distributed.py +0 -0
  232. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_double_crawlo_fix.py +0 -0
  233. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_double_crawlo_fix_simple.py +0 -0
  234. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_download_delay_middleware.py +0 -0
  235. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_downloader_proxy_compatibility.py +0 -0
  236. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_dynamic_downloaders_proxy.py +0 -0
  237. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_dynamic_proxy.py +0 -0
  238. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_dynamic_proxy_config.py +0 -0
  239. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_dynamic_proxy_real.py +0 -0
  240. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_edge_cases.py +0 -0
  241. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_enhanced_error_handler.py +0 -0
  242. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_enhanced_error_handler_comprehensive.py +0 -0
  243. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_env_config.py +0 -0
  244. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_error_handler_compatibility.py +0 -0
  245. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_factories.py +0 -0
  246. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_final_validation.py +0 -0
  247. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_framework_env_usage.py +0 -0
  248. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_framework_logger.py +0 -0
  249. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_framework_startup.py +0 -0
  250. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_integration.py +0 -0
  251. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_item_dedup_redis_key.py +0 -0
  252. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_large_scale_config.py +0 -0
  253. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_large_scale_helper.py +0 -0
  254. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_mode_change.py +0 -0
  255. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_mode_consistency.py +0 -0
  256. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_offsite_middleware.py +0 -0
  257. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_parsel.py +0 -0
  258. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_performance.py +0 -0
  259. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_performance_monitor.py +0 -0
  260. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_api.py +0 -0
  261. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_health_check.py +0 -0
  262. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_middleware.py +0 -0
  263. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_middleware_enhanced.py +0 -0
  264. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_middleware_integration.py +0 -0
  265. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_middleware_refactored.py +0 -0
  266. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_providers.py +0 -0
  267. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_stats.py +0 -0
  268. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_proxy_strategies.py +0 -0
  269. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_queue_empty_check.py +0 -0
  270. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_queue_manager_double_crawlo.py +0 -0
  271. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_queue_manager_redis_key.py +0 -0
  272. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_random_user_agent.py +0 -0
  273. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_real_scenario_proxy.py +0 -0
  274. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_redis_config.py +0 -0
  275. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_redis_connection_pool.py +0 -0
  276. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_redis_key_naming.py +0 -0
  277. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_redis_key_validator.py +0 -0
  278. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_redis_queue.py +0 -0
  279. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_request_ignore_middleware.py +0 -0
  280. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_request_params.py +0 -0
  281. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_request_serialization.py +0 -0
  282. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_response_code_middleware.py +0 -0
  283. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_response_filter_middleware.py +0 -0
  284. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_response_improvements.py +0 -0
  285. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_retry_middleware.py +0 -0
  286. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_scheduler.py +0 -0
  287. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_scheduler_config_update.py +0 -0
  288. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_simple_response.py +0 -0
  289. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_telecom_spider_redis_key.py +0 -0
  290. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_template_content.py +0 -0
  291. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_template_redis_key.py +0 -0
  292. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_tools.py +0 -0
  293. {crawlo-1.3.4 → crawlo-1.3.5}/tests/test_user_agents.py +0 -0
  294. {crawlo-1.3.4 → crawlo-1.3.5}/tests/tools_example.py +0 -0
  295. {crawlo-1.3.4 → crawlo-1.3.5}/tests/untested_features_report.md +0 -0
  296. {crawlo-1.3.4 → crawlo-1.3.5}/tests/verify_debug.py +0 -0
  297. {crawlo-1.3.4 → crawlo-1.3.5}/tests/verify_distributed.py +0 -0
  298. {crawlo-1.3.4 → crawlo-1.3.5}/tests/verify_log_fix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crawlo
3
- Version: 1.3.4
3
+ Version: 1.3.5
4
4
  Summary: Crawlo 是一款基于异步IO的高性能Python爬虫框架,支持分布式抓取。
5
5
  Home-page: https://github.com/crawl-coder/Crawlo.git
6
6
  Author: crawl-coder
@@ -0,0 +1 @@
1
+ __version__ = '1.3.5'
@@ -20,7 +20,14 @@ class AsyncmyMySQLPipeline:
20
20
  self._pool_lock = asyncio.Lock()
21
21
  self._pool_initialized = False
22
22
  self.pool = None
23
+
24
+ # 优先从爬虫的custom_settings中获取表名,如果没有则使用默认值
25
+ spider_table_name = None
26
+ if hasattr(crawler, 'spider') and crawler.spider and hasattr(crawler.spider, 'custom_settings'):
27
+ spider_table_name = crawler.spider.custom_settings.get('MYSQL_TABLE')
28
+
23
29
  self.table_name = (
30
+ spider_table_name or
24
31
  self.settings.get('MYSQL_TABLE') or
25
32
  getattr(crawler.spider, 'mysql_table', None) or
26
33
  f"{crawler.spider.name}_items"
@@ -21,8 +21,8 @@ def main():
21
21
  spider_modules = ['{{project_name}}.spiders']
22
22
  process = CrawlerProcess(spider_modules=spider_modules)
23
23
 
24
- # 运行指定的爬虫
25
- asyncio.run(process.crawl('{{spider_name}}'))
24
+ # TODO 运行指定的爬虫
25
+ asyncio.run(process.crawl('spider_name'))
26
26
 
27
27
  except Exception as e:
28
28
  print(f"❌ 运行失败: {e}")
@@ -0,0 +1,80 @@
1
+ # ==================== 向后兼容的日志接口 ====================
2
+ # 主要功能已迁移到 crawlo.logging 模块
3
+ # 本文件提供向后兼容接口,同时支持新的日志系统功能
4
+
5
+ import logging
6
+ from typing import Optional, Any
7
+
8
+ # 向后兼容:导入新的日志系统
9
+ try:
10
+ from crawlo.logging import get_logger as new_get_logger, configure_logging
11
+
12
+ _NEW_LOGGING_AVAILABLE = True
13
+ except ImportError:
14
+ _NEW_LOGGING_AVAILABLE = False
15
+ new_get_logger = None
16
+ configure_logging = None
17
+
18
+ LOG_FORMAT = '%(asctime)s - [%(name)s] - %(levelname)s: %(message)s'
19
+
20
+
21
+ # 向后兼容的日志函数
22
+ def get_logger(name: str = 'default', level: Optional[int] = None):
23
+ """获取Logger实例 - 向后兼容函数"""
24
+ if _NEW_LOGGING_AVAILABLE and new_get_logger:
25
+ # 使用新的日志系统
26
+ return new_get_logger(name)
27
+ else:
28
+ # 降级到基本的Python logging
29
+ logger = logging.getLogger(name)
30
+ if not logger.handlers:
31
+ handler = logging.StreamHandler()
32
+ formatter = logging.Formatter(LOG_FORMAT)
33
+ handler.setFormatter(formatter)
34
+ logger.addHandler(handler)
35
+ logger.setLevel(level or logging.INFO)
36
+ return logger
37
+
38
+
39
+ def get_component_logger(component_class: Any, settings: Optional[Any] = None, level: Optional[str] = None):
40
+ """
41
+ 获取组件Logger - 推荐的组件日志创建方式
42
+
43
+ Args:
44
+ component_class: 组件类
45
+ settings: 配置对象,用于读取日志级别配置
46
+ level: 日志级别(优先级低于settings中的配置)
47
+
48
+ Returns:
49
+ logging.Logger: 配置好的Logger实例
50
+ """
51
+ # 获取组件名称
52
+ if hasattr(component_class, '__name__'):
53
+ component_name = component_class.__name__
54
+ else:
55
+ component_name = str(component_class)
56
+
57
+ # 如果新日志系统可用,使用新系统
58
+ if _NEW_LOGGING_AVAILABLE and new_get_logger:
59
+ return new_get_logger(component_name)
60
+
61
+ # 否则使用向后兼容方式
62
+ # 从settings中获取日志级别(如果提供)
63
+ if settings is not None:
64
+ # 尝试从settings获取组件特定的日志级别
65
+ if hasattr(settings, 'get'):
66
+ # 检查是否有组件特定的日志级别配置
67
+ component_level = settings.get(f'LOG_LEVEL_{component_name}')
68
+ if component_level is not None:
69
+ level = component_level
70
+ else:
71
+ # 检查通用日志级别
72
+ general_level = settings.get('LOG_LEVEL')
73
+ if general_level is not None:
74
+ level = general_level
75
+
76
+ # 转换日志级别
77
+ if isinstance(level, str):
78
+ level = getattr(logging, level.upper(), logging.INFO)
79
+
80
+ return get_logger(component_name, level)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crawlo
3
- Version: 1.3.4
3
+ Version: 1.3.5
4
4
  Summary: Crawlo 是一款基于异步IO的高性能Python爬虫框架,支持分布式抓取。
5
5
  Home-page: https://github.com/crawl-coder/Crawlo.git
6
6
  Author: crawl-coder
@@ -173,8 +173,10 @@ tests/controlled_spider_example.py
173
173
  tests/date_tools_example.py
174
174
  tests/debug_configure.py
175
175
  tests/debug_framework_logger.py
176
+ tests/debug_log_config.py
176
177
  tests/debug_log_levels.py
177
178
  tests/debug_pipelines.py
179
+ tests/detailed_log_test.py
178
180
  tests/distributed_test.py
179
181
  tests/distributed_test_debug.py
180
182
  tests/dynamic_loading_example.py
@@ -183,8 +185,12 @@ tests/env_config_example.py
183
185
  tests/error_handling_example.py
184
186
  tests/final_command_test_report.md
185
187
  tests/final_comprehensive_test.py
188
+ tests/final_log_test.py
186
189
  tests/final_validation_test.py
190
+ tests/fix_log_test.py
187
191
  tests/framework_performance_test.py
192
+ tests/log_buffering_test.py
193
+ tests/log_generation_timing_test.py
188
194
  tests/optimized_performance_test.py
189
195
  tests/performance_comparison.py
190
196
  tests/queue_blocking_test.py
@@ -195,9 +201,11 @@ tests/response_improvements_example.py
195
201
  tests/simple_command_test.py
196
202
  tests/simple_crawlo_test.py
197
203
  tests/simple_log_test.py
204
+ tests/simple_log_test2.py
198
205
  tests/simple_optimization_test.py
199
206
  tests/simple_spider_test.py
200
207
  tests/simple_test.py
208
+ tests/spider_log_timing_test.py
201
209
  tests/test_advanced_tools.py
202
210
  tests/test_all_commands.py
203
211
  tests/test_all_redis_key_configs.py
@@ -232,10 +240,12 @@ tests/test_final_validation.py
232
240
  tests/test_framework_env_usage.py
233
241
  tests/test_framework_logger.py
234
242
  tests/test_framework_startup.py
243
+ tests/test_get_component_logger.py
235
244
  tests/test_integration.py
236
245
  tests/test_item_dedup_redis_key.py
237
246
  tests/test_large_scale_config.py
238
247
  tests/test_large_scale_helper.py
248
+ tests/test_logging_system.py
239
249
  tests/test_mode_change.py
240
250
  tests/test_mode_consistency.py
241
251
  tests/test_offsite_middleware.py
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: UTF-8 -*-
3
+ """
4
+ 调试日志配置问题
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ # 添加项目根目录到Python路径
12
+ project_root = Path(__file__).parent.parent
13
+ sys.path.insert(0, str(project_root))
14
+
15
+ from crawlo.logging import configure_logging as configure, get_logger, LogManager
16
+ from crawlo.logging.config import LogConfig
17
+
18
+
19
+ def debug_log_configuration():
20
+ """调试日志配置"""
21
+ print("=== 调试日志配置 ===")
22
+
23
+ # 重置配置
24
+ LogManager().reset()
25
+
26
+ # 1. 检查初始状态
27
+ print("1. 检查初始状态...")
28
+ print(f" 初始配置状态: {LogManager().is_configured}")
29
+ if LogManager().config:
30
+ print(f" 初始配置: {LogManager().config}")
31
+
32
+ # 2. 配置日志系统
33
+ print("2. 配置日志系统...")
34
+ config = configure(
35
+ LOG_LEVEL='DEBUG',
36
+ LOG_FILE='debug_test.log',
37
+ LOG_MAX_BYTES=1024,
38
+ LOG_BACKUP_COUNT=2,
39
+ LOG_CONSOLE_ENABLED=True,
40
+ LOG_FILE_ENABLED=True
41
+ )
42
+
43
+ print(f" 配置返回值: {config}")
44
+ print(f" 配置类型: {type(config)}")
45
+ print(f" 配置级别: {config.level}")
46
+ print(f" 配置文件路径: {config.file_path}")
47
+ print(f" 轮转大小: {config.max_bytes}")
48
+ print(f" 备份数量: {config.backup_count}")
49
+ print(f" 控制台启用: {config.console_enabled}")
50
+ print(f" 文件启用: {config.file_enabled}")
51
+
52
+ # 3. 检查管理器状态
53
+ print("3. 检查管理器状态...")
54
+ manager = LogManager()
55
+ print(f" 管理器配置状态: {manager.is_configured}")
56
+ if manager.config:
57
+ print(f" 管理器配置: {manager.config}")
58
+ print(f" 管理器配置文件路径: {manager.config.file_path}")
59
+
60
+ # 4. 测试Logger创建
61
+ print("4. 测试Logger创建...")
62
+ logger = get_logger('test.debug')
63
+ print(f" Logger handlers数量: {len(logger.handlers)}")
64
+
65
+ for i, handler in enumerate(logger.handlers):
66
+ handler_type = type(handler).__name__
67
+ print(f" Handler {i}: {handler_type}")
68
+ if hasattr(handler, 'baseFilename'):
69
+ print(f" 文件名: {handler.baseFilename}")
70
+
71
+ # 5. 测试日志输出
72
+ print("5. 测试日志输出...")
73
+ logger.info("调试测试消息")
74
+
75
+
76
+ def test_config_from_dict():
77
+ """测试从字典创建配置"""
78
+ print("\n=== 测试从字典创建配置 ===")
79
+
80
+ LogManager().reset()
81
+
82
+ # 使用字典配置
83
+ config_dict = {
84
+ 'level': 'DEBUG',
85
+ 'file_path': 'dict_test.log',
86
+ 'max_bytes': 1024,
87
+ 'backup_count': 2,
88
+ 'console_enabled': True,
89
+ 'file_enabled': True
90
+ }
91
+
92
+ config = LogConfig.from_dict(config_dict)
93
+ print(f" 字典配置: {config}")
94
+ print(f" 验证结果: {config.validate()}")
95
+
96
+ # 应用配置
97
+ LogManager().configure(config)
98
+
99
+ logger = get_logger('test.dict')
100
+ print(f" Logger handlers数量: {len(logger.handlers)}")
101
+
102
+ for i, handler in enumerate(logger.handlers):
103
+ handler_type = type(handler).__name__
104
+ print(f" Handler {i}: {handler_type}")
105
+
106
+
107
+ def main():
108
+ """主函数"""
109
+ print("开始调试日志配置问题...")
110
+
111
+ try:
112
+ debug_log_configuration()
113
+ test_config_from_dict()
114
+
115
+ print("\n=== 调试完成 ===")
116
+
117
+ except Exception as e:
118
+ print(f"\n调试过程中出现错误: {e}")
119
+ import traceback
120
+ traceback.print_exc()
121
+ return 1
122
+
123
+ return 0
124
+
125
+
126
+ if __name__ == '__main__':
127
+ sys.exit(main())
@@ -0,0 +1,234 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: UTF-8 -*-
3
+ """
4
+ 详细的日志系统功能测试
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import tempfile
10
+ import shutil
11
+ from pathlib import Path
12
+
13
+ # 添加项目根目录到Python路径
14
+ project_root = Path(__file__).parent.parent
15
+ sys.path.insert(0, str(project_root))
16
+
17
+ from crawlo.logging import configure_logging as configure, get_logger, LogManager
18
+ from crawlo.logging.config import LogConfig
19
+
20
+
21
+ def test_log_config_creation():
22
+ """测试日志配置创建"""
23
+ print("=== 测试日志配置创建 ===")
24
+
25
+ # 重置日志管理器
26
+ LogManager().reset()
27
+
28
+ # 1. 测试通过关键字参数创建配置
29
+ print("1. 测试通过关键字参数创建配置...")
30
+ config = configure(
31
+ LOG_LEVEL='DEBUG',
32
+ LOG_FILE='test.log',
33
+ LOG_MAX_BYTES=1024,
34
+ LOG_BACKUP_COUNT=3
35
+ )
36
+
37
+ print(f" 配置级别: {config.level}")
38
+ print(f" 配置文件路径: {config.file_path}")
39
+ print(f" 轮转大小: {config.max_bytes}")
40
+ print(f" 备份数量: {config.backup_count}")
41
+
42
+ # 2. 测试通过字典创建配置
43
+ print("2. 测试通过字典创建配置...")
44
+ LogManager().reset()
45
+ config_dict = {
46
+ 'LOG_LEVEL': 'WARNING',
47
+ 'LOG_FILE': 'dict_test.log',
48
+ 'LOG_CONSOLE_ENABLED': False
49
+ }
50
+ config = configure(**config_dict)
51
+
52
+ print(f" 配置级别: {config.level}")
53
+ print(f" 配置文件路径: {config.file_path}")
54
+ print(f" 控制台启用: {config.console_enabled}")
55
+
56
+
57
+ def test_logger_factory():
58
+ """测试Logger工厂"""
59
+ print("\n=== 测试Logger工厂 ===")
60
+
61
+ # 重置并配置
62
+ LogManager().reset()
63
+ configure(LOG_LEVEL='INFO')
64
+
65
+ # 1. 测试获取Logger
66
+ print("1. 测试获取Logger...")
67
+ logger1 = get_logger('test.factory1')
68
+ logger2 = get_logger('test.factory2')
69
+ logger3 = get_logger('test.factory1') # 应该是同一个实例
70
+
71
+ print(f" Logger1 ID: {id(logger1)}")
72
+ print(f" Logger2 ID: {id(logger2)}")
73
+ print(f" Logger3 ID: {id(logger3)}")
74
+ print(f" Logger1和Logger3是同一对象: {logger1 is logger3}")
75
+
76
+ # 2. 测试Logger配置
77
+ print("2. 测试Logger配置...")
78
+ print(f" Logger1名称: {logger1.name}")
79
+ print(f" Logger1 handlers数量: {len(logger1.handlers)}")
80
+
81
+ for i, handler in enumerate(logger1.handlers):
82
+ print(f" Handler {i}: {type(handler).__name__}")
83
+
84
+
85
+ def test_file_and_console_handlers():
86
+ """测试文件和控制台处理器"""
87
+ print("\n=== 测试文件和控制台处理器 ===")
88
+
89
+ # 创建临时目录
90
+ temp_dir = tempfile.mkdtemp()
91
+ log_file = os.path.join(temp_dir, 'handler_test.log')
92
+
93
+ try:
94
+ # 1. 测试文件和控制台都启用
95
+ print("1. 测试文件和控制台都启用...")
96
+ LogManager().reset()
97
+ configure(
98
+ LOG_LEVEL='INFO',
99
+ LOG_FILE=log_file,
100
+ LOG_CONSOLE_ENABLED=True,
101
+ LOG_FILE_ENABLED=True
102
+ )
103
+
104
+ logger = get_logger('test.handlers')
105
+ print(f" Handlers数量: {len(logger.handlers)}")
106
+
107
+ has_file_handler = False
108
+ has_console_handler = False
109
+
110
+ for handler in logger.handlers:
111
+ handler_type = type(handler).__name__
112
+ print(f" Handler类型: {handler_type}")
113
+ if 'FileHandler' in handler_type:
114
+ has_file_handler = True
115
+ print(f" 文件路径: {getattr(handler, 'baseFilename', 'N/A')}")
116
+ elif 'StreamHandler' in handler_type:
117
+ has_console_handler = True
118
+
119
+ print(f" 有文件处理器: {has_file_handler}")
120
+ print(f" 有控制台处理器: {has_console_handler}")
121
+
122
+ # 输出日志
123
+ logger.info("测试文件和控制台处理器")
124
+
125
+ # 检查文件是否存在
126
+ if os.path.exists(log_file):
127
+ with open(log_file, 'r', encoding='utf-8') as f:
128
+ content = f.read()
129
+ print(f" 文件内容行数: {len(content.splitlines())}")
130
+ else:
131
+ print(" 文件不存在!")
132
+
133
+ finally:
134
+ # 清理
135
+ shutil.rmtree(temp_dir, ignore_errors=True)
136
+
137
+
138
+ def test_log_levels():
139
+ """测试日志级别"""
140
+ print("\n=== 测试日志级别 ===")
141
+
142
+ # 1. 测试默认级别
143
+ print("1. 测试默认级别...")
144
+ LogManager().reset()
145
+ configure(LOG_LEVEL='WARNING')
146
+
147
+ logger = get_logger('test.levels')
148
+ logger.debug("DEBUG消息 - 不应该显示")
149
+ logger.info("INFO消息 - 不应该显示")
150
+ logger.warning("WARNING消息 - 应该显示")
151
+ logger.error("ERROR消息 - 应该显示")
152
+
153
+ # 2. 测试模块特定级别
154
+ print("2. 测试模块特定级别...")
155
+ LogManager().reset()
156
+ configure(
157
+ LOG_LEVEL='ERROR',
158
+ LOG_LEVELS={
159
+ 'test.debug_module': 'DEBUG',
160
+ 'test.info_module': 'INFO'
161
+ }
162
+ )
163
+
164
+ # 默认模块(ERROR级别)
165
+ default_logger = get_logger('test.default')
166
+ default_logger.info("默认模块INFO消息 - 不应该显示")
167
+ default_logger.error("默认模块ERROR消息 - 应该显示")
168
+
169
+ # DEBUG模块(DEBUG级别)
170
+ debug_logger = get_logger('test.debug_module')
171
+ debug_logger.debug("DEBUG模块DEBUG消息 - 应该显示")
172
+ debug_logger.info("DEBUG模块INFO消息 - 应该显示")
173
+
174
+ # INFO模块(INFO级别)
175
+ info_logger = get_logger('test.info_module')
176
+ info_logger.debug("INFO模块DEBUG消息 - 不应该显示")
177
+ info_logger.info("INFO模块INFO消息 - 应该显示")
178
+
179
+
180
+ def test_log_config_validation():
181
+ """测试日志配置验证"""
182
+ print("\n=== 测试日志配置验证 ===")
183
+
184
+ # 1. 测试有效配置
185
+ print("1. 测试有效配置...")
186
+ valid_config = LogConfig(level='INFO', file_path='valid.log')
187
+ is_valid = valid_config.validate()
188
+ print(f" 有效配置验证: {is_valid}")
189
+
190
+ # 2. 测试无效级别
191
+ print("2. 测试无效级别...")
192
+ invalid_config = LogConfig(level='INVALID', file_path='invalid.log')
193
+ is_valid = invalid_config.validate()
194
+ print(f" 无效级别验证: {is_valid}")
195
+
196
+ # 3. 测试目录创建
197
+ print("3. 测试目录创建...")
198
+ temp_dir = tempfile.mkdtemp()
199
+ nested_path = os.path.join(temp_dir, 'subdir', 'nested.log')
200
+
201
+ nested_config = LogConfig(level='INFO', file_path=nested_path)
202
+ is_valid = nested_config.validate()
203
+ print(f" 嵌套目录验证: {is_valid}")
204
+ print(f" 目录存在: {os.path.exists(os.path.dirname(nested_path))}")
205
+
206
+ # 清理
207
+ shutil.rmtree(temp_dir, ignore_errors=True)
208
+
209
+
210
+ def main():
211
+ """主测试函数"""
212
+ print("开始详细测试Crawlo框架日志系统...")
213
+
214
+ try:
215
+ # 运行所有测试
216
+ test_log_config_creation()
217
+ test_logger_factory()
218
+ test_file_and_console_handlers()
219
+ test_log_levels()
220
+ test_log_config_validation()
221
+
222
+ print("\n=== 详细测试完成 ===")
223
+
224
+ except Exception as e:
225
+ print(f"\n测试过程中出现错误: {e}")
226
+ import traceback
227
+ traceback.print_exc()
228
+ return 1
229
+
230
+ return 0
231
+
232
+
233
+ if __name__ == '__main__':
234
+ sys.exit(main())