django-structlog 6.1.0.dev1__tar.gz → 7.0.0.dev1__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.
- {django-structlog-6.1.0.dev1/django_structlog.egg-info → django-structlog-7.0.0.dev1}/PKG-INFO +13 -2
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/README.rst +11 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/__init__.py +1 -1
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/receivers.py +13 -20
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/commands.py +2 -5
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/middlewares/request.py +82 -45
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1/django_structlog.egg-info}/PKG-INFO +13 -2
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog.egg-info/requires.txt +1 -1
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/pyproject.toml +2 -2
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/LICENSE.rst +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/MANIFEST.in +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/app_settings.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/apps.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/__init__.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/signals.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/steps.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/middlewares/__init__.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/signals.py +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog.egg-info/SOURCES.txt +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog.egg-info/dependency_links.txt +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog.egg-info/top_level.txt +0 -0
- {django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/setup.cfg +0 -0
{django-structlog-6.1.0.dev1/django_structlog.egg-info → django-structlog-7.0.0.dev1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-structlog
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0.dev1
|
|
4
4
|
Summary: Structured Logging for Django
|
|
5
5
|
Author-email: Jules Robichaud-Gagnon <j.robichaudg+pypi@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -29,7 +29,7 @@ License-File: LICENSE.rst
|
|
|
29
29
|
Requires-Dist: django>=3.2
|
|
30
30
|
Requires-Dist: structlog>=21.4.0
|
|
31
31
|
Requires-Dist: asgiref>=3.6.0
|
|
32
|
-
Requires-Dist: django-ipware
|
|
32
|
+
Requires-Dist: django-ipware>=6.0.2
|
|
33
33
|
Provides-Extra: celery
|
|
34
34
|
Requires-Dist: celery>=5.1; extra == "celery"
|
|
35
35
|
Provides-Extra: commands
|
|
@@ -399,6 +399,17 @@ Json file (\ ``logs/json.log``\ )
|
|
|
399
399
|
Upgrade Guide
|
|
400
400
|
=============
|
|
401
401
|
|
|
402
|
+
.. _upgrade_7.0:
|
|
403
|
+
|
|
404
|
+
Upgrading to 7.0+
|
|
405
|
+
^^^^^^^^^^^^^^^^^
|
|
406
|
+
|
|
407
|
+
The dependency `django-ipware <https://github.com/un33k/django-ipware>`_ was upgraded to version 6. This library is used to retrieve the request's ip address.
|
|
408
|
+
|
|
409
|
+
Version 6 may have some `breaking changes <https://github.com/un33k/django-ipware/compare/v5.0.2...v6.0.2#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R97>`_ if you did customizations.
|
|
410
|
+
|
|
411
|
+
It should not affect most of the users but if you did some customizations, you might need to update your configurations.
|
|
412
|
+
|
|
402
413
|
.. _upgrade_6.0:
|
|
403
414
|
|
|
404
415
|
Upgrading to 6.0+
|
|
@@ -362,6 +362,17 @@ Json file (\ ``logs/json.log``\ )
|
|
|
362
362
|
Upgrade Guide
|
|
363
363
|
=============
|
|
364
364
|
|
|
365
|
+
.. _upgrade_7.0:
|
|
366
|
+
|
|
367
|
+
Upgrading to 7.0+
|
|
368
|
+
^^^^^^^^^^^^^^^^^
|
|
369
|
+
|
|
370
|
+
The dependency `django-ipware <https://github.com/un33k/django-ipware>`_ was upgraded to version 6. This library is used to retrieve the request's ip address.
|
|
371
|
+
|
|
372
|
+
Version 6 may have some `breaking changes <https://github.com/un33k/django-ipware/compare/v5.0.2...v6.0.2#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R97>`_ if you did customizations.
|
|
373
|
+
|
|
374
|
+
It should not affect most of the users but if you did some customizations, you might need to update your configurations.
|
|
375
|
+
|
|
365
376
|
.. _upgrade_6.0:
|
|
366
377
|
|
|
367
378
|
Upgrading to 6.0+
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/receivers.py
RENAMED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import structlog
|
|
2
|
+
from celery import current_app
|
|
3
|
+
from celery.signals import (
|
|
4
|
+
before_task_publish,
|
|
5
|
+
after_task_publish,
|
|
6
|
+
task_prerun,
|
|
7
|
+
task_retry,
|
|
8
|
+
task_success,
|
|
9
|
+
task_failure,
|
|
10
|
+
task_revoked,
|
|
11
|
+
task_unknown,
|
|
12
|
+
task_rejected,
|
|
13
|
+
)
|
|
2
14
|
|
|
3
15
|
from . import signals
|
|
4
16
|
|
|
@@ -19,9 +31,7 @@ class CeleryReceiver:
|
|
|
19
31
|
routing_key=None,
|
|
20
32
|
**kwargs,
|
|
21
33
|
):
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if celery.current_app.conf.task_protocol < 2:
|
|
34
|
+
if current_app.conf.task_protocol < 2:
|
|
25
35
|
return
|
|
26
36
|
|
|
27
37
|
context = structlog.contextvars.get_merged_contextvars(logger)
|
|
@@ -128,27 +138,10 @@ class CeleryReceiver:
|
|
|
128
138
|
)
|
|
129
139
|
|
|
130
140
|
def connect_signals(self):
|
|
131
|
-
from celery.signals import (
|
|
132
|
-
before_task_publish,
|
|
133
|
-
after_task_publish,
|
|
134
|
-
)
|
|
135
|
-
|
|
136
141
|
before_task_publish.connect(self.receiver_before_task_publish)
|
|
137
142
|
after_task_publish.connect(self.receiver_after_task_publish)
|
|
138
143
|
|
|
139
144
|
def connect_worker_signals(self):
|
|
140
|
-
from celery.signals import (
|
|
141
|
-
before_task_publish,
|
|
142
|
-
after_task_publish,
|
|
143
|
-
task_prerun,
|
|
144
|
-
task_retry,
|
|
145
|
-
task_success,
|
|
146
|
-
task_failure,
|
|
147
|
-
task_revoked,
|
|
148
|
-
task_unknown,
|
|
149
|
-
task_rejected,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
145
|
before_task_publish.connect(self.receiver_before_task_publish)
|
|
153
146
|
after_task_publish.connect(self.receiver_after_task_publish)
|
|
154
147
|
task_prerun.connect(self.receiver_task_prerun)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import structlog
|
|
2
2
|
import uuid
|
|
3
3
|
|
|
4
|
+
from django_extensions.management.signals import pre_command, post_command
|
|
5
|
+
|
|
4
6
|
logger = structlog.getLogger(__name__)
|
|
5
7
|
|
|
6
8
|
|
|
@@ -32,10 +34,5 @@ class DjangoCommandReceiver:
|
|
|
32
34
|
structlog.contextvars.reset_contextvars(**tokens)
|
|
33
35
|
|
|
34
36
|
def connect_signals(self):
|
|
35
|
-
try:
|
|
36
|
-
from django_extensions.management.signals import pre_command, post_command
|
|
37
|
-
except ModuleNotFoundError: # pragma: no cover
|
|
38
|
-
return
|
|
39
|
-
|
|
40
37
|
pre_command.connect(self.pre_receiver)
|
|
41
38
|
post_command.connect(self.post_receiver)
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/middlewares/request.py
RENAMED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import logging
|
|
2
3
|
import uuid
|
|
3
4
|
|
|
4
5
|
import structlog
|
|
5
6
|
from asgiref.sync import iscoroutinefunction, markcoroutinefunction
|
|
6
7
|
from django.core.exceptions import PermissionDenied
|
|
7
|
-
from django.http import Http404
|
|
8
|
+
from django.http import Http404, StreamingHttpResponse
|
|
8
9
|
from asgiref import sync
|
|
9
10
|
|
|
10
11
|
from .. import signals
|
|
@@ -20,13 +21,69 @@ def get_request_header(request, header_key, meta_key):
|
|
|
20
21
|
return request.META.get(meta_key)
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
def sync_streaming_content_wrapper(streaming_content, context):
|
|
25
|
+
with structlog.contextvars.bound_contextvars(**context):
|
|
26
|
+
logger.info("streaming_started")
|
|
27
|
+
try:
|
|
28
|
+
for chunk in streaming_content:
|
|
29
|
+
yield chunk
|
|
30
|
+
except Exception:
|
|
31
|
+
logger.exception("streaming_failed")
|
|
32
|
+
else:
|
|
33
|
+
logger.info("streaming_finished")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def async_streaming_content_wrapper(streaming_content, context):
|
|
37
|
+
with structlog.contextvars.bound_contextvars(**context):
|
|
38
|
+
logger.info("streaming_started")
|
|
39
|
+
try:
|
|
40
|
+
async for chunk in streaming_content:
|
|
41
|
+
yield chunk
|
|
42
|
+
except asyncio.CancelledError:
|
|
43
|
+
logger.warning("streaming_cancelled")
|
|
44
|
+
raise
|
|
45
|
+
except Exception:
|
|
46
|
+
logger.exception("streaming_failed")
|
|
47
|
+
else:
|
|
48
|
+
logger.info("streaming_finished")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class RequestMiddleware:
|
|
52
|
+
"""``RequestMiddleware`` adds request metadata to ``structlog``'s logger context automatically.
|
|
53
|
+
|
|
54
|
+
>>> MIDDLEWARE = [
|
|
55
|
+
... # ...
|
|
56
|
+
... 'django_structlog.middlewares.RequestMiddleware',
|
|
57
|
+
... ]
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
sync_capable = True
|
|
62
|
+
async_capable = True
|
|
63
|
+
|
|
24
64
|
def __init__(self, get_response):
|
|
25
65
|
self.get_response = get_response
|
|
66
|
+
if iscoroutinefunction(self.get_response):
|
|
67
|
+
markcoroutinefunction(self)
|
|
68
|
+
|
|
69
|
+
def __call__(self, request):
|
|
70
|
+
if iscoroutinefunction(self):
|
|
71
|
+
return self.__acall__(request)
|
|
72
|
+
self.prepare(request)
|
|
73
|
+
response = self.get_response(request)
|
|
74
|
+
self.handle_response(request, response)
|
|
75
|
+
return response
|
|
76
|
+
|
|
77
|
+
async def __acall__(self, request):
|
|
78
|
+
await sync.sync_to_async(self.prepare)(request)
|
|
79
|
+
response = await self.get_response(request)
|
|
80
|
+
await sync.sync_to_async(self.handle_response)(request, response)
|
|
81
|
+
return response
|
|
26
82
|
|
|
27
83
|
def handle_response(self, request, response):
|
|
28
84
|
if not hasattr(request, "_raised_exception"):
|
|
29
85
|
self.bind_user_id(request)
|
|
86
|
+
context = structlog.contextvars.get_merged_contextvars(logger)
|
|
30
87
|
signals.bind_extra_request_finished_metadata.send(
|
|
31
88
|
sender=self.__class__,
|
|
32
89
|
request=request,
|
|
@@ -45,6 +102,19 @@ class BaseRequestMiddleWare:
|
|
|
45
102
|
code=response.status_code,
|
|
46
103
|
request=self.format_request(request),
|
|
47
104
|
)
|
|
105
|
+
if isinstance(response, StreamingHttpResponse):
|
|
106
|
+
streaming_content = response.streaming_content
|
|
107
|
+
try:
|
|
108
|
+
iter(streaming_content)
|
|
109
|
+
except TypeError:
|
|
110
|
+
response.streaming_content = async_streaming_content_wrapper(
|
|
111
|
+
streaming_content, context
|
|
112
|
+
)
|
|
113
|
+
else:
|
|
114
|
+
response.streaming_content = sync_streaming_content_wrapper(
|
|
115
|
+
streaming_content, context
|
|
116
|
+
)
|
|
117
|
+
|
|
48
118
|
else:
|
|
49
119
|
exception = getattr(request, "_raised_exception")
|
|
50
120
|
delattr(request, "_raised_exception")
|
|
@@ -85,6 +155,16 @@ class BaseRequestMiddleWare:
|
|
|
85
155
|
def format_request(request):
|
|
86
156
|
return f"{request.method} {request.get_full_path()}"
|
|
87
157
|
|
|
158
|
+
@staticmethod
|
|
159
|
+
def bind_user_id(request):
|
|
160
|
+
if hasattr(request, "user") and request.user is not None:
|
|
161
|
+
user_id = None
|
|
162
|
+
if hasattr(request.user, "pk"):
|
|
163
|
+
user_id = request.user.pk
|
|
164
|
+
if isinstance(user_id, uuid.UUID):
|
|
165
|
+
user_id = str(user_id)
|
|
166
|
+
structlog.contextvars.bind_contextvars(user_id=user_id)
|
|
167
|
+
|
|
88
168
|
def process_exception(self, request, exception):
|
|
89
169
|
if isinstance(exception, (Http404, PermissionDenied)):
|
|
90
170
|
# We don't log an exception here, and we don't set that we handled
|
|
@@ -105,46 +185,3 @@ class BaseRequestMiddleWare:
|
|
|
105
185
|
code=500,
|
|
106
186
|
request=self.format_request(request),
|
|
107
187
|
)
|
|
108
|
-
|
|
109
|
-
@staticmethod
|
|
110
|
-
def bind_user_id(request):
|
|
111
|
-
if hasattr(request, "user") and request.user is not None:
|
|
112
|
-
user_id = None
|
|
113
|
-
if hasattr(request.user, "pk"):
|
|
114
|
-
user_id = request.user.pk
|
|
115
|
-
if isinstance(user_id, uuid.UUID):
|
|
116
|
-
user_id = str(user_id)
|
|
117
|
-
structlog.contextvars.bind_contextvars(user_id=user_id)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class RequestMiddleware(BaseRequestMiddleWare):
|
|
121
|
-
"""``RequestMiddleware`` adds request metadata to ``structlog``'s logger context automatically.
|
|
122
|
-
|
|
123
|
-
>>> MIDDLEWARE = [
|
|
124
|
-
... # ...
|
|
125
|
-
... 'django_structlog.middlewares.RequestMiddleware',
|
|
126
|
-
... ]
|
|
127
|
-
|
|
128
|
-
"""
|
|
129
|
-
|
|
130
|
-
sync_capable = True
|
|
131
|
-
async_capable = True
|
|
132
|
-
|
|
133
|
-
def __init__(self, get_response):
|
|
134
|
-
super().__init__(get_response)
|
|
135
|
-
if iscoroutinefunction(self.get_response):
|
|
136
|
-
markcoroutinefunction(self)
|
|
137
|
-
|
|
138
|
-
def __call__(self, request):
|
|
139
|
-
if iscoroutinefunction(self):
|
|
140
|
-
return self.__acall__(request)
|
|
141
|
-
self.prepare(request)
|
|
142
|
-
response = self.get_response(request)
|
|
143
|
-
self.handle_response(request, response)
|
|
144
|
-
return response
|
|
145
|
-
|
|
146
|
-
async def __acall__(self, request):
|
|
147
|
-
await sync.sync_to_async(self.prepare)(request)
|
|
148
|
-
response = await self.get_response(request)
|
|
149
|
-
await sync.sync_to_async(self.handle_response)(request, response)
|
|
150
|
-
return response
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1/django_structlog.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-structlog
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0.dev1
|
|
4
4
|
Summary: Structured Logging for Django
|
|
5
5
|
Author-email: Jules Robichaud-Gagnon <j.robichaudg+pypi@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -29,7 +29,7 @@ License-File: LICENSE.rst
|
|
|
29
29
|
Requires-Dist: django>=3.2
|
|
30
30
|
Requires-Dist: structlog>=21.4.0
|
|
31
31
|
Requires-Dist: asgiref>=3.6.0
|
|
32
|
-
Requires-Dist: django-ipware
|
|
32
|
+
Requires-Dist: django-ipware>=6.0.2
|
|
33
33
|
Provides-Extra: celery
|
|
34
34
|
Requires-Dist: celery>=5.1; extra == "celery"
|
|
35
35
|
Provides-Extra: commands
|
|
@@ -399,6 +399,17 @@ Json file (\ ``logs/json.log``\ )
|
|
|
399
399
|
Upgrade Guide
|
|
400
400
|
=============
|
|
401
401
|
|
|
402
|
+
.. _upgrade_7.0:
|
|
403
|
+
|
|
404
|
+
Upgrading to 7.0+
|
|
405
|
+
^^^^^^^^^^^^^^^^^
|
|
406
|
+
|
|
407
|
+
The dependency `django-ipware <https://github.com/un33k/django-ipware>`_ was upgraded to version 6. This library is used to retrieve the request's ip address.
|
|
408
|
+
|
|
409
|
+
Version 6 may have some `breaking changes <https://github.com/un33k/django-ipware/compare/v5.0.2...v6.0.2#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R97>`_ if you did customizations.
|
|
410
|
+
|
|
411
|
+
It should not affect most of the users but if you did some customizations, you might need to update your configurations.
|
|
412
|
+
|
|
402
413
|
.. _upgrade_6.0:
|
|
403
414
|
|
|
404
415
|
Upgrading to 6.0+
|
|
@@ -16,7 +16,7 @@ build-backend = "setuptools.build_meta"
|
|
|
16
16
|
"django>=3.2",
|
|
17
17
|
"structlog>=21.4.0",
|
|
18
18
|
"asgiref>=3.6.0",
|
|
19
|
-
"django-ipware",
|
|
19
|
+
"django-ipware>=6.0.2",
|
|
20
20
|
]
|
|
21
21
|
classifiers = [
|
|
22
22
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -129,7 +129,7 @@ build-backend = "setuptools.build_meta"
|
|
|
129
129
|
django32: Django >=3.2, <4.0
|
|
130
130
|
django41: Django >=4.1, <4.2
|
|
131
131
|
django42: Django >=4.2, <5.0
|
|
132
|
-
django50: Django
|
|
132
|
+
django50: Django >=5.0, <5.1
|
|
133
133
|
-r{toxinidir}/requirements/ci.txt
|
|
134
134
|
|
|
135
135
|
commands = pytest --cov=./test_app --cov=./django_structlog --cov-append test_app
|
|
File without changes
|
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/app_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/__init__.py
RENAMED
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/signals.py
RENAMED
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/celery/steps.py
RENAMED
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog/middlewares/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{django-structlog-6.1.0.dev1 → django-structlog-7.0.0.dev1}/django_structlog.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|