0001-logging-add-LOGGED_REQUEST_MAX_SIZE-settings.patch
passerelle/settings.py | ||
---|---|---|
211 | 211 |
# Max size of the response to log |
212 | 212 |
LOGGED_RESPONSES_MAX_SIZE = 4096 |
213 | 213 | |
214 |
# Max size of the request to log |
|
215 |
LOGGED_REQUEST_MAX_SIZE = 5000 |
|
216 | ||
214 | 217 |
# Number of days to keep logs |
215 | 218 |
LOG_RETENTION_DAYS = 7 |
216 | 219 |
passerelle/utils/__init__.py | ||
---|---|---|
158 | 158 |
if logger.level == 10: # DEBUG |
159 | 159 |
extra['request_headers'] = dict(request.headers.items()) |
160 | 160 |
if request.body: |
161 |
extra['request_payload'] = repr(request.body[:5000])
|
|
161 |
extra['request_payload'] = repr(request.body[:settings.LOGGED_REQUEST_MAX_SIZE])
|
|
162 | 162 |
if response is not None: |
163 | 163 |
message = message + ' (=> %s)' % response.status_code |
164 | 164 |
extra['response_status'] = response.status_code |
passerelle/utils/jsonresponse.py | ||
---|---|---|
132 | 132 |
except Exception as e: |
133 | 133 |
extras = {'method': req.method, 'exception': exception_to_text(e), 'request': req} |
134 | 134 |
if req.method == 'POST': |
135 |
extras.update({'body': repr(req.body[:5000])})
|
|
135 |
extras.update({'body': repr(req.body[:settings.LOGGED_REQUEST_MAX_SIZE])})
|
|
136 | 136 |
if (not isinstance(e, (Http404, PermissionDenied, ObjectDoesNotExist, RequestException)) |
137 | 137 |
and getattr(e, 'log_error', True)): |
138 | 138 |
logger.exception("Error occurred while processing request", extra=extras) |
passerelle/views.py | ||
---|---|---|
394 | 394 |
connector_name, endpoint_name = kwargs['connector'], kwargs['endpoint'] |
395 | 395 |
connector = self.get_object() |
396 | 396 |
url = request.get_full_path() |
397 |
payload = request.body[:5000]
|
|
397 |
payload = request.body[:settings.LOGGED_REQUEST_MAX_SIZE]
|
|
398 | 398 |
try: |
399 | 399 |
payload.decode('utf-8') |
400 | 400 |
except UnicodeDecodeError: |
tests/test_api_access.py | ||
---|---|---|
7 | 7 | |
8 | 8 |
import pytest |
9 | 9 | |
10 |
from django.test import override_settings |
|
11 | ||
10 | 12 |
from passerelle.base import signature |
11 |
from passerelle.base.models import ApiUser, AccessRight |
|
13 |
from passerelle.base.models import ApiUser, AccessRight, ResourceLog
|
|
12 | 14 |
from passerelle.apps.oxyd.models import OxydSMSGateway |
13 | 15 | |
14 | 16 |
pytestmark = pytest.mark.django_db |
... | ... | |
181 | 183 |
extra_environ={'REMOTE_ADDR': authorized_ip}) |
182 | 184 |
assert resp.json['err'] == 1 |
183 | 185 |
assert resp.json['err_desc'] == 'Payload error: missing "message" in JSON payload' |
186 | ||
187 |
def test_logged_request_max_size(app, oxyd): |
|
188 |
endpoint_url = reverse('generic-endpoint', |
|
189 |
kwargs={'connector': 'oxyd', 'slug': oxyd.slug, 'endpoint': 'send'}) |
|
190 |
api = ApiUser.objects.create(username='public', |
|
191 |
fullname='public', |
|
192 |
description='access for all', |
|
193 |
keytype='', key='') |
|
194 |
obj_type = ContentType.objects.get_for_model(OxydSMSGateway) |
|
195 |
AccessRight.objects.create(codename='can_send_messages', |
|
196 |
apiuser=api, |
|
197 |
resource_type=obj_type, |
|
198 |
resource_pk=oxyd.pk, |
|
199 |
) |
|
200 |
resp = app.post_json(endpoint_url, params={'foo': 'bar'}) |
|
201 |
assert ResourceLog.objects.all()[0].message[-9:] == '"bar"}\') ' |
|
202 | ||
203 |
# for empty payload the connector returns an APIError with |
|
204 |
assert 'Error occurred' in ResourceLog.objects.all()[1].message |
|
205 | ||
206 |
# troncate logs |
|
207 |
with override_settings(LOGGED_REQUEST_MAX_SIZE=6): |
|
208 |
resp = app.post_json(endpoint_url, params={'foo': 'bar'}) |
|
209 |
assert ResourceLog.objects.all()[2].message[-8:] == '"foo"\') ' |
tests/test_requests.py | ||
---|---|---|
105 | 105 |
assert not hasattr(record, 'response_content') |
106 | 106 |
assert not hasattr(record, 'response_headers') |
107 | 107 | |
108 |
def test_log_error_request_max_size(caplog, log_level): |
|
109 |
url = 'https://httperror.org/plop' |
|
110 | ||
111 |
logger = logging.getLogger('requests') |
|
112 |
logger.setLevel(log_level) |
|
113 | ||
114 |
with override_settings(LOGGED_REQUEST_MAX_SIZE=8): |
|
115 |
with HTTMock(http400_mock): |
|
116 |
requests = Request(logger=logger) |
|
117 |
response = requests.post(url, json={'name':'josh'}) |
|
118 | ||
119 |
print logger.level |
|
120 |
if logger.level == 10: # DEBUG |
|
121 |
records = [record for record in caplog.records if record.name == 'requests'] |
|
122 |
assert records[0].request_payload == '\'{"name":\'' |
|
123 | ||
124 | ||
108 | 125 |
@pytest.fixture(params=['xml', 'whatever', 'jpeg', 'pdf']) |
109 | 126 |
def endpoint_response(request): |
110 | 127 |
response_request = mock.Mock( |
111 |
- |