Kaynağa Gözat

Merge pull request #16118 from shadrak98/log-settings

fix: clean up logs job was broken
version-14
mergify[bot] 3 yıl önce
committed by GitHub
ebeveyn
işleme
70bbcccba7
Veri tabanında bu imza için bilinen anahtar bulunamadı GPG Anahtar Kimliği: 4AEE18F83AFDEB23
5 değiştirilmiş dosya ile 121 ekleme ve 22 silme
  1. +7
    -8
      frappe/core/doctype/activity_log/activity_log.py
  2. +1
    -2
      frappe/core/doctype/log_settings/log_settings.py
  3. +102
    -4
      frappe/core/doctype/log_settings/test_log_settings.py
  4. +2
    -2
      frappe/database/database.py
  5. +9
    -6
      frappe/email/queue.py

+ 7
- 8
frappe/core/doctype/activity_log/activity_log.py Dosyayı Görüntüle

@@ -1,15 +1,14 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# Copyright (c) 2022, Frappe Technologies and contributors
# License: MIT. See LICENSE # License: MIT. See LICENSE


import frappe
from frappe import _ from frappe import _
from frappe.utils import get_fullname, now
from frappe.model.document import Document
from frappe.core.utils import set_timeline_doc from frappe.core.utils import set_timeline_doc
import frappe
from frappe.model.document import Document
from frappe.query_builder import DocType, Interval from frappe.query_builder import DocType, Interval
from frappe.query_builder.functions import Now from frappe.query_builder.functions import Now
from pypika.terms import PseudoColumn
from frappe.utils import get_fullname, now



class ActivityLog(Document): class ActivityLog(Document):
def before_insert(self): def before_insert(self):
@@ -49,5 +48,5 @@ def clear_activity_logs(days=None):
days = 90 days = 90
doctype = DocType("Activity Log") doctype = DocType("Activity Log")
frappe.db.delete(doctype, filters=( frappe.db.delete(doctype, filters=(
doctype.creation < PseudoColumn(f"({Now() - Interval(days=days)})")
))
doctype.creation < (Now() - Interval(days=days))
))

+ 1
- 2
frappe/core/doctype/log_settings/log_settings.py Dosyayı Görüntüle

@@ -7,7 +7,6 @@ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
from frappe.query_builder import DocType, Interval from frappe.query_builder import DocType, Interval
from frappe.query_builder.functions import Now from frappe.query_builder.functions import Now
from pypika.terms import PseudoColumn




class LogSettings(Document): class LogSettings(Document):
@@ -19,7 +18,7 @@ class LogSettings(Document):
def clear_error_logs(self): def clear_error_logs(self):
table = DocType("Error Log") table = DocType("Error Log")
frappe.db.delete(table, filters=( frappe.db.delete(table, filters=(
table.creation < PseudoColumn(f"({Now() - Interval(days=self.clear_error_log_after)})")
table.creation < (Now() - Interval(days=self.clear_error_log_after))
)) ))


def clear_activity_logs(self): def clear_activity_logs(self):


+ 102
- 4
frappe/core/doctype/log_settings/test_log_settings.py Dosyayı Görüntüle

@@ -1,8 +1,106 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies and Contributors
# Copyright (c) 2022, Frappe Technologies and Contributors
# License: MIT. See LICENSE # License: MIT. See LICENSE
# import frappe

from datetime import datetime
import unittest import unittest


import frappe
from frappe.utils import now_datetime, add_to_date
from frappe.core.doctype.log_settings.log_settings import run_log_clean_up


class TestLogSettings(unittest.TestCase): class TestLogSettings(unittest.TestCase):
pass
@classmethod
def setUpClass(cls):

cls.savepoint = "TestLogSettings"
frappe.db.savepoint(cls.savepoint)

frappe.db.set_single_value(
"Log Settings",
{
"clear_error_log_after": 1,
"clear_activity_log_after": 1,
"clear_email_queue_after": 1,
},
)

@classmethod
def tearDownClass(cls):
frappe.db.rollback(save_point=cls.savepoint)

def setUp(self) -> None:
if self._testMethodName == "test_delete_logs":
self.datetime = frappe._dict()
self.datetime.current = now_datetime()
self.datetime.past = add_to_date(self.datetime.current, days=-4)
setup_test_logs(self.datetime.past)

def tearDown(self) -> None:
if self._testMethodName == "test_delete_logs":
del self.datetime

def test_delete_logs(self):
# make sure test data is present
activity_log_count = frappe.db.count(
"Activity Log", {"creation": ("<=", self.datetime.past)}
)
error_log_count = frappe.db.count(
"Error Log", {"creation": ("<=", self.datetime.past)}
)
email_queue_count = frappe.db.count(
"Email Queue", {"creation": ("<=", self.datetime.past)}
)

