Projet

Général

Profil

0001-logging-manage-log_retention_days-log-parameters-474.patch

Nicolas Roche, 22 octobre 2020 14:19

Télécharger (8,39 ko)

Voir les différences:

Subject: [PATCH] logging: manage log_retention_days log parameters (#47426)

 ...23_loggingparameters_log_retention_days.py | 20 ++++++++++++++++++
 passerelle/base/models.py                     |  8 ++++++-
 passerelle/base/views.py                      |  5 ++++-
 tests/test_misc.py                            | 21 ++++++++++++++++++-
 4 files changed, 51 insertions(+), 3 deletions(-)
 create mode 100644 passerelle/base/migrations/0023_loggingparameters_log_retention_days.py
passerelle/base/migrations/0023_loggingparameters_log_retention_days.py
1
# -*- coding: utf-8 -*-
2
# Generated by Django 1.11.18 on 2020-10-22 10:00
3
from __future__ import unicode_literals
4

  
5
from django.db import migrations, models
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('base', '0022_auto_20200715_1033'),
12
    ]
13

  
14
    operations = [
15
        migrations.AddField(
16
            model_name='loggingparameters',
17
            name='log_retention_days',
18
            field=models.PositiveIntegerField(default=7, help_text='Number of days to keep logs', verbose_name='Log retention days'),
19
        ),
20
    ]
passerelle/base/models.py
444 444
                                '%s is unsupported' % (field, cls))
445 445
        instance.save()
446 446
        if 'log_level' in d:
447 447
            instance.set_log_level(d['log_level'])
448 448
        return instance
449 449

  
450 450
    def clean_logs(self):
451 451
        # clean logs
452
        timestamp = timezone.now() - datetime.timedelta(days=settings.LOG_RETENTION_DAYS)
452
        timestamp = timezone.now() - datetime.timedelta(
453
            days=self.logging_parameters.log_retention_days)
453 454
        ResourceLog.objects.filter(
454 455
                appname=self.get_connector_slug(),
455 456
                slug=self.slug,
456 457
                timestamp__lt=timestamp).delete()
457 458

  
458 459
    def check_status(self):
459 460
        # should raise an exception if status is not ok
460 461
        raise NotImplementedError
......
665 666
        help_text=_('Maximum HTTP request size to log'),
666 667
        default=settings.LOGGED_REQUESTS_MAX_SIZE
667 668
    )
668 669
    responses_max_size = models.PositiveIntegerField(
669 670
        verbose_name=_('Responses maximum size'),
670 671
        help_text=_('Maximum HTTP reponse size to log'),
671 672
        default=settings.LOGGED_RESPONSES_MAX_SIZE
672 673
    )
674
    log_retention_days = models.PositiveIntegerField(
675
        verbose_name=_('Log retention days'),
676
        help_text=_('Number of days to keep logs'),
677
        default=settings.LOG_RETENTION_DAYS
678
    )
673 679

  
674 680
    class Meta:
675 681
        unique_together = (('resource_type', 'resource_pk'))
676 682

  
677 683

  
678 684
def parse_notification_delays(value):
679 685
    delays = [int(v.strip()) for v in value.split(',')]
680 686
    if not all(delay >= 0 for delay in delays):
passerelle/base/views.py
141 141
    def get_context_data(self, **kwargs):
142 142
        context = super(LoggingParametersUpdateView, self).get_context_data(**kwargs)
143 143
        context['connector'] = self.get_resource()
144 144
        return context
145 145

  
146 146
    def get_form_class(self):
147 147
        form_class = model_forms.modelform_factory(
148 148
            LoggingParameters,
149
            fields=['log_level', 'trace_emails', 'requests_max_size', 'responses_max_size'])
149
            fields=['log_level', 'trace_emails', 'requests_max_size', 'responses_max_size',
150
                    'log_retention_days'])
150 151
        form_class.base_fields['trace_emails'].widget.attrs['rows'] = '3'
151 152
        return form_class
152 153

  
153 154
    def get_initial(self):
154 155
        d = self.initial.copy()
155 156
        d['resource_type'] = self.kwargs['resource_type']
156 157
        d['resource_pk'] = self.kwargs['resource_pk']
157 158
        parameters = self.get_resource().logging_parameters
158 159
        d['log_level'] = parameters.log_level
159 160
        d['trace_emails'] = parameters.trace_emails
160 161
        d['requests_max_size'] = parameters.requests_max_size
161 162
        d['responses_max_size'] = parameters.responses_max_size
