simplibs-logger 0.1.0__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 (60) hide show
  1. simplibs_logger-0.1.0/LICENSE +21 -0
  2. simplibs_logger-0.1.0/PKG-INFO +508 -0
  3. simplibs_logger-0.1.0/README.md +474 -0
  4. simplibs_logger-0.1.0/pyproject.toml +78 -0
  5. simplibs_logger-0.1.0/setup.cfg +4 -0
  6. simplibs_logger-0.1.0/src/simplibs/logger/SimpleLogger.py +347 -0
  7. simplibs_logger-0.1.0/src/simplibs/logger/__init__.py +87 -0
  8. simplibs_logger-0.1.0/src/simplibs/logger/annotations/BackupCount.py +24 -0
  9. simplibs_logger-0.1.0/src/simplibs/logger/annotations/LogStream.py +29 -0
  10. simplibs_logger-0.1.0/src/simplibs/logger/annotations/MaxBytes.py +24 -0
  11. simplibs_logger-0.1.0/src/simplibs/logger/annotations/__init__.py +20 -0
  12. simplibs_logger-0.1.0/src/simplibs/logger/annotations/_helpers/__init__.py +19 -0
  13. simplibs_logger-0.1.0/src/simplibs/logger/annotations/_helpers/is_backup_count.py +25 -0
  14. simplibs_logger-0.1.0/src/simplibs/logger/annotations/_helpers/is_max_bytes.py +26 -0
  15. simplibs_logger-0.1.0/src/simplibs/logger/annotations/_helpers/is_writable_stream.py +30 -0
  16. simplibs_logger-0.1.0/src/simplibs/logger/definitions/DateFormat.py +51 -0
  17. simplibs_logger-0.1.0/src/simplibs/logger/definitions/LoggerLevel.py +73 -0
  18. simplibs_logger-0.1.0/src/simplibs/logger/definitions/LoggerName.py +58 -0
  19. simplibs_logger-0.1.0/src/simplibs/logger/definitions/MessageFormat.py +59 -0
  20. simplibs_logger-0.1.0/src/simplibs/logger/definitions/OutputFormat.py +38 -0
  21. simplibs_logger-0.1.0/src/simplibs/logger/definitions/__init__.py +31 -0
  22. simplibs_logger-0.1.0/src/simplibs/logger/definitions/constants/LEVEL_NAMES.py +36 -0
  23. simplibs_logger-0.1.0/src/simplibs/logger/definitions/constants/OUTPUT_FORMATS.py +25 -0
  24. simplibs_logger-0.1.0/src/simplibs/logger/definitions/constants/SUCCESS_LEVEL.py +23 -0
  25. simplibs_logger-0.1.0/src/simplibs/logger/definitions/constants/__init__.py +19 -0
  26. simplibs_logger-0.1.0/src/simplibs/logger/formatting/ColoredFormatter.py +97 -0
  27. simplibs_logger-0.1.0/src/simplibs/logger/formatting/JsonFormatter.py +159 -0
  28. simplibs_logger-0.1.0/src/simplibs/logger/formatting/__init__.py +21 -0
  29. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/__init__.py +24 -0
  30. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/collect_extra_fields.py +43 -0
  31. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/constants/JSON_KEYS.py +22 -0
  32. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/constants/LEVEL_STYLES.py +38 -0
  33. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/constants/RECORD_ATTRIBUTES.py +24 -0
  34. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/constants/__init__.py +16 -0
  35. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/encode_unknown_value.py +69 -0
  36. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/format_json_time.py +40 -0
  37. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/parse_levelname_field.py +56 -0
  38. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/pick_level_style.py +34 -0
  39. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/replace_non_finite.py +48 -0
  40. simplibs_logger-0.1.0/src/simplibs/logger/formatting/_helpers/style_levelname.py +47 -0
  41. simplibs_logger-0.1.0/src/simplibs/logger/formatting/build_formatter.py +89 -0
  42. simplibs_logger-0.1.0/src/simplibs/logger/handlers/__init__.py +18 -0
  43. simplibs_logger-0.1.0/src/simplibs/logger/handlers/_validations/__init__.py +12 -0
  44. simplibs_logger-0.1.0/src/simplibs/logger/handlers/_validations/raise_log_file_open_error.py +47 -0
  45. simplibs_logger-0.1.0/src/simplibs/logger/handlers/build_console_handler.py +83 -0
  46. simplibs_logger-0.1.0/src/simplibs/logger/handlers/build_file_handler.py +119 -0
  47. simplibs_logger-0.1.0/src/simplibs/logger/levels/__init__.py +18 -0
  48. simplibs_logger-0.1.0/src/simplibs/logger/levels/register_success_level.py +33 -0
  49. simplibs_logger-0.1.0/src/simplibs/logger/levels/resolve_level.py +43 -0
  50. simplibs_logger-0.1.0/src/simplibs/logger/lifecycle/__init__.py +19 -0
  51. simplibs_logger-0.1.0/src/simplibs/logger/lifecycle/close_logger.py +45 -0
  52. simplibs_logger-0.1.0/src/simplibs/logger/lifecycle/create_logger.py +172 -0
  53. simplibs_logger-0.1.0/src/simplibs/logger/py.typed +1 -0
  54. simplibs_logger-0.1.0/src/simplibs_logger.egg-info/PKG-INFO +508 -0
  55. simplibs_logger-0.1.0/src/simplibs_logger.egg-info/SOURCES.txt +58 -0
  56. simplibs_logger-0.1.0/src/simplibs_logger.egg-info/dependency_links.txt +1 -0
  57. simplibs_logger-0.1.0/src/simplibs_logger.egg-info/requires.txt +10 -0
  58. simplibs_logger-0.1.0/src/simplibs_logger.egg-info/top_level.txt +1 -0
  59. simplibs_logger-0.1.0/tests/test_SimpleLogger.py +454 -0
  60. simplibs_logger-0.1.0/tests/test_root_init.py +28 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dalibor Sova (Sudip2708)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,508 @@