self.assertNotEqual(activity_log_count, 0)
self.assertNotEqual(error_log_count, 0)
self.assertNotEqual(email_queue_count, 0)

# run clean up job
run_log_clean_up()

# test if logs are deleted
activity_log_count = frappe.db.count(
"Activity Log", {"creation": ("<", self.datetime.past)}
)
error_log_count = frappe.db.count(
"Error Log", {"creation": ("<", self.datetime.past)}
)
email_queue_count = frappe.db.count(
"Email Queue", {"creation": ("<", self.datetime.past)}
)

self.assertEqual(activity_log_count, 0)
self.assertEqual(error_log_count, 0)
self.assertEqual(email_queue_count, 0)


def setup_test_logs(past: datetime) -> None:
activity_log = frappe.get_doc(
{
"doctype": "Activity Log",
"subject": "Test subject",
"full_name": "test user2",
}
).insert(ignore_permissions=True)
activity_log.db_set("creation", past)

error_log = frappe.get_doc(
{
"doctype": "Error Log",
"method": "test_method",
"error": "traceback",
}
).insert(ignore_permissions=True)
error_log.db_set("creation", past)

doc1 = frappe.get_doc(
{
"doctype": "Email Queue",
"sender": "test1@example.com",
"message": "This is a test email1",
"priority": 1,
"expose_recipients": "test@receiver.com",
}
).insert(ignore_permissions=True)
doc1.db_set("creation", past)

+ 2
- 2
frappe/database/database.py Dosyayı Görüntüle

@@ -10,7 +10,7 @@ import re
import string import string
from contextlib import contextmanager from contextlib import contextmanager
from time import time from time import time
from typing import Dict, List, Tuple, Union
from typing import Dict, List, Optional, Tuple, Union


from pypika.terms import Criterion, NullValue, PseudoColumn from pypika.terms import Criterion, NullValue, PseudoColumn


@@ -561,7 +561,7 @@ class Database(object):
def get_list(*args, **kwargs): def get_list(*args, **kwargs):
return frappe.get_list(*args, **kwargs) return frappe.get_list(*args, **kwargs)


def set_single_value(self, doctype, fieldname, value, *args, **kwargs):
def set_single_value(self, doctype: str, fieldname: Union[str, Dict], value: Optional[Union[str, int]] = None, *args, **kwargs):
"""Set field value of Single DocType. """Set field value of Single DocType.


:param doctype: DocType of the single object :param doctype: DocType of the single object


+ 9
- 6
frappe/email/queue.py Dosyayı Görüntüle

@@ -1,10 +1,12 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE # License: MIT. See LICENSE


import frappe import frappe
from frappe import msgprint, _ from frappe import msgprint, _
from frappe.utils.verified_command import get_signed_params, verify_request from frappe.utils.verified_command import get_signed_params, verify_request
from frappe.utils import get_url, now_datetime, cint from frappe.utils import get_url, now_datetime, cint
from frappe.query_builder import DocType, Interval
from frappe.query_builder.functions import Now


def get_emails_sent_this_month(email_account=None): def get_emails_sent_this_month(email_account=None):
"""Get count of emails sent from a specific email account. """Get count of emails sent from a specific email account.
@@ -162,15 +164,16 @@ def get_queue():
by priority desc, creation asc by priority desc, creation asc
limit 500''', { 'now': now_datetime() }, as_dict=True) limit 500''', { 'now': now_datetime() }, as_dict=True)


def clear_outbox(days=None):
def clear_outbox(days: int = None) -> None:
"""Remove low priority older than 31 days in Outbox or configured in Log Settings. """Remove low priority older than 31 days in Outbox or configured in Log Settings.
Note: Used separate query to avoid deadlock Note: Used separate query to avoid deadlock
""" """
if not days:
days=31
days = days or 31
email_queue = DocType("Email Queue")


email_queues = frappe.db.sql_list("""SELECT `name` FROM `tabEmail Queue`
WHERE `priority`=0 AND `modified` < (NOW() - INTERVAL '{0}' DAY)""".format(days))
email_queues = frappe.qb.from_(email_queue).select(email_queue.name).where(
email_queue.modified < (Now() - Interval(days=days))
).run(pluck=True)


if email_queues: if email_queues:
frappe.db.delete("Email Queue", {"name": ("in", email_queues)}) frappe.db.delete("Email Queue", {"name": ("in", email_queues)})


Yükleniyor…
İptal
Kaydet