From 227c1b0433cf7c27f3c51609d7cf03bbf034d3b9 Mon Sep 17 00:00:00 2001 From: hail-cookies <81558994+hail-cookies@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:14:13 +0100 Subject: [PATCH 1/6] FIX DataCheck improved logging --- CommonLogic/DataSheets/DataCheck.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CommonLogic/DataSheets/DataCheck.php b/CommonLogic/DataSheets/DataCheck.php index 6635d3fa9..b6a0f1d74 100644 --- a/CommonLogic/DataSheets/DataCheck.php +++ b/CommonLogic/DataSheets/DataCheck.php @@ -156,7 +156,7 @@ protected function findViolationsViaFilter(DataSheetInterface $data, ConditionGr return $data->findRows($filter, $readMissingData, $logBook); } catch (DataSheetExtractError $e) { $logBook?->addLine('**ERROR** filtering data to check via `' . $filter->__toString() . '`. Assuming check does not apply'); - $this->getWorkbench()->getLogger()->logException(new DataCheckRuntimeError($data, 'Cannot perform data check. ' . $e->getMessage(), null, $e, $this)); + $this->getWorkbench()->getLogger()->logException(new DataCheckRuntimeError($data, 'Cannot perform data check via `' . $filter->__toString() . '`. ' . $e->getMessage(), null, $e, $this)); return []; } } From d6f6f37e1589a9ae6844a5e0159a269622301c0a Mon Sep 17 00:00:00 2001 From: hail-cookies <81558994+hail-cookies@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:40:37 +0100 Subject: [PATCH 2/6] FIX DataCheck improved logging --- CommonLogic/DataSheets/DataCheck.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CommonLogic/DataSheets/DataCheck.php b/CommonLogic/DataSheets/DataCheck.php index b6a0f1d74..438968425 100644 --- a/CommonLogic/DataSheets/DataCheck.php +++ b/CommonLogic/DataSheets/DataCheck.php @@ -155,7 +155,7 @@ protected function findViolationsViaFilter(DataSheetInterface $data, ConditionGr try { return $data->findRows($filter, $readMissingData, $logBook); } catch (DataSheetExtractError $e) { - $logBook?->addLine('**ERROR** filtering data to check via `' . $filter->__toString() . '`. Assuming check does not apply'); + $logBook?->addLine('**ERROR** filtering data to check via `' . $filter->__toString() . '`. Assuming check does not apply: **' . $e->getMessage() . '**'); $this->getWorkbench()->getLogger()->logException(new DataCheckRuntimeError($data, 'Cannot perform data check via `' . $filter->__toString() . '`. ' . $e->getMessage(), null, $e, $this)); return []; } From b1ec28ab292763820d92d2a23c29580578fa71f1 Mon Sep 17 00:00:00 2001 From: hail-cookies <81558994+hail-cookies@users.noreply.github.com> Date: Thu, 5 Feb 2026 15:37:01 +0100 Subject: [PATCH 3/6] DEV Monitor now tracks task_class, request_size and identifies UI tasks --- CommonLogic/Monitor.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/CommonLogic/Monitor.php b/CommonLogic/Monitor.php index da595afe3..29943ce87 100644 --- a/CommonLogic/Monitor.php +++ b/CommonLogic/Monitor.php @@ -2,8 +2,11 @@ namespace exface\Core\CommonLogic; use exface\Core\CommonLogic\Debugger\Profiler; +use exface\Core\DataTypes\PhpClassDataType; use exface\Core\Events\Action\OnBeforeActionPerformedEvent; use exface\Core\Events\Action\OnActionPerformedEvent; +use exface\Core\Facades\AbstractAjaxFacade\AbstractAjaxFacade; +use exface\Core\Interfaces\Tasks\HttpTaskInterface; use exface\Core\Interfaces\WorkbenchInterface; use exface\Core\Interfaces\Actions\ActionInterface; use exface\Core\Interfaces\Actions\iReadData; @@ -233,12 +236,12 @@ protected function isActionMonitored(ActionInterface $action) : bool return true; } } - + /** - * + * * @param ActionInterface $action - * @param TaskInterface $task - * @param float $duration + * @param TaskInterface $task + * @param float|null $duration * @return Monitor */ protected function addRowFromAction(ActionInterface $action, TaskInterface $task, float $duration = null) : Monitor @@ -323,8 +326,12 @@ protected function saveData() : Monitor 'USER' => $this->getWorkbench()->getSecurity()->getAuthenticatedUser()->getUid(), 'TIME' => $item['time'], 'DATE' => DateDataType::cast($item['time']), - 'DURATION' => $this->getTimeTotalMs() + 'DURATION' => $this->getTimeTotalMs(), + 'TASK_CLASS' => PhpClassDataType::findClassNameWithoutNamespace($task), + 'REQUEST_SIZE' => $task instanceof HttpTaskInterface ? $task->getHttpRequest()->getHeader('Content-Length')[0] : null, + 'UI_FLAG' => $task->getFacade() instanceof AbstractAjaxFacade ]); + $ds->dataCreate(); $logIds = $item['logIds']; From 507f53837b7edbac7dc578c60194434abb437b37 Mon Sep 17 00:00:00 2001 From: hail-cookies <81558994+hail-cookies@users.noreply.github.com> Date: Thu, 5 Feb 2026 15:41:30 +0100 Subject: [PATCH 4/6] DEV PAGE Monitor filtered out all non-UI actions --- Model/99_PAGE/exface.core.monitor.json | 10 +- .../04_ATTRIBUTE.json | 152 ++++++++++++++++++ 2 files changed, 160 insertions(+), 2 deletions(-) diff --git a/Model/99_PAGE/exface.core.monitor.json b/Model/99_PAGE/exface.core.monitor.json index d6177c5fb..0051d60ba 100644 --- a/Model/99_PAGE/exface.core.monitor.json +++ b/Model/99_PAGE/exface.core.monitor.json @@ -10,8 +10,8 @@ "replaces_page_selector": null, "created_by_user_selector": "0x31000000000000000000000000000000", "created_on": "2020-11-17 13:30:20", - "modified_by_user_selector": "0x11edb424effd2980b424025041000001", - "modified_on": "2024-03-12 09:53:45", + "modified_by_user_selector": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "modified_on": "2026-02-05 15:24:16", "icon": "tachometer", "contents": { "widget_type": "SplitVertical", @@ -401,6 +401,12 @@ "apply_on_change": true, "hidden": true }, + { + "attribute_alias": "UI_FLAG", + "comparator": "!==", + "value": 0, + "hidden": true + }, { "attribute_alias": "ACTION_NAME" }, diff --git a/Model/exface.Core.MONITOR_ACTION/04_ATTRIBUTE.json b/Model/exface.Core.MONITOR_ACTION/04_ATTRIBUTE.json index 9213c0367..5bbaa2328 100644 --- a/Model/exface.Core.MONITOR_ACTION/04_ATTRIBUTE.json +++ b/Model/exface.Core.MONITOR_ACTION/04_ATTRIBUTE.json @@ -681,6 +681,158 @@ "DEFAULT_VALUE": "", "FIXED_VALUE": "", "CUSTOM_DATA_TYPE": null + }, + { + "_EXPORT_SUMMARY": "Task Class [TASK_CLASS]", + "CREATED_ON": "2026-01-29 10:53:24", + "MODIFIED_ON": "2026-01-29 10:55:05", + "CREATED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "MODIFIED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "UID": "0x11f09f045a3808dc9f047722c9cadff2", + "SORTABLEFLAG": 1, + "FILTERABLEFLAG": 1, + "AGGREGATABLEFLAG": 1, + "DEFAULT_AGGREGATE_FUNCTION": "", + "VALUE_LIST_DELIMITER": ",", + "READABLEFLAG": 1, + "WRITABLEFLAG": 1, + "SYSTEMFLAG": 0, + "DEFAULT_EDITOR_UXON": null, + "COPY_WITH_RELATED_OBJECT": 0, + "DELETE_WITH_RELATED_OBJECT": 0, + "DEFAULT_DISPLAY_UXON": null, + "COMMENTS": "", + "NAME": "Task Class", + "RELATION_CARDINALITY": "", + "TYPE": "D", + "COPYABLEFLAG": 1, + "ICON": "", + "ICON_SET": "", + "ABBREVIATION": "", + "ALIAS": "TASK_CLASS", + "DATATYPE": "0x30000000000000000000000000000000", + "DATA_ADDRESS": "task_class", + "OBJECT": "0x11eb830a07a3fc70830a025041000001", + "FORMATTER": "", + "DISPLAYORDER": null, + "LABELFLAG": 0, + "UIDFLAG": 0, + "HIDDENFLAG": 0, + "EDITABLEFLAG": 1, + "REQUIREDFLAG": 0, + "RELATED_OBJ": null, + "SORTERPOS": null, + "SORTERDIR": "", + "RELATED_OBJ_ATTR": null, + "SHORT_DESCRIPTION": "", + "DATA_ADDRESS_PROPS": null, + "DEFAULT_VALUE": "", + "FIXED_VALUE": "", + "CUSTOM_DATA_TYPE": { + "length_max": 100 + } + }, + { + "_EXPORT_SUMMARY": "Request Size [REQUEST_SIZE]", + "CREATED_ON": "2026-01-29 10:53:24", + "MODIFIED_ON": "2026-01-29 10:55:19", + "CREATED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "MODIFIED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "UID": "0x11f0a1ea5a38373aa1ea8d10d37f0bc3", + "SORTABLEFLAG": 1, + "FILTERABLEFLAG": 1, + "AGGREGATABLEFLAG": 1, + "DEFAULT_AGGREGATE_FUNCTION": "", + "VALUE_LIST_DELIMITER": ",", + "READABLEFLAG": 1, + "WRITABLEFLAG": 1, + "SYSTEMFLAG": 0, + "DEFAULT_EDITOR_UXON": null, + "COPY_WITH_RELATED_OBJECT": 0, + "DELETE_WITH_RELATED_OBJECT": 0, + "DEFAULT_DISPLAY_UXON": null, + "COMMENTS": "", + "NAME": "Request Size", + "RELATION_CARDINALITY": "", + "TYPE": "D", + "COPYABLEFLAG": 1, + "ICON": "", + "ICON_SET": "", + "ABBREVIATION": "", + "ALIAS": "REQUEST_SIZE", + "DATATYPE": "0x11e7b0277435425e98350205857feb80", + "DATA_ADDRESS": "request_size", + "OBJECT": "0x11eb830a07a3fc70830a025041000001", + "FORMATTER": "", + "DISPLAYORDER": null, + "LABELFLAG": 0, + "UIDFLAG": 0, + "HIDDENFLAG": 0, + "EDITABLEFLAG": 1, + "REQUIREDFLAG": 0, + "RELATED_OBJ": null, + "SORTERPOS": null, + "SORTERDIR": "", + "RELATED_OBJ_ATTR": null, + "SHORT_DESCRIPTION": "", + "DATA_ADDRESS_PROPS": null, + "DEFAULT_VALUE": "", + "FIXED_VALUE": "", + "CUSTOM_DATA_TYPE": null + }, + { + "_EXPORT_SUMMARY": "UI Flag [UI_FLAG]", + "CREATED_ON": "2026-01-29 10:53:24", + "MODIFIED_ON": "2026-02-05 15:19:04", + "CREATED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "MODIFIED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a", + "UID": "0x11f0af1d5a382380af1d635c9e1d6249", + "SORTABLEFLAG": 1, + "FILTERABLEFLAG": 1, + "AGGREGATABLEFLAG": 1, + "DEFAULT_AGGREGATE_FUNCTION": "", + "VALUE_LIST_DELIMITER": ",", + "READABLEFLAG": 1, + "WRITABLEFLAG": 1, + "SYSTEMFLAG": 0, + "DEFAULT_EDITOR_UXON": null, + "COPY_WITH_RELATED_OBJECT": 0, + "DELETE_WITH_RELATED_OBJECT": 0, + "DEFAULT_DISPLAY_UXON": null, + "COMMENTS": "", + "NAME": "UI Flag", + "RELATION_CARDINALITY": "", + "TYPE": "D", + "COPYABLEFLAG": 1, + "ICON": "", + "ICON_SET": "", + "ABBREVIATION": "", + "ALIAS": "UI_FLAG", + "DATATYPE": "0x11e7b0277435425e98350205857feb80", + "DATA_ADDRESS": [ + "// Multiline text delimited by `\n`", + "(CASE", + " WHEN ui_flag IS NULL THEN -1", + " ELSE ui_flag", + "END)" + ], + "OBJECT": "0x11eb830a07a3fc70830a025041000001", + "FORMATTER": "", + "DISPLAYORDER": null, + "LABELFLAG": 0, + "UIDFLAG": 0, + "HIDDENFLAG": 0, + "EDITABLEFLAG": 1, + "REQUIREDFLAG": 0, + "RELATED_OBJ": null, + "SORTERPOS": null, + "SORTERDIR": "", + "RELATED_OBJ_ATTR": null, + "SHORT_DESCRIPTION": "", + "DATA_ADDRESS_PROPS": null, + "DEFAULT_VALUE": "", + "FIXED_VALUE": "", + "CUSTOM_DATA_TYPE": null } ], "totals_rows": [], From 0dc55fb309fc191e8febadb6c8fce2eb31befe18 Mon Sep 17 00:00:00 2001 From: hail-cookies <81558994+hail-cookies@users.noreply.github.com> Date: Fri, 6 Feb 2026 13:33:54 +0100 Subject: [PATCH 5/6] DEV Monitor now logs long running actions --- CommonLogic/Monitor.php | 51 ++++++++++++++++++++------ Config/System.config.json | 31 +++++++++------- Model/99_PAGE/exface.core.monitor.json | 8 +++- 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/CommonLogic/Monitor.php b/CommonLogic/Monitor.php index 29943ce87..d7bdee78e 100644 --- a/CommonLogic/Monitor.php +++ b/CommonLogic/Monitor.php @@ -5,6 +5,7 @@ use exface\Core\DataTypes\PhpClassDataType; use exface\Core\Events\Action\OnBeforeActionPerformedEvent; use exface\Core\Events\Action\OnActionPerformedEvent; +use exface\Core\Exceptions\Actions\ActionRuntimeError; use exface\Core\Facades\AbstractAjaxFacade\AbstractAjaxFacade; use exface\Core\Interfaces\Tasks\HttpTaskInterface; use exface\Core\Interfaces\WorkbenchInterface; @@ -43,6 +44,12 @@ class Monitor extends Profiler private $actionsEnabled = false; + private $longRunningActionsLogged = false; + + private $longRunningActionsThreshold = 10; + + private $longRunningActionsLevel = 'CRITICAL'; + private $errorsEnabled = false; /** @@ -54,18 +61,24 @@ public function __construct(WorkbenchInterface $workbench, float $startTimeMs = { parent::__construct($workbench, $startTimeMs); } - + /** - * + * * @param WorkbenchInterface $workbench + * @param float|null $startTimeMs */ - public static function register(WorkbenchInterface $workbench, float $startTimeMs = null) + public static function register(WorkbenchInterface $workbench, float $startTimeMs = null) : void { $self = new self($workbench, $startTimeMs); $config = $workbench->getConfig(); + $self->actionsEnabled = $config->getOption('MONITOR.ACTIONS.ENABLED'); $self->errorsEnabled = $config->getOption('MONITOR.ERRORS.ENABLED'); + $self->longRunningActionsLogged = $config->getOption('DEBUG.LOG_LONG_RUNNING_READS'); + $self->longRunningActionsThreshold = $config->getOption('DEBUG.LOG_LONG_RUNNING_READS_THRESHOLD'); + $self->longRunningActionsLevel = $config->getOption('DEBUG.LOG_LONG_RUNNING_READS_LEVEL'); + // Do not monitor anything while installing the workbench if ($workbench->isInstalled() === false) { return; @@ -160,7 +173,7 @@ public static function onCleanUp(OnCleanUpEvent $event) * @param OnBeforeActionPerformedEvent $event * @return void */ - public function onActionStart(OnBeforeActionPerformedEvent $event) + public function onActionStart(OnBeforeActionPerformedEvent $event) : void { if (! $this->isActionMonitored($event->getAction())) { return; @@ -174,18 +187,33 @@ public function onActionStart(OnBeforeActionPerformedEvent $event) * @param OnActionPerformedEvent $event * @return void */ - public function onActionStop(ActionEventInterface $event) + public function onActionStop(ActionEventInterface $event) : void { - if (! $this->isActionMonitored($event->getAction())) { + $action = $event->getAction(); + + if (! $this->isActionMonitored($action)) { return; } $ms = null; if ($this->actionsEnabled) { - $ms = $this->stop($event->getAction())->getTimeTotalMs(); - } - $this->addRowFromAction($event->getAction(), $event->getTask(), $ms); - return; + $ms = $this->stop($action)->getTimeTotalMs(); + $s = $ms / 1000; + + if($s > $this->longRunningActionsThreshold) { + $this->getWorkbench()->getLogger()->logException(new ActionRuntimeError( + $action, + 'Action "' . $action->getName() . '" ran for ' . $s . 's!', + $this->longRunningActionsLevel + )); + } + } + + if($action instanceof iReadData) { + return; + } + + $this->addRowFromAction($action, $event->getTask(), $ms); } /** @@ -227,7 +255,8 @@ public function addLogIdToLastRowObject(string $ids) : void protected function isActionMonitored(ActionInterface $action) : bool { switch (true) { - case $action instanceof iReadData: + // Ignore ReadData, unless we are logging long-running actions. + case $action instanceof iReadData && !$this->longRunningActionsLogged: case $action instanceof UxonAutosuggest: case $action instanceof ContextBarApi: case $action instanceof ShowContextPopup: diff --git a/Config/System.config.json b/Config/System.config.json index 23151a976..2d1cf66e5 100644 --- a/Config/System.config.json +++ b/Config/System.config.json @@ -44,22 +44,25 @@ "DEBUG.SQL_FORMATTING_MAX_CHARS": 20000, "DEBUG.AUTOMATIC_UXON_VALIDATION": true, "DEBUG.MAINTENANCE_MODE": false, - - "LOG.MINIMUM_LEVEL_TO_LOG": "debug", - "LOG.MAX_DAYS_TO_KEEP": "14", - "LOG.PERSIST_LOG_LEVEL": "critical", - "LOG.PASSTHROUGH_LOG_LEVEL": "error", + "DEBUG.LOG_LONG_RUNNING_READS": true, + "DEBUG.LOG_LONG_RUNNING_READS_THRESHOLD": 10, + "DEBUG.LOG_LONG_RUNNING_READS_LEVEL": "CRITICAL", + + "LOG.MINIMUM_LEVEL_TO_LOG": "debug", + "LOG.MAX_DAYS_TO_KEEP": "14", + "LOG.PERSIST_LOG_LEVEL": "critical", + "LOG.PASSTHROUGH_LOG_LEVEL": "error", "LOGIN.PROMPT.MESSAGES": [], - - "MONITOR.ENABLED": true, - "MONITOR.ACTIONS.ENABLED": false, - "MONITOR.ACTIONS.DAYS_TO_KEEP": 30, - "MONITOR.ERRORS.ENABLED": true, - "MONITOR.ERRORS.MINIMUM_LEVEL_TO_LOG": "critical", - "MONITOR.ERRORS.DAYS_TO_KEEP": 30, - - "FOLDERS.USERDATA_PATH_ABSOLUTE": "", + + "MONITOR.ENABLED": true, + "MONITOR.ACTIONS.ENABLED": true, + "MONITOR.ACTIONS.DAYS_TO_KEEP": 30, + "MONITOR.ERRORS.ENABLED": true, + "MONITOR.ERRORS.MINIMUM_LEVEL_TO_LOG": "critical", + "MONITOR.ERRORS.DAYS_TO_KEEP": 30, + + "FOLDERS.USERDATA_PATH_ABSOLUTE": "", "FOLDERS.CACHE_PATH_ABSOLUTE": "", "FOLDERS.BACKUP_PATH_ABSOLUTE": "", "FOLDERS.LOGS_PATH_ABSOLUTE": "", diff --git a/Model/99_PAGE/exface.core.monitor.json b/Model/99_PAGE/exface.core.monitor.json index 0051d60ba..17c59ecaf 100644 --- a/Model/99_PAGE/exface.core.monitor.json +++ b/Model/99_PAGE/exface.core.monitor.json @@ -11,7 +11,7 @@ "created_by_user_selector": "0x31000000000000000000000000000000", "created_on": "2020-11-17 13:30:20", "modified_by_user_selector": "0x11e8fe1c902c8ebea23ee4b318306b9a", - "modified_on": "2026-02-05 15:24:16", + "modified_on": "2026-02-06 11:46:25", "icon": "tachometer", "contents": { "widget_type": "SplitVertical", @@ -45,6 +45,12 @@ "value": 0, "hidden": true }, + { + "attribute_alias": "MONITOR_ACTION__UI_FLAG", + "value": 0, + "comparator": "!==", + "apply_to_aggregates": true + }, { "/*": "", "hidden": true, From b55ada2958275ed274ca85778cc08bb44cc5d6e9 Mon Sep 17 00:00:00 2001 From: hail-cookies <81558994+hail-cookies@users.noreply.github.com> Date: Fri, 6 Feb 2026 13:35:54 +0100 Subject: [PATCH 6/6] FIX system.config disabled long running action log by default --- Config/System.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/System.config.json b/Config/System.config.json index 2d1cf66e5..ca2c5d516 100644 --- a/Config/System.config.json +++ b/Config/System.config.json @@ -44,7 +44,7 @@ "DEBUG.SQL_FORMATTING_MAX_CHARS": 20000, "DEBUG.AUTOMATIC_UXON_VALIDATION": true, "DEBUG.MAINTENANCE_MODE": false, - "DEBUG.LOG_LONG_RUNNING_READS": true, + "DEBUG.LOG_LONG_RUNNING_READS": false, "DEBUG.LOG_LONG_RUNNING_READS_THRESHOLD": 10, "DEBUG.LOG_LONG_RUNNING_READS_LEVEL": "CRITICAL",