miu-logger 0.1.6__py3-none-any.whl → 0.2.0__py3-none-any.whl

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,287 @@
1
+ Metadata-Version: 2.4
2
+ Name: miu-logger
3
+ Version: 0.2.0
4
+ Summary: Multiprocessing-safe domain-based logging framework with QueueListener architecture
5
+ Author-email: Bruno Miura <brumiura@gmail.com>
6
+ License-Expression: MIT
7
+ Keywords: logging,multiprocessing,queue,structured-logging,python-logging
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Topic :: System :: Logging
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: colorama
16
+ Dynamic: license-file
17
+
18
+ # miu-logger
19
+
20
+ **Multiprocessing-safe, domain-driven structured logging for Python services**
21
+
22
+ `miu-logger` is a logging framework designed for **real systems**:
23
+
24
+ * Multiprocessing- and multithreading-safe
25
+ * Domain-separated loggers (`app`, `db`, `task`, etc.)
26
+ * Per-level log files (`debug.log`, `info.log`, `error.log`, …)
27
+ * Central queue listener to avoid file collisions
28
+ * Clean IDE autocomplete for both domains and log levels
29
+ * Minimal setup in application code
30
+
31
+ ---
32
+
33
+ ## Why use `miu-logger`
34
+
35
+ Python's standard logging is powerful but breaks down when:
36
+
37
+ * Multiple processes or threads write to the same log files
38
+ * You want **domain-specific log files**
39
+ * You want **centralized log routing**
40
+ * You want IDE autocomplete for domains and levels
41
+
42
+ `miu-logger` solves this by:
43
+
44
+ > Logging through a **central queue listener**, separating **domains** and **levels**, while exposing a **typed repository** for IDE-friendly access.
45
+
46
+ ---
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ uv add miu-logger
52
+ # or
53
+ pip install miu-logger
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Configuring Logging Domains
59
+
60
+ Domains represent **areas of your system** (not log levels). Examples: `app`, `db`, `redis`, `task`.
61
+
62
+ Define them in `LogConfig`:
63
+
64
+ ```python
65
+ import logging
66
+ from miu_logger.config import LogConfig
67
+ from miu_logger.repository import LoggingRepository
68
+
69
+ config = LogConfig(
70
+ log_dir="logs", # folder to store logs
71
+ domains=["app", "db", "redis"], # your custom domains
72
+ level=logging.DEBUG, # base log level for all domains
73
+ debug_enabled=True, # toggle debug messages
74
+ )
75
+
76
+ repo = LoggingRepository(config)
77
+ ```
78
+
79
+ ### Accessing Domain Loggers
80
+
81
+ ```python
82
+ repo.app.info("Application started")
83
+ repo.db.error("Database connection failed")
84
+ repo.redis.debug("Cache initialized")
85
+ ```
86
+
87
+ * Accessing a domain not defined in `config.domains` raises a `ValueError`:
88
+
89
+ ```python
90
+ repo.get("api") # ❌ ValueError if "api" not in config.domains
91
+ ```
92
+
93
+ * Domains can also be dynamically retrieved:
94
+
95
+ ```python
96
+ task_logger = repo.get("task") # Must be defined in config.domains
97
+ task_logger.info("Task started")
98
+ ```
99
+
100
+ ---
101
+
102
+ ## IDE Autocomplete with Stub Generation
103
+
104
+ Domains are dynamic, so editors cannot know them automatically.
105
+ Use the **stub generator** to enable autocomplete:
106
+
107
+ ```python
108
+ from miu_logger.stubgen import generate_repository_stub
109
+
110
+ generate_repository_stub(
111
+ domains=["app", "db", "redis", "task"], # all your domains
112
+ out_dir="typings", # directory for generated stubs
113
+ )
114
+ ```
115
+
116
+ This creates:
117
+
118
+ ```
119
+ typings/miu_logger/repository.pyi
120
+ ```
121
+
122
+ Tell your editor where the typings are:
123
+
124
+ * **VSCode / Pyright**:
125
+
126
+ ```json
127
+ {
128
+ "python.analysis.extraPaths": ["typings"]
129
+ }
130
+ ```
131
+
132
+ * **pyproject.toml (Pyright)**:
133
+
134
+ ```toml
135
+ [tool.pyright]
136
+ extraPaths = ["typings"]
137
+ ```
138
+
139
+ After this, your IDE knows both:
140
+
141
+ * Domains: `repo.app`, `repo.db`, …
142
+ * Log methods: `.debug()`, `.info()`, `.warning()`, `.error()`, `.exception()`
143
+
144
+ Regenerate stubs whenever you add new domains.
145
+
146
+ ---
147
+
148
+ ## Multiprocessing Usage
149
+
150
+ The repository uses a **central QueueListener** for safe multiprocessing logging.
151
+
152
+ **Main process:**
153
+
154
+ ```python
155
+ repo = LoggingRepository(config)
156
+ queue = repo.get_queue()
157
+ ```
158
+
159
+ **Worker processes:**
160
+
161
+ ```python
162
+ worker_repo = LoggingRepository(config, use_listener=False, queue=queue)
163
+ worker_repo.task.info("Worker started")
164
+ ```
165
+
166
+ All processes log safely to the same listener and files.
167
+
168
+ ---
169
+
170
+ ## Debug Control
171
+
172
+ Only `.debug()` messages are conditional via `debug_enabled`:
173
+
174
+ ```python
175
+ config.debug_enabled = False
176
+ repo.app.debug("Won't appear")
177
+ repo.app.info("Will appear")
178
+ ```
179
+
180
+ Useful for toggling debug messages in production.
181
+
182
+ ---
183
+
184
+ ## Output Structure
185
+
186
+ Logs are written in:
187
+
188
+ ```
189
+ logs/
190
+ ├─ app.log # domain logs
191
+ ├─ db.log
192
+ ├─ redis.log
193
+ ├─ debug.log # per-level logs
194
+ ├─ info.log
195
+ ├─ warning.log
196
+ └─ error.log
197
+ ```
198
+
199
+ Console output is **colorized** by level:
200
+
201
+ * DEBUG → blue
202
+ * INFO → green
203
+ * WARNING → yellow
204
+ * ERROR → red
205
+
206
+ Files remain clean.
207
+
208
+ ---
209
+
210
+ ## Graceful Shutdown
211
+
212
+ The repository automatically shuts down on process exit and supports manual shutdown:
213
+
214
+ ```python
215
+ repo.shutdown()
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Typical Usage Example
221
+
222
+ ```python
223
+ repo.app.info("Service starting")
224
+
225
+ try:
226
+ connect_db()
227
+ except Exception:
228
+ repo.db.exception("DB connection failed")
229
+
230
+ repo.redis.debug("Cache size: %d", cache_size)
231
+ ```
232
+
233
+ **Multiprocessing workers:**
234
+
235
+ ```python
236
+ def worker(queue):
237
+ repo = LoggingRepository(config, use_listener=False, queue=queue)
238
+ repo.task.info("Worker task started")
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Project Structure
244
+
245
+ ```
246
+ miu_logger/
247
+ ├─ repository.py # main LoggingRepository
248
+ ├─ listener.py # QueueListener and handler setup
249
+ ├─ logger_factory.py # logger creation functions
250
+ ├─ conditional.py # ConditionalLogger
251
+ ├─ filters.py # Logger filters
252
+ ├─ formatters.py # ColoredFormatter
253
+ ├─ config.py # LogConfig definition
254
+ └─ stubgen.py # stub generator for IDE autocomplete
255
+ ```
256
+
257
+ ---
258
+
259
+ ## When to Use
260
+
261
+ * Services with many subsystems
262
+ * Multiprocessing ingestion pipelines
263
+ * Long-running daemons
264
+ * Kubernetes / systemd services
265
+ * Need for clear operational logs
266
+
267
+ ---
268
+
269
+ ## When Not to Use
270
+
271
+ * Single-file scripts
272
+ * No multiprocessing
273
+ * No domain separation required
274
+
275
+ Plain `logging` is sufficient in those cases.
276
+
277
+ ---
278
+
279
+ ## License
280
+
281
+ MIT
282
+
283
+ ---
284
+
285
+ ## Author
286
+
287
+ **Bruno Miura**
@@ -7,8 +7,8 @@ miu_logger/listener.py,sha256=K6JDf-R3VQx6t1zfNnh3ltJRnAyYdV5TFTAeWQqc6bU,3336
7
7
  miu_logger/logger_factory.py,sha256=MhNaP73J9RbhmmVR6simqkZRCel2g6rPImRlijYAQXI,319
