pythonLogs 3.0.13__tar.gz → 4.0.2__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.
@@ -0,0 +1,627 @@
1
+ Metadata-Version: 2.3
2
+ Name: pythonLogs
3
+ Version: 4.0.2
4
+ Summary: High-performance Python logging library with file rotation and optimized caching for better performance
5
+ License: MIT
6
+ Keywords: python3,python-3,python,log,logging,logger,logutils,log-utils,pythonLogs
7
+ Author: Daniel Costa
8
+ Author-email: danieldcsta@gmail.com
9
+ Maintainer: Daniel Costa
10
+ Requires-Python: >=3.10,<4.0
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Other Environment
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Natural Language :: English
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3 :: Only
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Dist: pydantic (>=2.11.7,<3.0.0)
25
+ Requires-Dist: pydantic-settings (>=2.10.1,<3.0.0)
26
+ Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
27
+ Project-URL: Homepage, https://pypi.org/project/pythonLogs
28
+ Project-URL: Repository, https://github.com/ddc/pythonLogs
29
+ Description-Content-Type: text/markdown
30
+
31
+ # High-performance Python logging library
32
+
33
+ [![Donate](https://img.shields.io/badge/Donate-PayPal-brightgreen.svg?style=plastic)](https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
35
+ [![PyPi](https://img.shields.io/pypi/v/pythonLogs.svg)](https://pypi.python.org/pypi/pythonLogs)
36
+ [![PyPI Downloads](https://static.pepy.tech/badge/pythonLogs)](https://pepy.tech/projects/pythonLogs)
37
+ [![codecov](https://codecov.io/gh/ddc/pythonLogs/graph/badge.svg?token=QsjwsmYzgD)](https://codecov.io/gh/ddc/pythonLogs)
38
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
39
+ [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A//actions-badge.atrox.dev/ddc/pythonLogs/badge?ref=main&label=build&logo=none)](https://actions-badge.atrox.dev/ddc/pythonLogs/goto?ref=main)
40
+ [![Python](https://img.shields.io/pypi/pyversions/pythonLogs.svg)](https://www.python.org/downloads)
41
+
42
+ [![Support me on GitHub](https://img.shields.io/badge/Support_me_on_GitHub-154c79?style=for-the-badge&logo=github)](https://github.com/sponsors/ddc)
43
+
44
+ High-performance Python logging library with file rotation and optimized caching for better performance
45
+
46
+
47
+ ## Table of Contents
48
+
49
+ - [Features](#features)
50
+ - [Installation](#installation)
51
+ - [Logger Types](#logger-types)
52
+ - [Basic Logger](#basic-logger)
53
+ - [Size Rotating Logger](#size-rotating-logger)
54
+ - [Timed Rotating Logger](#timed-rotating-logger)
55
+ - [Context Manager Support](#context-manager-support)
56
+ - [Advanced Factory Features](#advanced-factory-features)
57
+ - [Memory Management](#memory-management)
58
+ - [Migration Guide](#migration-guide)
59
+ - [Performance Improvements](#performance-improvements)
60
+ - [Environment Variables](#env-variables-optional)
61
+ - [Development](#source-code)
62
+
63
+
64
+
65
+ # Features
66
+
67
+ ✨ **Factory Pattern** - Easy logger creation with centralized configuration
68
+ 🚀 **High Performance** - Optimized caching for 90%+ performance improvements
69
+ 🔄 **File Rotation** - Automatic rotation by size or time with compression
70
+ 🎯 **Type Safety** - Enum-based configuration with IDE support
71
+ ⚙️ **Flexible Configuration** - Environment variables, direct parameters, or defaults
72
+ 📍 **Location Tracking** - Optional filename and line number in logs
73
+ 🌍 **Timezone Support** - Full timezone handling including `localtime` and `UTC`
74
+ 💾 **Memory Efficient** - Logger registry and settings caching
75
+ 🔒 **Context Manager Support** - Automatic resource cleanup and exception safety
76
+ 🧵 **Thread Safe** - Concurrent access protection for all operations
77
+ 🔧 **Resource Management** - Automatic handler cleanup and memory leak prevention
78
+
79
+
80
+ # Installation
81
+ ```shell
82
+ pip install pythonLogs
83
+ ```
84
+
85
+
86
+ # Logger Types
87
+
88
+ ## Basic Logger
89
+ Console-only logging without file output. Perfect for development and simple applications.
90
+
91
+ ### Using Factory Pattern (Recommended)
92
+ ```python
93
+ from pythonLogs import basic_logger, LogLevel
94
+
95
+ # Option 1: Using string (simple) (case-insensitive)
96
+ logger = basic_logger(
97
+ name="my_app",
98
+ level="debug", # "debug", "info", "warning", "error", "critical"
99
+ timezone="America/Sao_Paulo",
100
+ showlocation=False
101
+ )
102
+ logger.warning("This is a warning example")
103
+
104
+ # Option 2: Using enum (type-safe)
105
+ logger = basic_logger(
106
+ name="my_app",
107
+ level=LogLevel.DEBUG,
108
+ timezone="America/Sao_Paulo",
109
+ showlocation=False
110
+ )
111
+ logger.warning("This is a warning example")
112
+ ```
113
+
114
+ ### Legacy Method (Still Supported)
115
+ ```python
116
+ from pythonLogs import BasicLog
117
+
118
+ logger = BasicLog(
119
+ level="debug",
120
+ name="app",
121
+ timezone="America/Sao_Paulo",
122
+ showlocation=False,
123
+ ).init()
124
+ logger.warning("This is a warning example")
125
+ ```
126
+
127
+ #### Example Output
128
+ `[2024-10-08T19:08:56.918-0300]:[WARNING]:[my_app]:This is a warning example`
129
+
130
+
131
+
132
+
133
+
134
+ ## Size Rotating Logger
135
+ File-based logging with automatic rotation when files reach a specified size. Rotated files are compressed as `.gz`.
136
+
137
+ + **Rotation**: Based on file size (`maxmbytes` parameter)
138
+ + **Naming**: Rotated logs have sequence numbers: `app.log_1.gz`, `app.log_2.gz`
139
+ + **Cleanup**: Old logs deleted based on `daystokeep` (default: 30 days)
140
+
141
+ ### Using Factory Pattern (Recommended)
142
+ ```python
143
+ from pythonLogs import size_rotating_logger, LogLevel
144
+
145
+ # Option 1: Using string (simple) (case-insensitive)
146
+ logger = size_rotating_logger(
147
+ name="my_app",
148
+ level="debug", # "debug", "info", "warning", "error", "critical"
149
+ directory="/app/logs",
150
+ filenames=["main.log", "app1.log"],
151
+ maxmbytes=5,
152
+ daystokeep=7,
153
+ timezone="America/Chicago",
154
+ streamhandler=True,
155
+ showlocation=False
156
+ )
157
+ logger.warning("This is a warning example")
158
+
159
+ # Option 2: Using enum (type-safe)
160
+ logger = size_rotating_logger(
161
+ name="my_app",
162
+ level=LogLevel.DEBUG,
163
+ directory="/app/logs",
164
+ filenames=["main.log", "app1.log"],
165
+ maxmbytes=5,
166
+ daystokeep=7,
167
+ timezone="America/Chicago",
168
+ streamhandler=True,
169
+ showlocation=False
170
+ )
171
+ logger.warning("This is a warning example")
172
+ ```
173
+
174
+ ### Legacy Method (Still Supported)
175
+ ```python
176
+ from pythonLogs import SizeRotatingLog
177
+
178
+ logger = SizeRotatingLog(
179
+ level="debug",
180
+ name="app",
181
+ directory="/app/logs",
182
+ filenames=["main.log", "app1.log"],
183
+ maxmbytes=5,
184
+ daystokeep=7,
185
+ timezone="America/Chicago",
186
+ streamhandler=True,
187
+ showlocation=False
188
+ ).init()
189
+ logger.warning("This is a warning example")
190
+ ```
191
+
192
+ #### Example Output
193
+ `[2024-10-08T19:08:56.918-0500]:[WARNING]:[my_app]:This is a warning example`
194
+
195
+
196
+
197
+
198
+
199
+ ## Timed Rotating Logger
200
+ File-based logging with automatic rotation based on time intervals. Rotated files are compressed as `.gz`.
201
+
202
+ + **Rotation**: Based on time (`when` parameter, defaults to `midnight`)
203
+ + **Naming**: Rotated logs have date suffix: `app_20240816.log.gz`
204
+ + **Cleanup**: Old logs deleted based on `daystokeep` (default: 30 days)
205
+ + **Supported Intervals**: `midnight`, `hourly`, `daily`, `W0-W6` (weekdays, 0=Monday)
206
+
207
+ ### Using Factory Pattern (Recommended)
208
+ ```python
209
+ from pythonLogs import timed_rotating_logger, LogLevel, RotateWhen
210
+
211
+ # Option 1: Using string (simple) (case-insensitive)
212
+ logger = timed_rotating_logger(
213
+ name="my_app",
214
+ level="debug", # "debug", "info", "warning", "error", "critical"
215
+ directory="/app/logs",
216
+ filenames=["main.log", "app2.log"],
217
+ when="midnight", # String when value
218
+ daystokeep=7,
219
+ timezone="UTC",
220
+ streamhandler=True,
221
+ showlocation=False
222
+ )
223
+ logger.warning("This is a warning example")
224
+
225
+ # Option 2: Using enum (type-safe)
226
+ logger = timed_rotating_logger(
227
+ name="my_app",
228
+ level=LogLevel.DEBUG, # Type-safe enum
229
+ directory="/app/logs",
230
+ filenames=["main.log", "app2.log"],
231
+ when=RotateWhen.MIDNIGHT, # Type-safe enum
232
+ daystokeep=7,
233
+ timezone="UTC",
234
+ streamhandler=True,
235
+ showlocation=False
236
+ )
237
+ logger.warning("This is a warning example")
238
+ ```
239
+
240
+ ### Legacy Method (Still Supported)
241
+ ```python
242
+ from pythonLogs import TimedRotatingLog
243
+
244
+ logger = TimedRotatingLog(
245
+ level="debug",
246
+ name="app",
247
+ directory="/app/logs",
248
+ filenames=["main.log", "app2.log"],
249
+ when="midnight",
250
+ daystokeep=7,
251
+ timezone="UTC",
252
+ streamhandler=True,
253
+ showlocation=False
254
+ ).init()
255
+ logger.warning("This is a warning example")
256
+ ```
257
+
258
+ #### Example Output
259
+ `[2024-10-08T19:08:56.918-0000]:[WARNING]:[my_app]:This is a warning example`
260
+
261
+
262
+
263
+
264
+
265
+ # Context Manager Support
266
+
267
+ All logger types support context managers for automatic resource cleanup and exception safety:
268
+
269
+ ## Basic Usage
270
+ ```python
271
+ from pythonLogs import BasicLog, SizeRotatingLog, TimedRotatingLog, LogLevel
272
+
273
+ # Automatic cleanup with context managers
274
+ with BasicLog(name="app", level=LogLevel.INFO) as logger:
275
+ logger.info("This is automatically cleaned up")
276
+ # Handlers are automatically closed on exit
277
+
278
+ with SizeRotatingLog(name="app", directory="/logs", filenames=["app.log"]) as logger:
279
+ logger.info("File handlers cleaned up automatically")
280
+ # File handlers closed and resources freed
281
+
282
+ # Exception safety - cleanup happens even if exceptions occur
283
+ try:
284
+ with TimedRotatingLog(name="app", directory="/logs") as logger:
285
+ logger.error("Error occurred")
286
+ raise ValueError("Something went wrong")
287
+ except ValueError:
288
+ pass # Logger was still cleaned up properly
289
+ ```
290
+
291
+ ## Benefits of Context Manager Usage
292
+ - 🔒 **Automatic Cleanup** - Handlers are closed and removed automatically
293
+ - ⚡ **Exception Safety** - Resources cleaned up even when exceptions occur
294
+ - 💾 **Memory Management** - Prevents memory leaks from unclosed handlers
295
+ - 🧵 **Thread Safety** - Cleanup operations are thread-safe
296
+ - 🔧 **No Manual Management** - No need to manually call cleanup methods
297
+
298
+ ## Factory Pattern + Context Managers
299
+ ```python
300
+ from pythonLogs import LoggerFactory, LoggerType
301
+
302
+ # Create logger through factory and use with context manager
303
+ logger_instance = LoggerFactory.get_or_create_logger(
304
+ LoggerType.SIZE_ROTATING,
305
+ name="production_app",
306
+ directory="/var/log"
307
+ )
308
+
309
+ # Use the logger instance directly
310
+ with logger_instance as logger:
311
+ logger.info("Factory created logger with automatic cleanup")
312
+ ```
313
+
314
+
315
+ # Advanced Factory Features
316
+
317
+ ## Logger Registry (Performance Optimization)
318
+ The factory pattern includes a built-in registry that caches loggers for improved performance:
319
+
320
+ ```python
321
+ from pythonLogs import get_or_create_logger, LoggerType, clear_logger_registry
322
+
323
+ # First call creates the logger
324
+ logger1 = get_or_create_logger(LoggerType.BASIC, name="cached_app")
325
+
326
+ # The Second call returns the same logger instance (90% faster)
327
+ logger2 = get_or_create_logger(LoggerType.BASIC, name="cached_app")
328
+
329
+ # Both variables point to the same logger instance
330
+ assert logger1 is logger2
331
+
332
+ # Clear registry when needed (useful for testing)
333
+ clear_logger_registry()
334
+ ```
335
+
336
+ ## Flexible Configuration Options
337
+ You can use either enums (for type safety) or strings (for simplicity):
338
+
339
+ ```python
340
+ from pythonLogs import LogLevel, RotateWhen, LoggerType
341
+
342
+ # Option 1: Type-safe enums (recommended)
343
+ LogLevel.DEBUG # "DEBUG"
344
+ LogLevel.INFO # "INFO"
345
+ LogLevel.WARNING # "WARNING"
346
+ LogLevel.ERROR # "ERROR"
347
+ LogLevel.CRITICAL # "CRITICAL"
348
+
349
+ # Option 2: String values (case-insensitive)
350
+ "debug" # Same as LogLevel.DEBUG
351
+ "info" # Same as LogLevel.INFO
352
+ "warning" # Same as LogLevel.WARNING
353
+ "warn" # Same as LogLevel.WARN (alias)
354
+ "error" # Same as LogLevel.ERROR
355
+ "critical" # Same as LogLevel.CRITICAL
356
+ "crit" # Same as LogLevel.CRIT (alias)
357
+ # Also supports: "DEBUG", "Info", "Warning", etc.
358
+
359
+ # RotateWhen values
360
+ RotateWhen.MIDNIGHT # "midnight"
361
+ RotateWhen.HOURLY # "H"
362
+ RotateWhen.DAILY # "D"
363
+ RotateWhen.MONDAY # "W0"
364
+ # ... through SUNDAY # "W6"
365
+ # String equivalents: "midnight", "H", "D", "W0"-"W6"
366
+
367
+ # LoggerType values
368
+ LoggerType.BASIC # "basic"
369
+ LoggerType.SIZE_ROTATING # "size_rotating"
370
+ LoggerType.TIMED_ROTATING # "timed_rotating"
371
+ # String equivalents: "basic", "size_rotating", "timed_rotating"
372
+ ```
373
+
374
+ ## Production Setup Example
375
+ ```python
376
+ from pythonLogs import size_rotating_logger, timed_rotating_logger, LogLevel, RotateWhen
377
+
378
+ # Application logger
379
+ app_logger = size_rotating_logger(
380
+ name="production_app",
381
+ directory="/var/log/myapp",
382
+ filenames=["app.log"],
383
+ maxmbytes=50, # 50MB files
384
+ daystokeep=30, # Keep 30 days
385
+ level=LogLevel.INFO,
386
+ streamhandler=True, # Also log to console
387
+ showlocation=True, # Show file:function:line
388
+ timezone="UTC"
389
+ )
390
+
391
+ # Error logger with longer retention
392
+ error_logger = size_rotating_logger(
393
+ name="production_errors",
394
+ directory="/var/log/myapp",
395
+ filenames=["errors.log"],
396
+ maxmbytes=10,
397
+ daystokeep=90, # Keep errors longer
398
+ level=LogLevel.ERROR,
399
+ streamhandler=False
400
+ )
401
+
402
+ # Audit logger with daily rotation
403
+ audit_logger = timed_rotating_logger(
404
+ name="audit_log",
405
+ directory="/var/log/myapp",
406
+ filenames=["audit.log"],
407
+ when=RotateWhen.MIDNIGHT,
408
+ level=LogLevel.INFO
409
+ )
410
+
411
+ # Use the loggers
412
+ app_logger.info("Application started")
413
+ error_logger.error("Database connection failed")
414
+ audit_logger.info("User admin logged in")
415
+ ```
416
+
417
+ ## Env Variables (Optional | Production)
418
+ .env variables can be used by leaving all options blank when calling the function
419
+ If not specified inside the .env file, it will use the dafault value
420
+ This is a good approach for production environments, since options can be changed easily
421
+ ```python
422
+ from pythonLogs import timed_rotating_logger
423
+ log = timed_rotating_logger()
424
+ ```
425
+
426
+ ```
427
+ LOG_LEVEL=DEBUG
428
+ LOG_TIMEZONE=UTC
429
+ LOG_ENCODING=UTF-8
430
+ LOG_APPNAME=app
431
+ LOG_FILENAME=app.log
432
+ LOG_DIRECTORY=/app/logs
433
+ LOG_DAYS_TO_KEEP=30
434
+ LOG_DATE_FORMAT=%Y-%m-%dT%H:%M:%S
435
+ LOG_STREAM_HANDLER=True
436
+ LOG_SHOW_LOCATION=False
437
+ LOG_MAX_LOGGERS=50
438
+ LOG_LOGGER_TTL_SECONDS=1800
439
+
440
+ # SizeRotatingLog
441
+ LOG_MAX_FILE_SIZE_MB=10
442
+
443
+ # TimedRotatingLog
444
+ LOG_ROTATE_WHEN=midnight
445
+ LOG_ROTATE_AT_UTC=True
446
+ LOG_ROTATE_FILE_SUFIX="%Y%m%d"
447
+ ```
448
+
449
+
450
+
451
+
452
+ # Memory Management
453
+
454
+ The library includes comprehensive memory management features to prevent memory leaks and optimize resource usage:
455
+
456
+ ## Automatic Resource Cleanup
457
+ ```python
458
+ from pythonLogs import clear_logger_registry, shutdown_logger, LoggerFactory
459
+
460
+ # Clear the entire logger registry with proper cleanup
461
+ clear_logger_registry()
462
+
463
+ # Shutdown specific logger and remove from registry
464
+ shutdown_logger("my_app_logger")
465
+
466
+ # Manual registry management
467
+ LoggerFactory.shutdown_logger("specific_logger")
468
+ LoggerFactory.clear_registry()
469
+ ```
470
+
471
+ ## Memory Optimization Features
472
+ ```python
473
+ from pythonLogs import (
474
+ get_memory_stats,
475
+ clear_formatter_cache,
476
+ clear_directory_cache,
477
+ optimize_lru_cache_sizes,
478
+ force_garbage_collection
479
+ )
480
+
481
+ # Get current memory usage statistics
482
+ stats = get_memory_stats()
483
+ print(f"Registry size: {stats['registry_size']}")
484
+ print(f"Formatter cache: {stats['formatter_cache_size']}")
485
+ print(f"Active loggers: {stats['active_logger_count']}")
486
+
487
+ # Clear various caches to free memory
488
+ clear_formatter_cache() # Clear cached formatters
489
+ clear_directory_cache() # Clear directory permission cache
490
+
491
+ # Optimize LRU cache sizes for memory-constrained environments
492
+ optimize_lru_cache_sizes()
493
+
494
+ # Force garbage collection and get collection statistics
495
+ gc_stats = force_garbage_collection()
496
+ print(f"Objects collected: {gc_stats['objects_collected']}")
497
+ ```
498
+
499
+ ## Registry Configuration
500
+ ```python
501
+ from pythonLogs import LoggerFactory
502
+
503
+ # Configure registry limits for memory management
504
+ LoggerFactory.set_memory_limits(
505
+ max_loggers=50, # Maximum cached loggers
506
+ ttl_seconds=1800 # Logger time-to-live (30 minutes)
507
+ )
508
+
509
+ # Monitor registered loggers
510
+ registered = LoggerFactory.get_registered_loggers()
511
+ print(f"Currently registered: {list(registered.keys())}")
512
+ ```
513
+
514
+ ## Thread-Safe Operations
515
+ All memory management operations are thread-safe and can be used safely in multi-threaded applications:
516
+
517
+ ```python
518
+ import threading
519
+ from pythonLogs import size_rotating_logger, clear_logger_registry
520
+
521
+ def worker_function(worker_id):
522
+ # Each thread can safely create and use loggers
523
+ logger = size_rotating_logger(
524
+ name=f"worker_{worker_id}",
525
+ directory="/app/logs"
526
+ )
527
+
528
+ with logger as log:
529
+ log.info(f"Worker {worker_id} started")
530
+ # Automatic cleanup per thread
531
+
532
+ # Create multiple threads - all operations are thread-safe
533
+ threads = []
534
+ for i in range(10):
535
+ thread = threading.Thread(target=worker_function, args=(i,))
536
+ threads.append(thread)
537
+ thread.start()
538
+
539
+ # Wait for completion and clean up
540
+ for thread in threads:
541
+ thread.join()
542
+
543
+ # Safe to clear registry from main thread
544
+ clear_logger_registry()
545
+ ```
546
+
547
+
548
+ # Migration Guide
549
+
550
+ ## Upgrading from Legacy to Factory Pattern
551
+
552
+ The factory pattern is **100% backward compatible**. Your existing code will continue to work unchanged.
553
+
554
+ ### Before (Legacy - Still Works)
555
+ ```python
556
+ from pythonLogs import BasicLog, SizeRotatingLog, TimedRotatingLog
557
+
558
+ # Old way
559
+ basic_logger = BasicLog(level="info", name="app").init()
560
+ size_logger = SizeRotatingLog(level="debug", name="app", directory="/logs").init()
561
+ timed_logger = TimedRotatingLog(level="warning", name="app", directory="/logs").init()
562
+ ```
563
+
564
+ ### After (Factory Pattern - Recommended)
565
+ ```python
566
+ from pythonLogs import basic_logger, size_rotating_logger, timed_rotating_logger, LogLevel
567
+
568
+ # New way - cleaner and faster
569
+ basic_logger = basic_logger(level=LogLevel.INFO, name="app")
570
+ size_logger = size_rotating_logger(level=LogLevel.DEBUG, name="app", directory="/logs")
571
+ timed_logger = timed_rotating_logger(level=LogLevel.WARNING, name="app", directory="/logs")
572
+ ```
573
+
574
+ ### Benefits of Migration
575
+ - 🚀 **90% faster logger creation** with registry caching
576
+ - 🎯 **Type safety** with enum-based parameters
577
+ - 💡 **Better IDE support** with autocomplete and validation
578
+ - 🔧 **Cleaner API** without manual `.init()` calls
579
+ - 📚 **Centralized configuration** through factory pattern
580
+
581
+ # Performance Improvements
582
+
583
+ ## Benchmarks
584
+ The factory pattern with optimizations provides significant performance improvements:
585
+
586
+ | Feature | Improvement | Benefit |
587
+ |---------|-------------|---------|
588
+ | Logger Registry | 90%+ faster | Cached logger instances |
589
+ | Settings Caching | ~85% faster | Reused configuration objects |
590
+ | Directory Validation | ~75% faster | Cached permission checks |
591
+ | Timezone Operations | ~60% faster | Cached timezone functions |
592
+
593
+ ## Performance Test Results
594
+ ```python
595
+ # Create 100 loggers - Performance comparison
596
+ # Legacy method: ~0.045 seconds
597
+ # Factory pattern: ~0.004 seconds
598
+ # Improvement: 91% faster ⚡
599
+ ```
600
+
601
+ # Source Code
602
+ ### Build
603
+ ```shell
604
+ poetry build -f wheel
605
+ ```
606
+
607
+
608
+
609
+ # Run Tests and Get Coverage Report using Poe
610
+ ```shell
611
+ poetry update --with test
612
+ poe test
613
+ ```
614
+
615
+
616
+
617
+ # License
618
+ Released under the [MIT License](LICENSE)
619
+
620
+
621
+
622
+
623
+ # Buy me a cup of coffee
624
+ + [GitHub Sponsor](https://github.com/sponsors/ddc)
625
+ + [ko-fi](https://ko-fi.com/ddcsta)
626
+ + [Paypal](https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ)
627
+