diff --git a/frappe/desk/doctype/system_health_report/system_health_report.json b/frappe/desk/doctype/system_health_report/system_health_report.json index 65899b4c210..b5f4a2840bd 100644 --- a/frappe/desk/doctype/system_health_report/system_health_report.json +++ b/frappe/desk/doctype/system_health_report/system_health_report.json @@ -24,7 +24,12 @@ "failed_emails", "incoming_emails_last_7_days_column", "handled_emails", - "unhandled_emails" + "unhandled_emails", + "errors_tab", + "errors_generated_in_last_1_day_section", + "total_errors", + "top_errors", + "column_break_keyz" ], "fields": [ { @@ -132,6 +137,30 @@ "fieldname": "handled_emails", "fieldtype": "Int", "label": "Handled Emails" + }, + { + "fieldname": "errors_tab", + "fieldtype": "Tab Break", + "label": "Errors" + }, + { + "fieldname": "errors_generated_in_last_1_day_section", + "fieldtype": "Section Break", + "label": "Errors generated in last 1 day" + }, + { + "fieldname": "total_errors", + "fieldtype": "Int", + "label": "Total Errors" + }, + { + "fieldname": "top_errors", + "fieldtype": "Code", + "label": "Top Errors" + }, + { + "fieldname": "column_break_keyz", + "fieldtype": "Column Break" } ], "hide_toolbar": 1, @@ -139,7 +168,7 @@ "is_virtual": 1, "issingle": 1, "links": [], - "modified": "2024-04-18 18:50:33.486009", + "modified": "2024-04-18 19:11:38.645528", "modified_by": "Administrator", "module": "Desk", "name": "System Health Report", diff --git a/frappe/desk/doctype/system_health_report/system_health_report.py b/frappe/desk/doctype/system_health_report/system_health_report.py index 20b4a881f70..ad074b2c336 100644 --- a/frappe/desk/doctype/system_health_report/system_health_report.py +++ b/frappe/desk/doctype/system_health_report/system_health_report.py @@ -48,7 +48,9 @@ class SystemHealthReport(Document): scheduler_status: DF.Data | None socketio_ping_check: DF.Literal["Fail", "Pass"] socketio_transport_mode: DF.Literal["Polling", "Websocket"] + top_errors: DF.Code | None total_background_workers: DF.Int + total_errors: DF.Int total_outgoing_emails: DF.Int unhandled_emails: DF.Int # end: auto-generated types @@ -60,6 +62,7 @@ def load_from_db(self): super(Document, self).__init__({}) self.fetch_background_workers() self.fetch_email_stats() + self.fetch_errors() def fetch_background_workers(self): self.scheduler_status = get_scheduler_status().get("status") @@ -92,7 +95,7 @@ def fetch_background_workers(self): ) def fetch_email_stats(self): - threshold = add_to_date(None, days=-1, as_datetime=True) + threshold = add_to_date(None, days=-7, as_datetime=True) filters = {"creation": (">", threshold), "modified": (">", threshold)} self.total_outgoing_emails = frappe.db.count("Email Queue", filters) self.pending_emails = frappe.db.count("Email Queue", {"status": "Not Sent", **filters}) @@ -103,6 +106,26 @@ def fetch_email_stats(self): {"sent_or_received": "Received", "communication_type": "Communication", **filters}, ) + def fetch_errors(self): + from terminaltables import AsciiTable + + threshold = add_to_date(None, days=-1, as_datetime=True) + filters = {"creation": (">", threshold), "modified": (">", threshold)} + self.total_errors = frappe.db.count("Error Log", filters) + + top_errors = frappe.db.sql( + """select method, count(*) as occurance + from `tabError Log` + where modified > %(threshold)s and creation > %(threshold)s + group by method + order by occurance desc + limit 5""", + {"threshold": threshold}, + as_list=True, + ) + if top_errors: + self.top_errors = AsciiTable([["Error Title", "Count"], *top_errors]).table + def db_update(self): raise NotImplementedError