json-logify 0.1.0__tar.gz → 0.1.3__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.
- {json_logify-0.1.0 → json_logify-0.1.3}/PKG-INFO +154 -43
- json_logify-0.1.3/README.md +304 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/json_logify.egg-info/PKG-INFO +154 -43
- {json_logify-0.1.0 → json_logify-0.1.3}/json_logify.egg-info/SOURCES.txt +3 -1
- {json_logify-0.1.0 → json_logify-0.1.3}/json_logify.egg-info/requires.txt +0 -7
- json_logify-0.1.3/logify/core.py +400 -0
- json_logify-0.1.3/logify/django.py +381 -0
- json_logify-0.1.3/logify/fastapi.py +82 -0
- json_logify-0.1.3/logify/flask.py +88 -0
- json_logify-0.1.3/logify/version.py +1 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/pyproject.toml +8 -8
- json_logify-0.1.3/tests/test_config_logic.py +54 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/tests/test_core.py +13 -9
- {json_logify-0.1.0 → json_logify-0.1.3}/tests/test_django.py +86 -12
- json_logify-0.1.3/tests/test_fastapi.py +335 -0
- json_logify-0.1.3/tests/test_flask.py +350 -0
- json_logify-0.1.3/tests/test_security_masking.py +86 -0
- json_logify-0.1.0/README.md +0 -187
- json_logify-0.1.0/logify/core.py +0 -198
- json_logify-0.1.0/logify/django.py +0 -88
- json_logify-0.1.0/logify/fastapi.py +0 -82
- json_logify-0.1.0/logify/flask.py +0 -88
- json_logify-0.1.0/logify/version.py +0 -1
- json_logify-0.1.0/tests/test_fastapi.py +0 -335
- json_logify-0.1.0/tests/test_flask.py +0 -350
- {json_logify-0.1.0 → json_logify-0.1.3}/LICENSE +0 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/json_logify.egg-info/dependency_links.txt +0 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/json_logify.egg-info/top_level.txt +0 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/logify/__init__.py +0 -0
- {json_logify-0.1.0 → json_logify-0.1.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: json-logify
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Universal structured logging with exact JSON schema for Python frameworks
|
|
5
5
|
Author-email: Bakdoolot Kulbarakov <kulbarakovbh@gmail.com>
|
|
6
6
|
Maintainer-email: Bakdoolot Kulbarakov <kulbarakovbh@gmail.com>
|
|
@@ -54,11 +54,6 @@ Requires-Dist: structlog>=23.0.0
|
|
|
54
54
|
Requires-Dist: orjson>=3.8.0
|
|
55
55
|
Provides-Extra: django
|
|
56
56
|
Requires-Dist: django>=5.2.6; extra == "django"
|
|
57
|
-
Provides-Extra: fastapi
|
|
58
|
-
Requires-Dist: fastapi>=0.116.1; extra == "fastapi"
|
|
59
|
-
Requires-Dist: uvicorn>=0.35.0; extra == "fastapi"
|
|
60
|
-
Provides-Extra: flask
|
|
61
|
-
Requires-Dist: flask>=3.1.2; extra == "flask"
|
|
62
57
|
Provides-Extra: dev
|
|
63
58
|
Requires-Dist: pytest>=8.4.2; extra == "dev"
|
|
64
59
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
@@ -83,13 +78,14 @@ Universal structured logging with exact JSON schema for Python frameworks.
|
|
|
83
78
|
|
|
84
79
|
## Features
|
|
85
80
|
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
**
|
|
81
|
+
- **Exact JSON Schema**: Consistent log format across all frameworks
|
|
82
|
+
- **High Performance**: Built with structlog and orjson for maximum speed
|
|
83
|
+
- **Universal**: Works with Django, FastAPI, Flask and standalone Python
|
|
84
|
+
- **Security First**: Automatic masking of sensitive data (passwords, tokens, etc.)
|
|
85
|
+
- **Easy Setup**: One-line configuration for most use cases
|
|
86
|
+
- **Rich Context**: Request IDs, user tracking, and custom payload support
|
|
87
|
+
- **Smart Filtering**: Configurable path ignoring and request/response body logging
|
|
88
|
+
- **Modern Python**: Full type hints and async support
|
|
93
89
|
|
|
94
90
|
## Quick Start
|
|
95
91
|
|
|
@@ -101,8 +97,8 @@ pip install json-logify
|
|
|
101
97
|
|
|
102
98
|
# For specific frameworks
|
|
103
99
|
pip install json-logify[django]
|
|
104
|
-
pip install json-logify[fastapi]
|
|
105
|
-
pip install json-logify[flask]
|
|
100
|
+
# pip install json-logify[fastapi] # Coming soon
|
|
101
|
+
# pip install json-logify[flask] # Coming soon
|
|
106
102
|
|
|
107
103
|
# Everything
|
|
108
104
|
pip install json-logify[all]
|
|
@@ -111,50 +107,164 @@ pip install json-logify[all]
|
|
|
111
107
|
### Basic Usage
|
|
112
108
|
|
|
113
109
|
```python
|
|
114
|
-
from logify import info, error
|
|
110
|
+
from logify import info, error, debug, warning
|
|
115
111
|
|
|
116
|
-
#
|
|
117
|
-
info("User logged in"
|
|
112
|
+
# Basic logging with message
|
|
113
|
+
info("User logged in")
|
|
118
114
|
|
|
119
|
-
#
|
|
115
|
+
# With structured context
|
|
116
|
+
info("Payment processed", amount=100.0, currency="USD", user_id="user123")
|
|
117
|
+
|
|
118
|
+
# Different log levels
|
|
119
|
+
debug("Debug information", query_time=0.023)
|
|
120
|
+
warning("Slow database query detected", query_time=1.52, query_id="a1b2c3")
|
|
121
|
+
error("Payment failed", error_code="CARD_DECLINED", user_id="user123")
|
|
122
|
+
|
|
123
|
+
# Exception handling
|
|
120
124
|
try:
|
|
121
|
-
|
|
125
|
+
# Some code that might fail
|
|
126
|
+
result = some_function()
|
|
122
127
|
except Exception as e:
|
|
123
|
-
error("Operation failed",
|
|
128
|
+
error("Operation failed", exception=str(e), operation="some_function")
|
|
124
129
|
```
|
|
125
130
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"payload": {
|
|
133
|
-
"user_id": "12345",
|
|
134
|
-
"action": "login"
|
|
135
|
-
}
|
|
136
|
-
}
|
|
131
|
+
### Django Integration
|
|
132
|
+
|
|
133
|
+
#### 1. Install with Django extras:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install json-logify[django]
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
#### 2. Configure in settings.py:
|
|
140
140
|
|
|
141
141
|
```python
|
|
142
|
-
# settings.py
|
|
143
142
|
from logify.django import get_logging_config
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
service_name="myapp",
|
|
147
|
-
json_logs=True
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
# Add middleware (optional for request tracking)
|
|
144
|
+
# Add middleware to MIDDLEWARE list
|
|
151
145
|
MIDDLEWARE = [
|
|
152
|
-
'logify.django.LogifyMiddleware',
|
|
153
146
|
# ... other middleware
|
|
147
|
+
'logify.django.LogifyMiddleware', # ← Add this
|
|
154
148
|
]
|
|
149
|
+
|
|
150
|
+
# Configure logging with json-logify
|
|
151
|
+
LOGGING = get_logging_config(
|
|
152
|
+
service_name="my-django-app",
|
|
153
|
+
level="INFO",
|
|
154
|
+
max_string_length=200, # String truncation limit
|
|
155
|
+
sensitive_fields=[ # Fields to mask with "***"
|
|
156
|
+
"password", "passwd", "secret", "token", "api_key",
|
|
157
|
+
"access_token", "refresh_token", "session_key",
|
|
158
|
+
"credit_card", "cvv", "ssn", "authorization",
|
|
159
|
+
"cookie", "x-api-key", "custom_sensitive_field"
|
|
160
|
+
],
|
|
161
|
+
ignore_paths=[ # Paths to skip logging
|
|
162
|
+
"/health/", "/static/", "/favicon.ico",
|
|
163
|
+
"/admin/jsi18n/", "/metrics/"
|
|
164
|
+
]
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Optional: Reduce Django built-in logger noise
|
|
168
|
+
LOGGING['loggers'].update({
|
|
169
|
+
'django.utils.autoreload': {'level': 'WARNING'},
|
|
170
|
+
'django.db.backends': {'level': 'WARNING'},
|
|
171
|
+
'django.server': {'level': 'WARNING'},
|
|
172
|
+
'django.request': {'level': 'WARNING'},
|
|
173
|
+
})
|
|
155
174
|
```
|
|
156
175
|
|
|
157
|
-
|
|
176
|
+
#### 3. Use in your views:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from logify import info, error, debug, warning
|
|
180
|
+
from django.http import JsonResponse
|
|
181
|
+
|
|
182
|
+
def process_payment(request):
|
|
183
|
+
# Log with automatic request context
|
|
184
|
+
info("Payment processing started",
|
|
185
|
+
user_id=request.user.id,
|
|
186
|
+
amount=request.POST.get('amount'))
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
# Sensitive data gets automatically masked
|
|
190
|
+
info("User data received",
|
|
191
|
+
username=request.user.username, # ← Visible
|
|
192
|
+
password=request.POST.get('password'), # ← Masked: "***"
|
|
193
|
+
credit_card=request.POST.get('card'), # ← Masked: "***"
|
|
194
|
+
email=request.user.email) # ← Visible
|
|
195
|
+
|
|
196
|
+
# Your business logic
|
|
197
|
+
payment = process_payment_logic(request.POST)
|
|
198
|
+
|
|
199
|
+
# Log success
|
|
200
|
+
info("Payment completed",
|
|
201
|
+
payment_id=payment.id,
|
|
202
|
+
status="success",
|
|
203
|
+
amount=payment.amount)
|
|
204
|
+
|
|
205
|
+
return JsonResponse({"status": "success", "payment_id": payment.id})
|
|
206
|
+
|
|
207
|
+
except ValidationError as e:
|
|
208
|
+
error("Payment validation failed", error=e, user_id=request.user.id)
|
|
209
|
+
return JsonResponse({"status": "error", "message": str(e)}, status=400)
|
|
210
|
+
except Exception as e:
|
|
211
|
+
error("Payment processing failed", error=e)
|
|
212
|
+
return JsonResponse({"status": "error"}, status=500)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### 4. What you get automatically:
|
|
216
|
+
|
|
217
|
+
**Request logging:**
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"timestamp": "2025-09-09T08:09:35.933Z",
|
|
221
|
+
"message": "Request started",
|
|
222
|
+
"level": "INFO",
|
|
223
|
+
"payload": {
|
|
224
|
+
"request_id": "b62e59b6-bae7-4a96-821d",
|
|
225
|
+
"service": "my-django-app",
|
|
226
|
+
"method": "POST",
|
|
227
|
+
"path": "/api/payment/",
|
|
228
|
+
"user_info": "User ID: 123: john_doe",
|
|
229
|
+
"headers": {
|
|
230
|
+
"Content-Type": "application/json",
|
|
231
|
+
"Authorization": "***", // ← Automatically masked
|
|
232
|
+
"User-Agent": "curl/8.7.1"
|
|
233
|
+
},
|
|
234
|
+
"request_body": {
|
|
235
|
+
"username": "john_doe",
|
|
236
|
+
"password": "***", // ← Automatically masked
|
|
237
|
+
"credit_card": "***" // ← Automatically masked
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Your application logs:**
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"timestamp": "2025-09-09T08:09:35.934Z",
|
|
247
|
+
"message": "Payment completed",
|
|
248
|
+
"level": "INFO",
|
|
249
|
+
"payload": {
|
|
250
|
+
"request_id": "b62e59b6-bae7-4a96-821d", // ← Auto-linked to request
|
|
251
|
+
"payment_id": "pay_123456",
|
|
252
|
+
"status": "success",
|
|
253
|
+
"amount": 99.99
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**🔒 Security Features:**
|
|
259
|
+
- **Automatic masking**: Passwords, tokens, API keys, credit cards → `"***"`
|
|
260
|
+
- **Header filtering**: Authorization, Cookie, X-API-Key → `"***"`
|
|
261
|
+
- **Recursive masking**: Works in nested objects and arrays
|
|
262
|
+
- **Request/Response body**: Limited size + content-type filtering
|
|
263
|
+
- **Path ignoring**: Skip health checks, static files, etc.
|
|
264
|
+
- Request and response bodies (with sensitive fields masked)
|
|
265
|
+
|
|
266
|
+
<!--
|
|
267
|
+
### FastAPI Integration (Coming Soon)
|
|
158
268
|
|
|
159
269
|
```python
|
|
160
270
|
from fastapi import FastAPI
|
|
@@ -170,7 +280,7 @@ async def root():
|
|
|
170
280
|
return {"message": "Hello World"}
|
|
171
281
|
```
|
|
172
282
|
|
|
173
|
-
### Flask Integration
|
|
283
|
+
### Flask Integration (Coming Soon)
|
|
174
284
|
|
|
175
285
|
```python
|
|
176
286
|
from flask import Flask
|
|
@@ -185,6 +295,7 @@ def hello():
|
|
|
185
295
|
info("Flask endpoint called", endpoint="/")
|
|
186
296
|
return "Hello, World!"
|
|
187
297
|
```
|
|
298
|
+
-->
|
|
188
299
|
|
|
189
300
|
## Advanced Usage
|
|
190
301
|
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# json-logify
|
|
2
|
+
|
|
3
|
+
Universal structured logging with exact JSON schema for Python frameworks.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/py/json-logify)
|
|
6
|
+
[](https://pypi.org/project/json-logify/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Exact JSON Schema**: Consistent log format across all frameworks
|
|
12
|
+
- **High Performance**: Built with structlog and orjson for maximum speed
|
|
13
|
+
- **Universal**: Works with Django, FastAPI, Flask and standalone Python
|
|
14
|
+
- **Security First**: Automatic masking of sensitive data (passwords, tokens, etc.)
|
|
15
|
+
- **Easy Setup**: One-line configuration for most use cases
|
|
16
|
+
- **Rich Context**: Request IDs, user tracking, and custom payload support
|
|
17
|
+
- **Smart Filtering**: Configurable path ignoring and request/response body logging
|
|
18
|
+
- **Modern Python**: Full type hints and async support
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Basic installation
|
|
26
|
+
pip install json-logify
|
|
27
|
+
|
|
28
|
+
# For specific frameworks
|
|
29
|
+
pip install json-logify[django]
|
|
30
|
+
# pip install json-logify[fastapi] # Coming soon
|
|
31
|
+
# pip install json-logify[flask] # Coming soon
|
|
32
|
+
|
|
33
|
+
# Everything
|
|
34
|
+
pip install json-logify[all]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Basic Usage
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from logify import info, error, debug, warning
|
|
41
|
+
|
|
42
|
+
# Basic logging with message
|
|
43
|
+
info("User logged in")
|
|
44
|
+
|
|
45
|
+
# With structured context
|
|
46
|
+
info("Payment processed", amount=100.0, currency="USD", user_id="user123")
|
|
47
|
+
|
|
48
|
+
# Different log levels
|
|
49
|
+
debug("Debug information", query_time=0.023)
|
|
50
|
+
warning("Slow database query detected", query_time=1.52, query_id="a1b2c3")
|
|
51
|
+
error("Payment failed", error_code="CARD_DECLINED", user_id="user123")
|
|
52
|
+
|
|
53
|
+
# Exception handling
|
|
54
|
+
try:
|
|
55
|
+
# Some code that might fail
|
|
56
|
+
result = some_function()
|
|
57
|
+
except Exception as e:
|
|
58
|
+
error("Operation failed", exception=str(e), operation="some_function")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Django Integration
|
|
62
|
+
|
|
63
|
+
#### 1. Install with Django extras:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install json-logify[django]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### 2. Configure in settings.py:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from logify.django import get_logging_config
|
|
73
|
+
|
|
74
|
+
# Add middleware to MIDDLEWARE list
|
|
75
|
+
MIDDLEWARE = [
|
|
76
|
+
# ... other middleware
|
|
77
|
+
'logify.django.LogifyMiddleware', # ← Add this
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
# Configure logging with json-logify
|
|
81
|
+
LOGGING = get_logging_config(
|
|
82
|
+
service_name="my-django-app",
|
|
83
|
+
level="INFO",
|
|
84
|
+
max_string_length=200, # String truncation limit
|
|
85
|
+
sensitive_fields=[ # Fields to mask with "***"
|
|
86
|
+
"password", "passwd", "secret", "token", "api_key",
|
|
87
|
+
"access_token", "refresh_token", "session_key",
|
|
88
|
+
"credit_card", "cvv", "ssn", "authorization",
|
|
89
|
+
"cookie", "x-api-key", "custom_sensitive_field"
|
|
90
|
+
],
|
|
91
|
+
ignore_paths=[ # Paths to skip logging
|
|
92
|
+
"/health/", "/static/", "/favicon.ico",
|
|
93
|
+
"/admin/jsi18n/", "/metrics/"
|
|
94
|
+
]
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Optional: Reduce Django built-in logger noise
|
|
98
|
+
LOGGING['loggers'].update({
|
|
99
|
+
'django.utils.autoreload': {'level': 'WARNING'},
|
|
100
|
+
'django.db.backends': {'level': 'WARNING'},
|
|
101
|
+
'django.server': {'level': 'WARNING'},
|
|
102
|
+
'django.request': {'level': 'WARNING'},
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### 3. Use in your views:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from logify import info, error, debug, warning
|
|
110
|
+
from django.http import JsonResponse
|
|
111
|
+
|
|
112
|
+
def process_payment(request):
|
|
113
|
+
# Log with automatic request context
|
|
114
|
+
info("Payment processing started",
|
|
115
|
+
user_id=request.user.id,
|
|
116
|
+
amount=request.POST.get('amount'))
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
# Sensitive data gets automatically masked
|
|
120
|
+
info("User data received",
|
|
121
|
+
username=request.user.username, # ← Visible
|
|
122
|
+
password=request.POST.get('password'), # ← Masked: "***"
|
|
123
|
+
credit_card=request.POST.get('card'), # ← Masked: "***"
|
|
124
|
+
email=request.user.email) # ← Visible
|
|
125
|
+
|
|
126
|
+
# Your business logic
|
|
127
|
+
payment = process_payment_logic(request.POST)
|
|
128
|
+
|
|
129
|
+
# Log success
|
|
130
|
+
info("Payment completed",
|
|
131
|
+
payment_id=payment.id,
|
|
132
|
+
status="success",
|
|
133
|
+
amount=payment.amount)
|
|
134
|
+
|
|
135
|
+
return JsonResponse({"status": "success", "payment_id": payment.id})
|
|
136
|
+
|
|
137
|
+
except ValidationError as e:
|
|
138
|
+
error("Payment validation failed", error=e, user_id=request.user.id)
|
|
139
|
+
return JsonResponse({"status": "error", "message": str(e)}, status=400)
|
|
140
|
+
except Exception as e:
|
|
141
|
+
error("Payment processing failed", error=e)
|
|
142
|
+
return JsonResponse({"status": "error"}, status=500)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### 4. What you get automatically:
|
|
146
|
+
|
|
147
|
+
**Request logging:**
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"timestamp": "2025-09-09T08:09:35.933Z",
|
|
151
|
+
"message": "Request started",
|
|
152
|
+
"level": "INFO",
|
|
153
|
+
"payload": {
|
|
154
|
+
"request_id": "b62e59b6-bae7-4a96-821d",
|
|
155
|
+
"service": "my-django-app",
|
|
156
|
+
"method": "POST",
|
|
157
|
+
"path": "/api/payment/",
|
|
158
|
+
"user_info": "User ID: 123: john_doe",
|
|
159
|
+
"headers": {
|
|
160
|
+
"Content-Type": "application/json",
|
|
161
|
+
"Authorization": "***", // ← Automatically masked
|
|
162
|
+
"User-Agent": "curl/8.7.1"
|
|
163
|
+
},
|
|
164
|
+
"request_body": {
|
|
165
|
+
"username": "john_doe",
|
|
166
|
+
"password": "***", // ← Automatically masked
|
|
167
|
+
"credit_card": "***" // ← Automatically masked
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Your application logs:**
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"timestamp": "2025-09-09T08:09:35.934Z",
|
|
177
|
+
"message": "Payment completed",
|
|
178
|
+
"level": "INFO",
|
|
179
|
+
"payload": {
|
|
180
|
+
"request_id": "b62e59b6-bae7-4a96-821d", // ← Auto-linked to request
|
|
181
|
+
"payment_id": "pay_123456",
|
|
182
|
+
"status": "success",
|
|
183
|
+
"amount": 99.99
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**🔒 Security Features:**
|
|
189
|
+
- **Automatic masking**: Passwords, tokens, API keys, credit cards → `"***"`
|
|
190
|
+
- **Header filtering**: Authorization, Cookie, X-API-Key → `"***"`
|
|
191
|
+
- **Recursive masking**: Works in nested objects and arrays
|
|
192
|
+
- **Request/Response body**: Limited size + content-type filtering
|
|
193
|
+
- **Path ignoring**: Skip health checks, static files, etc.
|
|
194
|
+
- Request and response bodies (with sensitive fields masked)
|
|
195
|
+
|
|
196
|
+
<!--
|
|
197
|
+
### FastAPI Integration (Coming Soon)
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from fastapi import FastAPI
|
|
201
|
+
from logify.fastapi import LogifyMiddleware
|
|
202
|
+
|
|
203
|
+
app = FastAPI()
|
|
204
|
+
app.add_middleware(LogifyMiddleware, service_name="myapi")
|
|
205
|
+
|
|
206
|
+
@app.get("/")
|
|
207
|
+
async def root():
|
|
208
|
+
from logify import info
|
|
209
|
+
info("API endpoint called", endpoint="/")
|
|
210
|
+
return {"message": "Hello World"}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Flask Integration (Coming Soon)
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from flask import Flask
|
|
217
|
+
from logify.flask import init_logify
|
|
218
|
+
|
|
219
|
+
app = Flask(__name__)
|
|
220
|
+
init_logify(app, service_name="myapp")
|
|
221
|
+
|
|
222
|
+
@app.route("/")
|
|
223
|
+
def hello():
|
|
224
|
+
from logify import info
|
|
225
|
+
info("Flask endpoint called", endpoint="/")
|
|
226
|
+
return "Hello, World!"
|
|
227
|
+
```
|
|
228
|
+
-->
|
|
229
|
+
|
|
230
|
+
## Advanced Usage
|
|
231
|
+
|
|
232
|
+
### Context Management
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
from logify import bind, set_request_context, clear_request_context
|
|
236
|
+
|
|
237
|
+
# Bind context to a logger
|
|
238
|
+
logger = bind(service="auth", module="login")
|
|
239
|
+
logger.info("Processing login", user_id="123")
|
|
240
|
+
|
|
241
|
+
# Set request-level context (useful in middleware)
|
|
242
|
+
set_request_context(request_id="req-456", user_id="123")
|
|
243
|
+
info("User action", action="view_profile") # Includes request context
|
|
244
|
+
clear_request_context()
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Performance Tracking
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
from logify import track_performance
|
|
251
|
+
|
|
252
|
+
@track_performance
|
|
253
|
+
def expensive_operation():
|
|
254
|
+
# Your code here
|
|
255
|
+
return "result"
|
|
256
|
+
|
|
257
|
+
# Automatically logs function start, completion, and duration
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Custom Configuration
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from logify import configure_logging
|
|
264
|
+
|
|
265
|
+
# Configure with custom settings
|
|
266
|
+
configure_logging(
|
|
267
|
+
service_name="myapp",
|
|
268
|
+
level="DEBUG"
|
|
269
|
+
)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Log Schema
|
|
273
|
+
|
|
274
|
+
All logs follow this exact JSON schema:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"timestamp": "2025-01-15T10:30:00.123Z",
|
|
279
|
+
"message": "Log message here",
|
|
280
|
+
"level": "INFO",
|
|
281
|
+
"error": "Error description (optional)",
|
|
282
|
+
"payload": {
|
|
283
|
+
"service": "myapp",
|
|
284
|
+
"request_id": "req-123",
|
|
285
|
+
"custom_field": "custom_value"
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The `error` field is optional and will only appear when logging errors or exceptions.
|
|
291
|
+
|
|
292
|
+
## Requirements
|
|
293
|
+
|
|
294
|
+
- Python 3.8+
|
|
295
|
+
- structlog >= 23.0.0
|
|
296
|
+
- orjson >= 3.8.0
|
|
297
|
+
|
|
298
|
+
## License
|
|
299
|
+
|
|
300
|
+
MIT License - see LICENSE file for details.
|
|
301
|
+
|
|
302
|
+
## Contributing
|
|
303
|
+
|
|
304
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|