Replace clean_days with log_size in the cron configuration

Closes #14319
This commit is contained in:
Cédric Krier
2025-10-27 19:20:23 +01:00
parent ff2c9f7bc3
commit b7ee37bb0a
4 changed files with 58 additions and 11 deletions
+1
View File
@@ -1,3 +1,4 @@
* Replace ``clean_days`` with ``log_size`` in the cron configuration
* Enforce access check in export_data (issue14366)
* Include the traceback only in RPC responses in development mode (issue14354)
* Enforce access check in HTML editor route (issue14364)
+4 -4
View File
@@ -447,12 +447,12 @@ cron
.. _config-cron.clean_days:
clean_days
~~~~~~~~~~
log_size
~~~~~~~~
The number of days after which scheduled task logs are removed.
The approximate number of log entries to keep for each scheduled task.
Default: ``30``
Default: ``100``
.. _config-queue:
+32 -7
View File
@@ -9,7 +9,8 @@ from collections import defaultdict
from dateutil.relativedelta import relativedelta
from sql import Literal
from sql.conditionals import Coalesce
from sql.conditionals import Case, Coalesce
from sql.functions import CurrentTimestamp, Extract
from trytond import backend, config
from trytond.exceptions import UserError, UserWarning
@@ -311,10 +312,34 @@ class Log(ModelSQL, ModelView):
return self.ended - self.started
@classmethod
def clean(cls, date=None):
if date is None:
clean_days = config.getint('cron', 'clean_days', default=30)
date = (
datetime.datetime.now() - datetime.timedelta(days=clean_days))
logs = cls.search([('create_date', '<', date)])
def clean(cls, size=None):
pool = Pool()
Cron = pool.get('ir.cron')
cursor = Transaction().connection.cursor()
log = cls.__table__()
cron = Cron.__table__()
if size is None:
size = config.getint('cron', 'log_size', default=100)
interval = Case(
(cron.interval_type == 'minutes', datetime.timedelta(minutes=1)),
(cron.interval_type == 'hours', datetime.timedelta(hours=1)),
(cron.interval_type == 'days', datetime.timedelta(days=1)),
(cron.interval_type == 'weeks', datetime.timedelta(weeks=1)),
(cron.interval_type == 'months', datetime.timedelta(days=30)))
started = log.started
now = CurrentTimestamp()
if backend.name == 'sqlite':
started = Extract('epoch', started)
now = Extract('epoch', now)
cursor.execute(*log
.join(cron, condition=log.cron == cron.id)
.select(log.id,
where=started < (
now - (interval * cron.interval_number * size))))
logs = cls.browse([l for l, in cursor])
cls.delete(logs)
+21
View File
@@ -802,5 +802,26 @@ class IrCronTestCase(TestCase):
self.assertIsInstance(cron.get_timezone('timezone'), str)
@with_transaction()
def test_clean(self):
"Test cleaning cron logs"
pool = Pool()
Cron = pool.get('ir.cron')
Log = pool.get('ir.cron.log')
dt = datetime
cron = Cron(
interval_number=2, interval_type='hours',
method='ir.trigger|trigger_time')
cron.logs = [{
'started': dt.datetime.now() - dt.timedelta(hours=i),
'ended': dt.datetime.now() - dt.timedelta(hours=i + 1)}
for i in range(0, 20, 2)]
cron.save()
Log.clean(5)
self.assertEqual(len(cron.logs), 5)
del ModuleTestCase