aiologging 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.
- aiologging-0.1.0/LICENSE +21 -0
- aiologging-0.1.0/PKG-INFO +600 -0
- aiologging-0.1.0/README.md +530 -0
- aiologging-0.1.0/aiologging/__init__.py +326 -0
- aiologging-0.1.0/aiologging/config.py +529 -0
- aiologging-0.1.0/aiologging/exceptions.py +898 -0
- aiologging-0.1.0/aiologging/handlers/__init__.py +32 -0
- aiologging-0.1.0/aiologging/handlers/base.py +793 -0
- aiologging-0.1.0/aiologging/handlers/file.py +418 -0
- aiologging-0.1.0/aiologging/handlers/http.py +779 -0
- aiologging-0.1.0/aiologging/handlers/rotating.py +563 -0
- aiologging-0.1.0/aiologging/handlers/stream.py +296 -0
- aiologging-0.1.0/aiologging/logger.py +721 -0
- aiologging-0.1.0/aiologging/py.typed +0 -0
- aiologging-0.1.0/aiologging/types.py +624 -0
- aiologging-0.1.0/aiologging/utils.py +275 -0
- aiologging-0.1.0/aiologging.egg-info/PKG-INFO +600 -0
- aiologging-0.1.0/aiologging.egg-info/SOURCES.txt +31 -0
- aiologging-0.1.0/aiologging.egg-info/dependency_links.txt +1 -0
- aiologging-0.1.0/aiologging.egg-info/requires.txt +29 -0
- aiologging-0.1.0/aiologging.egg-info/top_level.txt +1 -0
- aiologging-0.1.0/pyproject.toml +112 -0
- aiologging-0.1.0/setup.cfg +4 -0
- aiologging-0.1.0/tests/test_config.py +697 -0
- aiologging-0.1.0/tests/test_exceptions.py +506 -0
- aiologging-0.1.0/tests/test_file_handlers.py +376 -0
- aiologging-0.1.0/tests/test_handlers.py +522 -0
- aiologging-0.1.0/tests/test_http_handlers.py +618 -0
- aiologging-0.1.0/tests/test_logger.py +408 -0
- aiologging-0.1.0/tests/test_regressions.py +163 -0
- aiologging-0.1.0/tests/test_rotating_handlers.py +947 -0
- aiologging-0.1.0/tests/test_types.py +480 -0
- aiologging-0.1.0/tests/test_utils.py +308 -0
aiologging-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Евгений Дементьев
|
|
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 all
|
|
13
|
+
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 THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aiologging
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Asynchronous logging library with full compatibility to standard logging module
|
|
5
|
+
Author: Evgenii Dementev (m6mok)
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Евгений Дементьев
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/m6mok/aiologging
|
|
29
|
+
Project-URL: Repository, https://github.com/m6mok/aiologging
|
|
30
|
+
Project-URL: Bug Tracker, https://github.com/m6mok/aiologging/issues
|
|
31
|
+
Keywords: logging,async,asyncio,aiologging
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Intended Audience :: Developers
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: OS Independent
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
42
|
+
Classifier: Topic :: System :: Logging
|
|
43
|
+
Classifier: Typing :: Typed
|
|
44
|
+
Requires-Python: >=3.9
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
License-File: LICENSE
|
|
47
|
+
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
|
|
48
|
+
Provides-Extra: aiofiles
|
|
49
|
+
Requires-Dist: aiofiles>=23.0.0; extra == "aiofiles"
|
|
50
|
+
Provides-Extra: aiohttp
|
|
51
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "aiohttp"
|
|
52
|
+
Provides-Extra: protobuf
|
|
53
|
+
Requires-Dist: protobuf>=4.0.0; extra == "protobuf"
|
|
54
|
+
Provides-Extra: all
|
|
55
|
+
Requires-Dist: aiofiles>=23.0.0; extra == "all"
|
|
56
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "all"
|
|
57
|
+
Requires-Dist: protobuf>=4.0.0; extra == "all"
|
|
58
|
+
Provides-Extra: dev
|
|
59
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
60
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
61
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
62
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
63
|
+
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
|
64
|
+
Requires-Dist: types-aiofiles; extra == "dev"
|
|
65
|
+
Requires-Dist: types-protobuf; extra == "dev"
|
|
66
|
+
Requires-Dist: aiofiles>=23.0.0; extra == "dev"
|
|
67
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "dev"
|
|
68
|
+
Requires-Dist: protobuf>=4.0.0; extra == "dev"
|
|
69
|
+
Dynamic: license-file
|
|
70
|
+
|
|
71
|
+
# aiologging
|
|
72
|
+
|
|
73
|
+
[](https://github.com/m6mok/aiologging/actions/workflows/ci.yml)
|
|
74
|
+
|
|
75
|
+
Asynchronous logging library for Python (3.9+) with full compatibility to the standard logging module but with async methods requiring await.
|
|
76
|
+
|
|
77
|
+
## Features
|
|
78
|
+
|
|
79
|
+
- **Full API Compatibility**: Drop-in replacement for standard logging with async methods
|
|
80
|
+
- **Async Handlers**: Non-blocking I/O for streams, files, and HTTP endpoints
|
|
81
|
+
- **File Rotation**: Size and time-based log rotation with async support
|
|
82
|
+
- **HTTP Handlers**: Send logs to HTTP endpoints with extensible authentication
|
|
83
|
+
- **Buffered Handlers**: High-performance batch processing for high-volume logging
|
|
84
|
+
- **Performance Metrics**: Built-in metrics collection for monitoring logging performance
|
|
85
|
+
- **Error Handling**: Comprehensive error handling with custom exception types
|
|
86
|
+
- **Configuration Management**: Flexible configuration from files, dictionaries, or environment variables
|
|
87
|
+
- **Optional Dependencies**: Install only what you need
|
|
88
|
+
- **Strict Type Checking**: Full mypy support with type hints
|
|
89
|
+
- **Context Manager Support**: Safe resource management with `async with`
|
|
90
|
+
|
|
91
|
+
## Installation
|
|
92
|
+
|
|
93
|
+
### Basic Installation
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pip install aiologging
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### With Optional Dependencies
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# For file handlers
|
|
103
|
+
pip install aiologging[aiofiles]
|
|
104
|
+
|
|
105
|
+
# For HTTP handlers
|
|
106
|
+
pip install aiologging[aiohttp]
|
|
107
|
+
|
|
108
|
+
# For Protobuf support
|
|
109
|
+
pip install aiologging[protobuf]
|
|
110
|
+
|
|
111
|
+
# All dependencies
|
|
112
|
+
pip install aiologging[all]
|
|
113
|
+
|
|
114
|
+
# Development dependencies
|
|
115
|
+
pip install aiologging[dev]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Quick Start
|
|
119
|
+
|
|
120
|
+
### Basic Usage
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
import asyncio
|
|
124
|
+
import aiologging
|
|
125
|
+
|
|
126
|
+
async def main():
|
|
127
|
+
async with aiologging.getLogger("app") as logger:
|
|
128
|
+
await logger.info("Application started")
|
|
129
|
+
await logger.warning("Something might be wrong")
|
|
130
|
+
await logger.error("An error occurred")
|
|
131
|
+
|
|
132
|
+
asyncio.run(main())
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Basic Configuration
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
import aiologging
|
|
139
|
+
|
|
140
|
+
# Configure basic logging (similar to logging.basicConfig)
|
|
141
|
+
aiologging.basicConfig(
|
|
142
|
+
level=aiologging.INFO,
|
|
143
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
async def main():
|
|
147
|
+
async with aiologging.getLogger("app") as logger:
|
|
148
|
+
await logger.info("This will be logged to stderr")
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Using Convenience Functions
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
import asyncio
|
|
155
|
+
import aiologging
|
|
156
|
+
|
|
157
|
+
async def main():
|
|
158
|
+
# Create handlers using convenience functions
|
|
159
|
+
stream_handler = aiologging.create_stream_handler(level=aiologging.INFO)
|
|
160
|
+
file_handler = aiologging.create_file_handler("app.log", level=aiologging.DEBUG)
|
|
161
|
+
|
|
162
|
+
# Get logger and add handlers
|
|
163
|
+
async with aiologging.getLogger("app") as logger:
|
|
164
|
+
logger.addHandler(stream_handler)
|
|
165
|
+
logger.addHandler(file_handler)
|
|
166
|
+
|
|
167
|
+
await logger.info("This goes to both stderr and app.log")
|
|
168
|
+
|
|
169
|
+
asyncio.run(main())
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Examples
|
|
173
|
+
|
|
174
|
+
Complete runnable examples live in the [examples/](examples/) directory:
|
|
175
|
+
|
|
176
|
+
- [examples/basic_usage.py](examples/basic_usage.py) — levels, `basicConfig`, `exc_info`, one-off logging
|
|
177
|
+
- [examples/file_logging.py](examples/file_logging.py) — file handler, size- and time-based rotation
|
|
178
|
+
- [examples/http_logging.py](examples/http_logging.py) — JSON batches over HTTP with a custom authenticator (includes a local test collector)
|
|
179
|
+
- [examples/config_usage.py](examples/config_usage.py) — configuring loggers from a dictionary
|
|
180
|
+
|
|
181
|
+
## Handlers
|
|
182
|
+
|
|
183
|
+
### Stream Handler
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
import aiologging
|
|
187
|
+
import sys
|
|
188
|
+
|
|
189
|
+
async def main():
|
|
190
|
+
async with aiologging.getLogger("app") as logger:
|
|
191
|
+
# Add stdout handler
|
|
192
|
+
stdout_handler = aiologging.AsyncStreamHandler(sys.stdout)
|
|
193
|
+
logger.addHandler(stdout_handler)
|
|
194
|
+
|
|
195
|
+
await logger.info("This goes to stdout")
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### File Handler (requires aiofiles)
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
import aiologging
|
|
202
|
+
|
|
203
|
+
async def main():
|
|
204
|
+
async with aiologging.getLogger("app") as logger:
|
|
205
|
+
# Add file handler
|
|
206
|
+
file_handler = aiologging.AsyncFileHandler("app.log")
|
|
207
|
+
logger.addHandler(file_handler)
|
|
208
|
+
|
|
209
|
+
await logger.info("This goes to app.log")
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Rotating File Handler (requires aiofiles)
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
import aiologging
|
|
216
|
+
|
|
217
|
+
async def main():
|
|
218
|
+
async with aiologging.getLogger("app") as logger:
|
|
219
|
+
# Size-based rotation
|
|
220
|
+
rotating_handler = aiologging.AsyncRotatingFileHandler(
|
|
221
|
+
"app.log",
|
|
222
|
+
max_bytes=1024*1024, # 1MB
|
|
223
|
+
backup_count=5
|
|
224
|
+
)
|
|
225
|
+
logger.addHandler(rotating_handler)
|
|
226
|
+
|
|
227
|
+
# Time-based rotation
|
|
228
|
+
timed_handler = aiologging.AsyncTimedRotatingFileHandler(
|
|
229
|
+
"app.log",
|
|
230
|
+
when="midnight",
|
|
231
|
+
backup_count=7
|
|
232
|
+
)
|
|
233
|
+
logger.addHandler(timed_handler)
|
|
234
|
+
|
|
235
|
+
await logger.info("This will be rotated")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### HTTP Handler (requires aiohttp)
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
import aiologging
|
|
242
|
+
|
|
243
|
+
async def main():
|
|
244
|
+
async with aiologging.getLogger("app") as logger:
|
|
245
|
+
# Basic HTTP handler
|
|
246
|
+
http_handler = aiologging.AsyncHttpHandler(
|
|
247
|
+
"https://api.example.com/logs",
|
|
248
|
+
headers={"Authorization": "Bearer token"}
|
|
249
|
+
)
|
|
250
|
+
logger.addHandler(http_handler)
|
|
251
|
+
|
|
252
|
+
await logger.info("This will be sent via HTTP")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Custom Authentication
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
import aiologging
|
|
259
|
+
|
|
260
|
+
async def oauth_authenticator(session, request_data):
|
|
261
|
+
"""Custom OAuth authentication."""
|
|
262
|
+
# Refresh token logic here
|
|
263
|
+
token = await refresh_oauth_token()
|
|
264
|
+
return {"Authorization": f"Bearer {token}"}
|
|
265
|
+
|
|
266
|
+
async def main():
|
|
267
|
+
async with aiologging.getLogger("app") as logger:
|
|
268
|
+
http_handler = aiologging.AsyncHttpHandler(
|
|
269
|
+
"https://api.example.com/logs",
|
|
270
|
+
authenticator=oauth_authenticator
|
|
271
|
+
)
|
|
272
|
+
logger.addHandler(http_handler)
|
|
273
|
+
|
|
274
|
+
await logger.info("This uses custom authentication")
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## HTTP Handler Formats
|
|
278
|
+
|
|
279
|
+
### JSON Handler
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
json_handler = aiologging.AsyncHttpJsonHandler(
|
|
283
|
+
"https://api.example.com/logs"
|
|
284
|
+
)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Text Handler
|
|
288
|
+
|
|
289
|
+
```python
|
|
290
|
+
text_handler = aiologging.AsyncHttpTextHandler(
|
|
291
|
+
"https://api.example.com/logs"
|
|
292
|
+
)
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Protobuf Handler (requires protobuf)
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
proto_handler = aiologging.AsyncHttpProtoHandler(
|
|
299
|
+
"https://api.example.com/logs"
|
|
300
|
+
)
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Universal Handler (auto-detect format)
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
universal_handler = aiologging.AsyncHttpHandler(
|
|
307
|
+
"https://api.example.com/logs",
|
|
308
|
+
format_type="application/json" # Optional: auto-detected if not specified
|
|
309
|
+
)
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Advanced Usage
|
|
313
|
+
|
|
314
|
+
### Custom Filters
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
import aiologging
|
|
318
|
+
|
|
319
|
+
class CustomFilter:
|
|
320
|
+
def filter(self, record):
|
|
321
|
+
return "important" in record.getMessage()
|
|
322
|
+
|
|
323
|
+
async def main():
|
|
324
|
+
async with aiologging.getLogger("app") as logger:
|
|
325
|
+
logger.addFilter(CustomFilter())
|
|
326
|
+
|
|
327
|
+
await logger.info("This is important") # Will be logged
|
|
328
|
+
await logger.info("This is not") # Will be filtered
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Custom Formatters
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
import logging
|
|
335
|
+
import aiologging
|
|
336
|
+
|
|
337
|
+
async def main():
|
|
338
|
+
async with aiologging.getLogger("app") as logger:
|
|
339
|
+
formatter = logging.Formatter(
|
|
340
|
+
"%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
handler = aiologging.AsyncStreamHandler()
|
|
344
|
+
handler.setFormatter(formatter)
|
|
345
|
+
logger.addHandler(handler)
|
|
346
|
+
|
|
347
|
+
await logger.info("Formatted message")
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Error Handling
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
import aiologging
|
|
354
|
+
|
|
355
|
+
async def error_handler(record, exception):
|
|
356
|
+
"""Custom error handler for failed log operations."""
|
|
357
|
+
print(f"Failed to log {record.getMessage()}: {exception}")
|
|
358
|
+
|
|
359
|
+
async def main():
|
|
360
|
+
async with aiologging.getLogger("app") as logger:
|
|
361
|
+
handler = aiologging.AsyncStreamHandler()
|
|
362
|
+
handler.error_handler = error_handler
|
|
363
|
+
logger.addHandler(handler)
|
|
364
|
+
|
|
365
|
+
await logger.info("This has custom error handling")
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Performance Metrics
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
import asyncio
|
|
372
|
+
import aiologging
|
|
373
|
+
|
|
374
|
+
async def main():
|
|
375
|
+
# Create logger with metrics enabled
|
|
376
|
+
async with aiologging.getLogger("app") as logger:
|
|
377
|
+
# Get metrics for the logger
|
|
378
|
+
metrics = logger.get_metrics()
|
|
379
|
+
print(f"Logger metrics: {metrics}")
|
|
380
|
+
|
|
381
|
+
# Get metrics for handlers
|
|
382
|
+
for handler in logger.handlers:
|
|
383
|
+
if hasattr(handler, 'get_metrics'):
|
|
384
|
+
handler_metrics = handler.get_metrics()
|
|
385
|
+
print(f"Handler metrics: {handler_metrics}")
|
|
386
|
+
|
|
387
|
+
asyncio.run(main())
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Batch Processing
|
|
391
|
+
|
|
392
|
+
```python
|
|
393
|
+
import aiologging
|
|
394
|
+
from aiologging.types import BatchConfig
|
|
395
|
+
|
|
396
|
+
async def main():
|
|
397
|
+
async with aiologging.getLogger("app") as logger:
|
|
398
|
+
# Configure batch processing for HTTP handler
|
|
399
|
+
batch_config = BatchConfig(
|
|
400
|
+
batch_size=100,
|
|
401
|
+
flush_interval=5.0,
|
|
402
|
+
max_retries=3
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
http_handler = aiologging.AsyncHttpHandler(
|
|
406
|
+
"https://api.example.com/logs",
|
|
407
|
+
batch_config=batch_config
|
|
408
|
+
)
|
|
409
|
+
logger.addHandler(http_handler)
|
|
410
|
+
|
|
411
|
+
# Log many messages - they'll be sent in batches
|
|
412
|
+
for i in range(150):
|
|
413
|
+
await logger.info(f"Message {i}")
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Configuration Management
|
|
417
|
+
|
|
418
|
+
### Configuration from Dictionary
|
|
419
|
+
|
|
420
|
+
```python
|
|
421
|
+
import asyncio
|
|
422
|
+
import aiologging
|
|
423
|
+
|
|
424
|
+
config = {
|
|
425
|
+
"version": 1,
|
|
426
|
+
"loggers": {
|
|
427
|
+
"myapp": {
|
|
428
|
+
"level": "INFO",
|
|
429
|
+
"handlers": ["console", "file"]
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
"handlers": {
|
|
433
|
+
"console": {
|
|
434
|
+
"class": "stream",
|
|
435
|
+
"level": "INFO",
|
|
436
|
+
"stream": "stdout"
|
|
437
|
+
},
|
|
438
|
+
"file": {
|
|
439
|
+
"class": "file",
|
|
440
|
+
"level": "DEBUG",
|
|
441
|
+
"filename": "app.log",
|
|
442
|
+
"mode": "a"
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
# Configure from dictionary
|
|
448
|
+
aiologging.configure_from_dict(config)
|
|
449
|
+
|
|
450
|
+
async def main():
|
|
451
|
+
logger = aiologging.get_configured_logger("myapp")
|
|
452
|
+
await logger.info("This uses configured logger")
|
|
453
|
+
|
|
454
|
+
asyncio.run(main())
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Configuration from File
|
|
458
|
+
|
|
459
|
+
```python
|
|
460
|
+
import asyncio
|
|
461
|
+
import aiologging
|
|
462
|
+
|
|
463
|
+
# Configure from JSON file
|
|
464
|
+
aiologging.configure_from_file("logging_config.json")
|
|
465
|
+
|
|
466
|
+
async def main():
|
|
467
|
+
logger = aiologging.get_configured_logger("myapp")
|
|
468
|
+
await logger.info("This uses logger configured from file")
|
|
469
|
+
|
|
470
|
+
asyncio.run(main())
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Migration from Standard Logging
|
|
474
|
+
|
|
475
|
+
### Standard Logging
|
|
476
|
+
|
|
477
|
+
```python
|
|
478
|
+
import logging
|
|
479
|
+
|
|
480
|
+
logger = logging.getLogger("app")
|
|
481
|
+
logger.info("Message")
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### With aiologging
|
|
485
|
+
|
|
486
|
+
```python
|
|
487
|
+
import aiologging
|
|
488
|
+
|
|
489
|
+
async def main():
|
|
490
|
+
async with aiologging.getLogger("app") as logger:
|
|
491
|
+
await logger.info("Message")
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Key Differences
|
|
495
|
+
|
|
496
|
+
1. **Async Context**: Use `async with` for proper resource management
|
|
497
|
+
2. **Await Methods**: All logging methods require `await`
|
|
498
|
+
3. **Async Handlers**: All handlers are non-blocking
|
|
499
|
+
4. **Type Safety**: Full type hints and mypy compliance
|
|
500
|
+
5. **Error Handling**: Enhanced error handling with custom exception types
|
|
501
|
+
6. **Performance Metrics**: Built-in metrics collection for monitoring
|
|
502
|
+
|
|
503
|
+
## API Reference
|
|
504
|
+
|
|
505
|
+
### Logger Methods
|
|
506
|
+
|
|
507
|
+
All standard logging methods are available as async:
|
|
508
|
+
|
|
509
|
+
- `await logger.log(level, msg, *args, **kwargs)`
|
|
510
|
+
- `await logger.debug(msg, *args, **kwargs)`
|
|
511
|
+
- `await logger.info(msg, *args, **kwargs)`
|
|
512
|
+
- `await logger.warning(msg, *args, **kwargs)`
|
|
513
|
+
- `await logger.error(msg, *args, **kwargs)`
|
|
514
|
+
- `await logger.critical(msg, *args, **kwargs)`
|
|
515
|
+
- `await logger.exception(msg, *args, **kwargs)`
|
|
516
|
+
|
|
517
|
+
### Handler Classes
|
|
518
|
+
|
|
519
|
+
- `AsyncHandler` - Base async handler
|
|
520
|
+
- `AsyncStreamHandler` - Stream output handler
|
|
521
|
+
- `AsyncFileHandler` - File output handler (requires aiofiles)
|
|
522
|
+
- `AsyncRotatingFileHandler` - Size-based rotation (requires aiofiles)
|
|
523
|
+
- `AsyncTimedRotatingFileHandler` - Time-based rotation (requires aiofiles)
|
|
524
|
+
- `AsyncHttpHandler` - Universal HTTP handler (requires aiohttp)
|
|
525
|
+
- `AsyncHttpTextHandler` - Plain text HTTP handler (requires aiohttp)
|
|
526
|
+
- `AsyncHttpJsonHandler` - JSON HTTP handler (requires aiohttp)
|
|
527
|
+
- `AsyncHttpProtoHandler` - Protobuf HTTP handler (requires aiohttp, protobuf)
|
|
528
|
+
|
|
529
|
+
### Configuration Classes
|
|
530
|
+
|
|
531
|
+
- `BatchConfig` - Batch processing configuration
|
|
532
|
+
- `FileConfig` - File handler configuration
|
|
533
|
+
- `HttpConfig` - HTTP handler configuration
|
|
534
|
+
- `LoggerConfig` - Logger configuration
|
|
535
|
+
- `RotationConfig` - Rotation configuration for file handlers
|
|
536
|
+
|
|
537
|
+
### Exception Classes
|
|
538
|
+
|
|
539
|
+
- `AiologgingError` - Base exception for all aiologging errors
|
|
540
|
+
- `HandlerError` - Base exception for handler errors
|
|
541
|
+
- `ConfigurationError` - Configuration-related errors
|
|
542
|
+
- `DependencyError` - Missing optional dependencies
|
|
543
|
+
- `AuthenticationError` - Authentication failures
|
|
544
|
+
- `NetworkError` - Network-related errors
|
|
545
|
+
- `FileError` - File operation errors
|
|
546
|
+
- `RotationError` - File rotation errors
|
|
547
|
+
- `BatchError` - Batch processing errors
|
|
548
|
+
- `FormatterError` - Formatting errors
|
|
549
|
+
- `LoggerError` - Logger operation errors
|
|
550
|
+
- `ContextError` - Context manager errors
|
|
551
|
+
|
|
552
|
+
## Performance Considerations
|
|
553
|
+
|
|
554
|
+
1. **Buffering**: Use buffered handlers for high-volume logging
|
|
555
|
+
2. **Batch Processing**: Configure appropriate batch sizes for HTTP handlers
|
|
556
|
+
3. **Async I/O**: All I/O operations are non-blocking
|
|
557
|
+
4. **Resource Management**: Always use context managers for proper cleanup
|
|
558
|
+
5. **Metrics Collection**: Enable metrics to monitor performance
|
|
559
|
+
6. **Rate Limiting**: Use rate limiters to prevent log flooding
|
|
560
|
+
7. **Adaptive Buffering**: Enable adaptive buffering for optimal performance
|
|
561
|
+
|
|
562
|
+
## Testing
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
# Install development dependencies
|
|
566
|
+
pip install aiologging[dev]
|
|
567
|
+
|
|
568
|
+
# Run tests
|
|
569
|
+
pytest
|
|
570
|
+
|
|
571
|
+
# Run tests with coverage
|
|
572
|
+
pytest --cov=aiologging
|
|
573
|
+
|
|
574
|
+
# Run type checking
|
|
575
|
+
mypy aiologging
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
## Contributing
|
|
579
|
+
|
|
580
|
+
1. Fork the repository
|
|
581
|
+
2. Create a feature branch
|
|
582
|
+
3. Add tests for new functionality
|
|
583
|
+
4. Ensure all tests pass and type checking succeeds
|
|
584
|
+
5. Submit a pull request
|
|
585
|
+
|
|
586
|
+
## License
|
|
587
|
+
|
|
588
|
+
MIT License - see LICENSE file for details.
|
|
589
|
+
|
|
590
|
+
## Changelog
|
|
591
|
+
|
|
592
|
+
### 0.1.0
|
|
593
|
+
|
|
594
|
+
- Initial release
|
|
595
|
+
- Full async logging API
|
|
596
|
+
- Stream, file, and HTTP handlers
|
|
597
|
+
- File rotation support
|
|
598
|
+
- Extensible authentication
|
|
599
|
+
- Optional dependencies
|
|
600
|
+
- Strict type checking
|