details:   https://code.tryton.org/tryton/commit/70af6f8634b2
branch:    default
user:      Cédric Krier <[email protected]>
date:      Mon Oct 27 19:20:23 2025 +0100
description:
        Replace clean_days with log_size in the cron configuration

        Closes #14319
diffstat:

 trytond/CHANGELOG                    |   1 +
 trytond/doc/topics/configuration.rst |   8 +++---
 trytond/trytond/ir/cron.py           |  39 +++++++++++++++++++++++++++++------
 trytond/trytond/tests/test_ir.py     |  21 +++++++++++++++++++
 4 files changed, 58 insertions(+), 11 deletions(-)

diffs (112 lines):

diff -r a9d8deaa4897 -r 70af6f8634b2 trytond/CHANGELOG
--- a/trytond/CHANGELOG Tue Oct 21 12:14:04 2025 +0200
+++ b/trytond/CHANGELOG Mon Oct 27 19:20:23 2025 +0100
@@ -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)
diff -r a9d8deaa4897 -r 70af6f8634b2 trytond/doc/topics/configuration.rst
--- a/trytond/doc/topics/configuration.rst      Tue Oct 21 12:14:04 2025 +0200
+++ b/trytond/doc/topics/configuration.rst      Mon Oct 27 19:20:23 2025 +0100
@@ -447,12 +447,12 @@
 
 .. _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:
 
diff -r a9d8deaa4897 -r 70af6f8634b2 trytond/trytond/ir/cron.py
--- a/trytond/trytond/ir/cron.py        Tue Oct 21 12:14:04 2025 +0200
+++ b/trytond/trytond/ir/cron.py        Mon Oct 27 19:20:23 2025 +0100
@@ -9,7 +9,8 @@
 
 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 @@
         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)
diff -r a9d8deaa4897 -r 70af6f8634b2 trytond/trytond/tests/test_ir.py
--- a/trytond/trytond/tests/test_ir.py  Tue Oct 21 12:14:04 2025 +0200
+++ b/trytond/trytond/tests/test_ir.py  Mon Oct 27 19:20:23 2025 +0100
@@ -802,5 +802,26 @@
 
         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

Reply via email to