1
+ Metadata-Version: 2.4
2
+ Name: simplibs-logger
3
+ Version: 0.1.0
4
+ Summary: A ready-to-use logger on top of the standard logging module: a console, an optional rotating file, colored level names, optional JSON output and a short calling interface.
5
+ Author-email: "Dalibor Sova (Sudip2708)" <daliborsova@seznam.cz>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/simplibs/simplibs-logger
8
+ Project-URL: Repository, https://github.com/simplibs/simplibs-logger
9
+ Project-URL: Issues, https://github.com/simplibs/simplibs-logger/issues
10
+ Project-URL: Changelog, https://github.com/simplibs/simplibs-logger/blob/main/CHANGELOG.md
11
+ Keywords: logger,logging,log,console,json,jsonl,rotating-file,colors,simplibs,simplibs-logger,developer-tools
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: System :: Logging
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: simplibs-exception>=1.1.4
25
+ Requires-Dist: simplibs-object>=0.1.0
26
+ Requires-Dist: simplibs-validate>=0.3.2
27
+ Requires-Dist: simplibs-path>=0.1.1
28
+ Requires-Dist: simplibs-style>=0.1.0
29
+ Requires-Dist: simplibs-file>=0.1.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=9.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # 📜 `simplibs-logger`
36
+
37
+ [![PyPI](https://img.shields.io/pypi/v/simplibs-logger)](https://pypi.org/project/simplibs-logger/)
38
+ [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/downloads/)
39
+ [![Licence](https://img.shields.io/badge/licence-MIT-green)](https://github.com/simplibs/simplibs-logger/blob/main/LICENSE)
40
+ [![tests](https://github.com/simplibs/simplibs-logger/actions/workflows/tests.yml/badge.svg)](https://github.com/simplibs/simplibs-logger/actions)
41
+
42
+ **A logger that works the moment you create it.**
43
+
44
+ A ready-to-use logger built **on** the standard `logging` module, not instead of it: one constructor gives
45
+ you a colored console, an optional rotating file, optional JSON output and a short way to write —
46
+ `logger.log_info("text %s", value)`. A wrong level, format or stream fails when you give it, not when the
47
+ first record is written, and a record always points at the line of *your* code.
48
+
49
+ ```python
50
+ from simplibs.logger import SimpleLogger
51
+
52
+ logger = SimpleLogger(name="my_app", file_path="logs/app.log")
53
+
54
+ logger.log_info("Application started")
55
+ logger.log_success("Import finished: %d rows", 120) # SUCCESS, level 25 — between INFO and WARNING
56
+ logger("Disk almost full", level="warning") # the logger is callable
57
+ ```
58
+
59
+ > Works with [`simplibs-cli`](https://pypi.org/project/simplibs-cli/): `resolve_verbosity(quiet=…, verbose=…)`
60
+ > returns a level that `SimpleLogger(level=…)` accepts as it is.
61
+
62
+ ---
63
+
64
+ ## 🧭 The Core Philosophy
65
+
66
+ The standard `logging` module is powerful and starts empty: a logger with no handler, a default level that
67
+ swallows `info`, a format that fails with a bare `ValueError` on the first record, a file that grows
68
+ until the disk is full. Every program configures the same things by hand — and every copy forgets one.
69
+ `simplibs-logger` is that configuration, written once and checked.
70
+
71
+ * **It works at once.** The default level is INFO, the console is colored, and nothing needs configuring
72
+ before `log_info` writes a line.
73
+ * **On top of `logging`, never beside it.** A `SimpleLogger` wraps a real `logging.Logger` (`logger.logger`),
74
+ and the handlers and formatters are standard classes you can attach to any logger yourself.
75
+ * **A wrong value fails early.** Levels, names, formats, output kinds and streams are validated when they
76
+ are given — with the very function the standard library will call later.
77
+ * **Build first, swap after.** Every handler is built, and the file opened, before the existing logger is
78
+ touched. A bad path leaves the previous setup in place, and handlers are closed, never leaked.
79
+ * **The right place in the traceback.** File, line and function are those of the code that called the
80
+ logger, for `log_info`, for `logger("text")` and for everything between.
81
+ * **Text for people, JSON for machines.** A readable console and a JSON Lines file are one call.
82
+ * **Layers that only look left.** `definitions` and `annotations` ← `levels` ← `formatting` ← `handlers` ←
83
+ `lifecycle` ← `SimpleLogger` — every layer imports only from those before it.
84
+
85
+ ```python
86
+ SimpleLogger(level="loud") # -> raises: unknown level name
87
+ SimpleLogger(message_format="%(asctime)s %") # -> raises: not a valid message format
88
+ SimpleLogger(max_bytes=0) # -> raises: zero would mean "never rotate"
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 📦 Installation
94
+
95
+ ```bash
96
+ pip install simplibs-logger
97
+ ```
98
+
99
+ Requires Python 3.11+. The runtime dependencies (installed automatically) are other simplibs libraries:
100
+ [`simplibs-exception`](https://pypi.org/project/simplibs-exception/) for the error card of a log file that
101
+ cannot be opened, [`simplibs-object`](https://pypi.org/project/simplibs-object/) for the validated atoms,
102
+ [`simplibs-validate`](https://pypi.org/project/simplibs-validate/) for `@validate_call` and the validated
103
+ types, [`simplibs-path`](https://pypi.org/project/simplibs-path/) for the log file's path,
104
+ [`simplibs-style`](https://pypi.org/project/simplibs-style/) for the colors, and
105
+ [`simplibs-file`](https://pypi.org/project/simplibs-file/) for the type of the encoding.
106
+
107
+ ---
108
+
109
+ ## 🚀 Quick Start in 60 Seconds
110
+
111
+ ### Level 1: A logger with no setup
112
+
113
+ ```python
114
+ from simplibs.logger import SimpleLogger
115
+
116
+ logger = SimpleLogger()
117
+
118
+ logger.log_debug("Not shown — the default level is INFO")
119
+ logger.log_info("Application started")
120
+ logger.log_success("Import finished: %d rows", 120)
121
+ logger.log_warning("Disk almost full")
122
+ logger.log_error("Request failed")
123
+ ```
124
+
125
+ ```text
126
+ 2026-10-24 12:00:00 | INFO | simplibs | Application started
127
+ 2026-10-24 12:00:00 | SUCCESS | simplibs | Import finished: 120 rows
128
+ 2026-10-24 12:00:00 | WARNING | simplibs | Disk almost full
129
+ 2026-10-24 12:00:00 | ERROR | simplibs | Request failed
130
+ ```
131
+
132
+ The records go to standard error, and the level names are colored in a terminal. The columns stay
133
+ straight, because the padding counts the visible name, not the color codes.
134
+
135
+ ### Level 2: A file that rotates, closed properly
136
+
137
+ ```python
138
+ from simplibs.logger import SimpleLogger
139
+
140
+ with SimpleLogger(name="my_app", level="debug", file_path="logs/app.log",
141
+ max_bytes=1_000_000, backup_count=5) as logger:
142
+ logger.log_debug("Connecting to %s", "db.local")
143
+ logger.log_info("Ready")
144
+ ```
145
+
146
+ `logs/` and the file are created when missing. The file is plain text, never colored, and at 1 MB it
147
+ becomes `app.log.1` while five older files are kept. Leaving the `with` block closes the file.
148
+
149
+ ### Level 3: JSON for the machines
150
+
151
+ ```python
152
+ from simplibs.logger import SimpleLogger
153
+
154
+ logger = SimpleLogger(name="api", file_path="logs/api.jsonl", file_output="json", utc=True)
155
+
156
+ logger.log_info("request done", extra={"request_id": "r-7", "status": 200})
157
+ ```
158
+
159
+ The console stays readable text; the file gets one JSON object per line:
160
+
161
+ ```json
162
+ {"time":"2026-10-24T12:34:56.789Z","level":"INFO","logger":"api","message":"request done","function":"<module>","file":"app.py","line":5,"request_id":"r-7","status":200}
163
+ ```
164
+
165
+ ### Level 4: Exceptions, the switch and your own wiring
166
+
167
+ ```python
168
+ import logging
169
+ from simplibs.logger import SimpleLogger, build_console_handler
170
+
171
+ logger = SimpleLogger(name="importer", level="debug")
172
+
173
+ def import_rows():
174
+ raise ValueError("row 3 is broken")
175
+
176
+ try:
177
+ import_rows()
178
+ except ValueError:
179
+ logger.log_exception("Import failed") # ERROR + the traceback
180
+
181
+ if logger.is_enabled_for("debug"): # worth asking before an expensive message
182
+ logger.log_debug("state: %s", {"rows": 3})
183
+
184
+ logger.enabled = False # silence it, whatever the level
185
+ logger.log_error("not written")
186
+
187
+ # the pieces work on any standard logger
188
+ third_party = logging.getLogger("third_party")
189
+ third_party.addHandler(build_console_handler(level="warning"))
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 🛠️ Architecture & Package Structure
195
+
196
+ ```
197
+ src/simplibs/logger/
198
+ ├── annotations/ ◄── Validated types for signatures (BackupCount, MaxBytes, LogStream)
199
+ ├── definitions/ ◄── Validated atoms and fixed values (LoggerLevel, LoggerName, ... SUCCESS_LEVEL)
200
+ ├── levels/ ◄── A name to a number, and the name SUCCESS (resolve_level, register_success_level)
201
+ ├── formatting/ ◄── How a record looks (build_formatter, ColoredFormatter, JsonFormatter)
202
+ ├── handlers/ ◄── Where records go (build_console_handler, build_file_handler)
203
+ ├── lifecycle/ ◄── Create and release (create_logger, close_logger)
204
+ └── SimpleLogger.py ◄── The ready-to-use logger class
205
+ ```
206
+
207
+ The root of the package exports everything — the logger, the building blocks, the atoms, the constants and
208
+ the annotations — so one import line is all a program needs. The folders are plain packages for the code's
209
+ own organization; nothing has to be imported from them. The internal `_helpers` and `_validations` of each
210
+ folder are not exported.
211
+
212
+ ```python
213
+ from simplibs.logger import SimpleLogger, create_logger, close_logger
214
+ from simplibs.logger import build_console_handler, build_file_handler, build_formatter, JsonFormatter
215
+ ```
216
+
217
+ ---
218
+
219
+ ## 📒 SimpleLogger — The Ready-to-Use Logger
220
+
221
+ The class most programs need: a configured `logging.Logger` behind a small calling interface. The
222
+ constructor builds the console, the file, the colors and the JSON output; `log_info`, `log_success`,
223
+ `log_warning`, … write the records, `logger("text")` writes at the default level, and `log_exception`
224
+ adds the traceback. It has an `enabled` switch, `is_enabled_for(level)`, `set_level`, `close()` and works as
225
+ a context manager.
226
+
227
+ ```python
228
+ logger = SimpleLogger(file_path="logs/app.log")
229
+ logger.log_info("user %s logged in", name)
230
+ ```
231
+
232
+ ➡️ [README_LOGGER_SIMPLELOGGER](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_SIMPLELOGGER.md)
233
+
234
+ ---
235
+
236
+ ## 🔄 Lifecycle — Create and Release
237
+
238
+ Two functions underneath `SimpleLogger`, for a program that wants a plain `logging.Logger`:
239
+ `create_logger` builds one, validated, with no duplicate handlers however often it is called, and
240
+ `close_logger` detaches **and closes** every handler so the log file is released.
241
+
242
+ ```python
243
+ logger = create_logger(name="my_app", level="debug", file_path="logs/app.log", propagate=True)
244
+ close_logger(logger)
245
+ ```
246
+
247
+ ➡️ [README_LOGGER_LIFECYCLE](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_LIFECYCLE.md)
248
+
249
+ ---
250
+
251
+ ## 📮 Handlers — Where Records Go
252
+
253
+ Two builders of standard handlers: `build_console_handler` (standard error by default, any object with
254
+ `write` as a stream) and `build_file_handler` (creates its folder and file, rotates with `max_bytes`, and
255
+ turns a failed open into a structured card). A handler has no level of its own unless one is asked for, so
256
+ the logger decides.
257
+
258
+ ```python
259
+ console = build_console_handler(level="warning", output="json")
260
+ file = build_file_handler("logs/app.log", max_bytes=1_000_000)
261
+ ```
262
+
263
+ ➡️ [README_LOGGER_HANDLERS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_HANDLERS.md)
264
+
265
+ ---
266
+
267
+ ## 🎨 Formatting — How a Record Looks
268
+
269
+ `build_formatter` is the one place a formatter is made and validated. `ColoredFormatter` colors the level
270
+ name and keeps the columns straight; `JsonFormatter` writes each record as one line of valid JSON, with the
271
+ fields of `extra=` as flat keys.
272
+
273
+ | Output | Formatter | For |
274
+ |----------|---------------------|------------------------------------------------|
275
+ | `text` | `logging.Formatter` | A file read by a person. |
276
+ | `text`, colored | `ColoredFormatter` | The console. |
277
+ | `json` | `JsonFormatter` | A log collector, `jq`, a container's stderr. |
278
+
279
+ ➡️ [README_LOGGER_FORMATTING](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_FORMATTING.md)
280
+
281
+ ---
282
+
283
+ ## 📶 Levels — Numbers and Names
284
+
285
+ `resolve_level` turns a level written as a number or a name (`"debug"`, `"SUCCESS"`, `35`) into the number,
286
+ and `register_success_level` gives the number 25 the name `SUCCESS` in `logging`, once, without overwriting
287
+ a name another library chose.
288
+
289
+ ```python
290
+ resolve_level("debug") # -> 10
291
+ resolve_level(None) # -> 20
292
+ ```
293
+
294
+ ➡️ [README_LOGGER_LEVELS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_LEVELS.md)
295
+
296
+ ---
297
+
298
+ ## 🧬 Definitions — Validated Atoms and Fixed Values
299
+
300
+ The vocabulary of the library. Five validated atoms say what a value may be and what it is when nobody
301
+ chose; three constants hold the fixed values behind them.
302
+
303
+ | Name | What it is |
304
+ |-------------------|----------------------------------------------------------------------------|
305
+ | `LoggerLevel` | A positive number or a level name; default INFO. |
306
+ | `LoggerName` | A name that cannot reach the root logger; default `"simplibs"`. |
307
+ | `DateFormat` | A `time.strftime` format; default `"%Y-%m-%d %H:%M:%S"`. |
308
+ | `MessageFormat` | A `%`-style line format, syntax checked, field names free. |
309
+ | `OutputFormat` | `"text"` (default) or `"json"`. |
310
+ | `SUCCESS_LEVEL`, `LEVEL_NAMES`, `OUTPUT_FORMATS` | The level 25, the six level names, the two output formats. |
311
+
312
+ ➡️ [README_LOGGER_DEFINITIONS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_DEFINITIONS.md)
313
+
314
+ ---
315
+
316
+ ## 🔖 Annotations — Types for Your Signatures
317
+
318
+ Three validated types that this library's signatures use and a caller can use in theirs, with
319
+ `@validate_call`:
320
+
321
+ | Type | Accepts |
322
+ |---------------|----------------------------------------------------------|
323
+ | `BackupCount` | An `int` of at least one. |
324
+ | `MaxBytes` | An `int` greater than zero, or `None` — never rotate. |
325
+ | `LogStream` | Any object with `write`, or `None` — standard error. |
326
+
327
+ ➡️ [README_LOGGER_ANNOTATIONS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_ANNOTATIONS.md)
328
+
329
+ ---
330
+
331
+ ## 📖 Quick Reference
332
+
333
+ ### 📒 `SimpleLogger` — The Ready-to-Use Logger
334
+
335
+ | Member | Description / Parameters |
336
+ |------------------------------|--------------------------------------------------------------------------------------------|
337
+ | `SimpleLogger(...)` | Builds the logger (`enabled`, `name`, `level`, `default_level`, `file_path`, `encoding`, `console`, `colored`, `console_level`, `file_level`, `stream`, `message_format`, `date_format`, `utc`, `max_bytes`, `backup_count`, `console_output`, `file_output`, `json_default`). |
338
+ | `log`, `logger(...)` | Writes at `level` or at `default_level` (`message`, `*args`, `level=None`, `**kwargs`). |
339
+ | `log_debug` … `log_critical` | One method per level, incl. `log_success` (`message`, `*args`, `**kwargs`). |
340
+ | `log_exception` | ERROR with the traceback (`message`, `*args`, `**kwargs`). |
341
+ | `is_enabled_for` | Would a record of this level be written now (`level=None`). |
342
+ | `set_level` | Changes the level of the logger (`level`). |
343
+ | `enabled` | The switch; assignable. |
344
+ | `logger`, `name`, `level` | The underlying logger, its name and level. Read-only. |
345
+ | `close`, `with` | Closes every handler and stops writing. |
346
+
347
+ ➡️ [README_LOGGER_SIMPLELOGGER](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_SIMPLELOGGER.md)
348
+
349
+ ---
350
+
351
+ ### 🔄 `lifecycle/` — Create and Release
352
+
353
+ | Function | Description / Parameters |
354
+ |-----------------|------------------------------------------------------------------------------------------|
355
+ | `create_logger` | Builds a validated `logging.Logger` (the arguments of `SimpleLogger` without `enabled` and `default_level`, plus `propagate=False`). |
356
+ | `close_logger` | Detaches and closes every handler of a logger (`logger`). |
357
+
358
+ ➡️ [README_LOGGER_LIFECYCLE](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_LIFECYCLE.md)
359
+
360
+ ---
361
+
362
+ ### 📮 `handlers/` — Where Records Go
363
+
364
+ | Function | Description / Parameters |
365
+ |-------------------------|-----------------------------------------------------------------------------------|
366
+ | `build_console_handler` | A stream handler (`level`, `stream`, `message_format`, `date_format`, `colored=True`, `utc`, `output`, `json_default`). |
367
+ | `build_file_handler` | A file handler, optionally rotating (`file_path`, `level`, `encoding`, `message_format`, `date_format`, `utc`, `max_bytes`, `backup_count=3`, `output`, `json_default`). |
368
+
369
+ ➡️ [README_LOGGER_HANDLERS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_HANDLERS.md)
370
+
371
+ ---
372
+
373
+ ### 🎨 `formatting/` — How a Record Looks
374
+
375
+ | Name | Description / Parameters |
376
+ |--------------------|---------------------------------------------------------------------------------------|
377
+ | `build_formatter` | A validated formatter (`message_format`, `date_format`, `colored=False`, `utc`, `output`, `json_default`). |
378
+ | `ColoredFormatter` | Colors the level name, padding included (`fmt`, `datefmt`). |
379
+ | `JsonFormatter` | One JSON object per line (`utc=False`, `default=None`). |
380
+
381
+ ➡️ [README_LOGGER_FORMATTING](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_FORMATTING.md)
382
+
383
+ ---
384
+
385
+ ### 📶 `levels/` — Numbers and Names
386
+
387
+ | Function | Description / Parameters |
388
+ |--------------------------|------------------------------------------------------------------|
389
+ | `resolve_level` | A level as a number (`level=None`). |
390
+ | `register_success_level` | Names the number 25 `SUCCESS`, once. |
391
+
392
+ ➡️ [README_LOGGER_LEVELS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_LEVELS.md)
393
+
394
+ ---
395
+
396
+ ### 🧬 `definitions/` — Validated Atoms and Fixed Values
397
+
398
+ | Name | Description |
399
+ |----------------------------------------|---------------------------------------------------------------|
400
+ | `LoggerLevel`, `LoggerName` | A level (default INFO); a logger name (default `"simplibs"`). |
401
+ | `DateFormat`, `MessageFormat` | A `strftime` format; a `%`-style line format. |
402
+ | `OutputFormat` | `"text"` or `"json"`. |
403
+ | `SUCCESS_LEVEL`, `LEVEL_NAMES`, `OUTPUT_FORMATS` | `25`; the six level names; `("text", "json")`. |
404
+
405
+ ➡️ [README_LOGGER_DEFINITIONS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_DEFINITIONS.md)
406
+
407
+ ---
408
+
409
+ ### 🔖 `annotations/` — Types for Your Signatures
410
+
411
+ | Type | Description |
412
+ |---------------|----------------------------------------------------------|
413
+ | `BackupCount` | How many rotated files to keep; at least one. |
414
+ | `MaxBytes` | A size limit in bytes, or `None` for no rotation. |
415
+ | `LogStream` | A stream with `write`, or `None` for standard error. |
416
+
417
+ ➡️ [README_LOGGER_ANNOTATIONS](https://github.com/simplibs/simplibs-logger/blob/main/docs/README_LOGGER_ANNOTATIONS.md)
418
+
419
+ ---
420
+
421
+ ## 🔌 Streams, Colors and Files
422
+
423
+ How the logger behaves where the output goes somewhere other than a terminal:
424
+
425
+ * **The console is standard error.** Diagnostics belong there. A program that prints its log next to its own
426
+ output passes `stream=sys.stdout`; any object with `write` works.
427
+ * **The color follows the style switch, not the stream.** `simplibs-style` decides — from `NO_COLOR`,
428
+ `FORCE_COLOR`, `TERM=dumb` and from whether *standard output* is a terminal. A program that redirects
429
+ only one of the two passes `colored=False`, or calls `set_styles_enabled(False)`.
430
+ * **Files and JSON are never colored.** ANSI codes do not belong in a file.
431
+ * **The default level is INFO** (the standard library starts at WARNING), and `SUCCESS` is the number 25.
432
+ * **One name, one logger.** `SimpleLogger(name="x")` twice gives the same underlying logger and the second
433
+ reconfigures the first. The default name `"simplibs"` is the parent of every `simplibs.*` logger, so the default logger also
434
+ receives what other simplibs libraries log through plain `logging`. A `SimpleLogger` or `create_logger`
435
+ logger does not pass its records up unless `propagate=True`.
436
+ * **Close what you open.** `close()` and `with` release the log file — on Windows an open handler blocks
437
+ deleting or rotating it. On Windows, rotation also needs the file to be open in one process only.
438
+
439
+ ---
440
+
441
+ ## ⚠️ Exceptions
442
+
443
+ The library defines one error of its own: a structured
444
+ [`AccessError`](https://pypi.org/project/simplibs-exception/) card, with a name that starts with `LOGGER_`.
445
+ Everything else is refused by the libraries it is built on, each with its own structured card: an invalid
446
+ level, name or format by the atoms (`simplibs-object`), a wrong argument type by `@validate_call`
447
+ (`simplibs-validate`), and a path that cannot be prepared by `ensure_file` (`simplibs-path`).
448
+
449
+ | Error name | Card | Wraps | Raised when |
450
+ |---------------------------|---------------|-------------------------------------|--------------------------------------------|
451
+ | `LOGGER_FILE_OPEN_FAILED` | `AccessError` | the caught `OSError` (its own type) | The OS refuses to open the log file. |
452
+
453
+ Because the card keeps the original exception type, `except PermissionError` still works.
454
+
455
+ ---
456
+
457
+ ## 🔗 Related libraries
458
+
459
+ * **[`simplibs-exception`](https://pypi.org/project/simplibs-exception/)** — the structured card of a log file that cannot be opened.
460
+ * **[`simplibs-object`](https://pypi.org/project/simplibs-object/)** — `SimpleConstant`, the base of the validated atoms.
461
+ * **[`simplibs-validate`](https://pypi.org/project/simplibs-validate/)** — `@validate_call` and the validated types behind the annotations.
462
+ * **[`simplibs-path`](https://pypi.org/project/simplibs-path/)** — `ensure_file` and `PathLike` for the log file.
463
+ * **[`simplibs-style`](https://pypi.org/project/simplibs-style/)** — the colors of the level names and the switch that turns them off.
464
+ * **[`simplibs-file`](https://pypi.org/project/simplibs-file/)** — `EncodingName`, the type of the file's encoding.
465
+ * **[`simplibs-cli`](https://pypi.org/project/simplibs-cli/)** — `resolve_verbosity` turns `--quiet` and `-v` into a level for this logger.
466
+
467
+ ---
468
+
469
+ ## ☯️ About simplibs
470
+
471
+ All libraries in the **simplibs** (Simple Libraries) ecosystem share a common
472
+ engineering philosophy:
473
+
474
+ * **Dyslexia-friendly:**
475
+ We actively minimize cognitive load. Code is atomized into small, self-contained units,
476
+ files are named directly after the logical task they perform, and explanations describe
477
+ *why* something is designed, not just *what* it is.
478
+ * **Programmer's Zen:**
479
+ Nothing should be missing, and nothing should be superfluous. We value clean execution
480
+ paths and robust, understandable code architectures over rushed, messy feature sets.
481
+ * **Defensive Style:**
482
+ We actively anticipate edge cases and failure modes so that only safe operational paths
483
+ remain. Our code is built to degrade gracefully rather than crash unexpectedly.
484
+ * **Minimalism:**
485
+ Find the most direct path to the goal in as few operational steps as possible without
486
+ taking shortcuts on safety, readability, or completeness.
487
+ * **Code as Craft:**
488
+ Code should be pleasant to look at, readable at a glance, and evoke structural harmony.
489
+ We treat software engineering as a precision trade.
490
+
491
+ ---
492
+
493
+ ### 🤝 Contributing & Community
494
+
495
+ This is an **open-source project** built with love and care. We strongly believe in
496
+ community collaboration and welcome any feedback, bug reports, or feature ideas!
497
+
498
+ * **Want to contribute?** Feel free to open an Issue or submit a Pull Request.
499
+ * **Want to get in touch?** If you'd like to discuss the project further, collaborate,
500
+ or just say hello, feel free to open a GitHub Issue or start a Discussion.
501
+
502
+ ---
503
+
504
+ ### 📝 License
505
+
506
+ This library is released under the **MIT License**. Build great things!
507
+
508
+ ---