163
        d['log_retention_days'] = parameters.log_retention_days
162 164
        return d
163 165

  
164 166
    def get_resource(self):
165 167
        content_type = ContentType.objects.get_for_id(self.kwargs['resource_type'])
166 168
        return content_type.model_class().objects.get(pk=self.kwargs['resource_pk'])
167 169

  
168 170
    def get_success_url(self):
169 171
        return self.get_resource().get_absolute_url()
170 172

  
171 173
    def form_valid(self, form):
172 174
        parameters = self.get_resource().logging_parameters
173 175
        parameters.log_level = form.cleaned_data['log_level']
174 176
        parameters.trace_emails = form.cleaned_data['trace_emails']
175 177
        parameters.requests_max_size = form.cleaned_data['requests_max_size']
176 178
        parameters.responses_max_size = form.cleaned_data['responses_max_size']
179
        parameters.log_retention_days = form.cleaned_data['log_retention_days']
177 180
        parameters.save()
178 181
        return super(LoggingParametersUpdateView, self).form_valid(form)
179 182

  
180 183

  
181 184
class ManageAvailabilityView(UpdateView):
182 185
    template_name = 'passerelle/manage/manage_availability_form.html'
183 186
    form_class = AvailabilityParametersForm
184 187

  
tests/test_misc.py
1 1
import datetime
2 2
import pytest
3 3
from mock import patch
4 4

  
5
from django.contrib.contenttypes.models import ContentType
5 6
from django.core.files import File
6 7
from django.db import connection
7 8
from django.db.migrations.executor import MigrationExecutor
9
from django.core.urlresolvers import reverse
8 10
from django.utils import timezone
9 11
from django.utils.six import StringIO
10 12

  
11 13
from passerelle.base.models import ResourceLog
12 14
from passerelle.apps.opengis.models import OpenGIS
13 15
from passerelle.apps.clicrdv.models import ClicRdv
14 16

  
17
from test_manager import login, admin_user
18

  
15 19

  
16 20
def test_get_description_url_fields(db):
17 21
    connector = OpenGIS(slug='plop', wms_service_url='http://www.example.net')
18 22
    assert 'http://www.example.net' in [x[1] for x in connector.get_description_fields()]
19 23

  
20 24
    connector = OpenGIS(slug='plop', wms_service_url='http://username:secret@www.example.net')
21 25
    assert 'http://***:***@www.example.net' in [x[1] for x in connector.get_description_fields()]
22 26

  
......
25 29

  
26 30

  
27 31
def test_get_description_secret_fields(db):
28 32
    connector = ClicRdv(slug='plop', apikey='secret1', username='plop', password='secret2')
29 33
    assert not 'secret1' in [x[1] for x in connector.get_description_fields()]
30 34
    assert not 'secret2' in [x[1] for x in connector.get_description_fields()]
31 35

  
32 36

  
33
def test_log_cleaning(db):
37
def test_log_cleaning(app, db, admin_user, settings):
34 38
    ResourceLog.objects.all().delete()
35 39
    connector = OpenGIS(slug='plop', wms_service_url='http://www.example.net')
40
    connector.save()
36 41
    connector.logger.error('hello1')
37 42
    connector.logger.error('hello2')
38 43

  
39 44
    assert ResourceLog.objects.all().count() == 2
40 45

  
41 46
    ResourceLog.objects.update(timestamp=timezone.now() - datetime.timedelta(days=10))
42 47
    connector.logger.error('hello3')
43 48
    assert ResourceLog.objects.all().count() == 3
44 49

  
50
    url = reverse('logging-parameters', kwargs={
51
        'resource_type': ContentType.objects.get_for_model(connector).id,
52
        'resource_pk': connector.id})
53
    app = login(app)
54
    resp = app.get(url)
55
    assert int(resp.html.find('input', {'name': 'log_retention_days'})['value']) == \
56
        settings.LOG_RETENTION_DAYS
57
    resp.form['log_retention_days'] = '11'
58
    resp.form.submit()
59
    connector.daily()
60
    assert ResourceLog.objects.all().count() == 3
61

  
62
    resp.form['log_retention_days'] = '10'
63
    resp.form.submit()
45 64
    connector.daily()
46 65
    assert ResourceLog.objects.all().count() == 1
47 66

  
48 67
@pytest.fixture
49 68
def email_handler():
50 69
    import logging
51 70
    from django.utils.log import AdminEmailHandler
52 71

  
53
-