8
8
  miu_logger/repository.py,sha256=FQOO-njKzW6i528EJpDYfusPDbW2DEGcVpxnqHUbzgg,2458
9
9
  miu_logger/stubgen.py,sha256=w0TJRu2aG55Gs1_tKwOcU7f7Nmr6j0l36rMgMHsz-SM,1878
10
- miu_logger-0.1.6.dist-info/licenses/LICENSE,sha256=jLLem0QFpsFv7Lkgp7I7FeN4DIdgCKIxzklfdkkesWg,1075
11
- miu_logger-0.1.6.dist-info/METADATA,sha256=ufZi24rFlglR7Cb5qaNBPA3D54f3JSgjUGlXnu2xoq8,2915
12
- miu_logger-0.1.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
13
- miu_logger-0.1.6.dist-info/top_level.txt,sha256=70Nuj1YRYLMkqiRZv1pPZPhi_VystPGqm1nC3s-uHz4,11
14
- miu_logger-0.1.6.dist-info/RECORD,,
10
+ miu_logger-0.2.0.dist-info/licenses/LICENSE,sha256=jLLem0QFpsFv7Lkgp7I7FeN4DIdgCKIxzklfdkkesWg,1075
11
+ miu_logger-0.2.0.dist-info/METADATA,sha256=grikqmBJXT_Iqwd7V7mK70jlcm-w6J_AFffzJH0dN-M,6030
12
+ miu_logger-0.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
13
+ miu_logger-0.2.0.dist-info/top_level.txt,sha256=70Nuj1YRYLMkqiRZv1pPZPhi_VystPGqm1nC3s-uHz4,11
14
+ miu_logger-0.2.0.dist-info/RECORD,,
@@ -1,151 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: miu-logger
3
- Version: 0.1.6
4
- Summary: Multiprocessing-safe domain-based logging framework with QueueListener architecture
5
- Author-email: Bruno Miura <brumiura@gmail.com>
6
- License-Expression: MIT
7
- Keywords: logging,multiprocessing,queue,structured-logging,python-logging
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3 :: Only
10
- Classifier: Operating System :: OS Independent
11
- Classifier: Topic :: System :: Logging
12
- Requires-Python: >=3.10
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
- Requires-Dist: colorama
16
- Dynamic: license-file
17
-
18
- ```python
19
- repo = LoggingRepository(config)
20
- queue = repo.get_queue()
21
- ```
22
-
23
- **Worker processes:**
24
-
25
- ```python
26
- worker_repo = LoggingRepository(config, use_listener=False, queue=queue)
27
- worker_repo.task.info("Worker started")
28
- ```
29
-
30
- All processes log safely to the same listener and files.
31
-
32
- ---
33
-
34
- ## Debug Control
35
-
36
- Only `.debug()` messages are conditional via `debug_enabled`:
37
-
38
- ```python
39
- config.debug_enabled = False
40
- repo.app.debug("Won't appear")
41
- repo.app.info("Will appear")
42
- ```
43
-
44
- Useful for toggling debug messages in production.
45
-
46
- ---
47
-
48
- ## Output Structure
49
-
50
- Logs are written in:
51
-
52
- ```
53
- logs/
54
- ├─ app.log # domain logs
55
- ├─ db.log
56
- ├─ redis.log
57
- ├─ debug.log # per-level logs
58
- ├─ info.log
59
- ├─ warning.log
60
- └─ error.log
61
- ```
62
-
63
- Console output is **colorized** by level:
64
-
65
- * DEBUG → blue
66
- * INFO → green
67
- * WARNING → yellow
68
- * ERROR → red
69
-
70
- Files remain clean.
71
-
72
- ---
73
-
74
- ## Graceful Shutdown
75
-
76
- The repository automatically shuts down on process exit and supports manual shutdown:
77
-
78
- ```python
79
- repo.shutdown()
80
- ```
81
-
82
- ---
83
-
84
- ## Typical Usage Example
85
-
86
- ```python
87
- repo.app.info("Service starting")
88
-
89
- try:
90
- connect_db()
91
- except Exception:
92
- repo.db.exception("DB connection failed")
93
-
94
- repo.redis.debug("Cache size: %d", cache_size)
95
- ```
96
-
97
- **Multiprocessing workers:**
98
-
99
- ```python
100
- def worker(queue):
101
- repo = LoggingRepository(config, use_listener=False, queue=queue)
102
- repo.task.info("Worker task started")
103
- ```
104
-
105
- ---
106
-
107
- ## Project Structure
108
-
109
- ```
110
- miu_logger/
111
- ├─ repository.py # main LoggingRepository
112
- ├─ listener.py # QueueListener and handler setup
113
- ├─ logger_factory.py # logger creation functions
114
- ├─ conditional.py # ConditionalLogger
115
- ├─ filters.py # Logger filters
116
- ├─ formatters.py # ColoredFormatter
117
- ├─ config.py # LogConfig definition
118
- └─ stubgen.py # stub generator for IDE autocomplete
119
- ```
120
-
121
- ---
122
-
123
- ## When to Use
124
-
125
- * Services with many subsystems
126
- * Multiprocessing ingestion pipelines
127
- * Long-running daemons
128
- * Kubernetes / systemd services
129
- * Need for clear operational logs
130
-
131
- ---
132
-
133
- ## When Not to Use
134
-
135
- * Single-file scripts
136
- * No multiprocessing
137
- * No domain separation required
138
-
139
- Plain `logging` is sufficient in those cases.
140
-
141
- ---
142
-
143
- ## License
144
-
145
- MIT
146
-
147
- ---
148
-
149
- ## Author
150
-
151
- **Bruno Miura**